12874c5fdSThomas Gleixner // SPDX-License-Identifier: GPL-2.0-or-later
25bc3cb74SMauro Carvalho Chehab /*
35bc3cb74SMauro Carvalho Chehab  * Video capture interface for Linux version 2
45bc3cb74SMauro Carvalho Chehab  *
55bc3cb74SMauro Carvalho Chehab  * A generic framework to process V4L2 ioctl commands.
65bc3cb74SMauro Carvalho Chehab  *
75bc3cb74SMauro Carvalho Chehab  * Authors:	Alan Cox, <alan@lxorguk.ukuu.org.uk> (version 1)
832590819SMauro Carvalho Chehab  *              Mauro Carvalho Chehab <mchehab@kernel.org> (version 2)
95bc3cb74SMauro Carvalho Chehab  */
105bc3cb74SMauro Carvalho Chehab 
118dbcc3faSArnd Bergmann #include <linux/compat.h>
12758d90e1STomasz Figa #include <linux/mm.h>
135bc3cb74SMauro Carvalho Chehab #include <linux/module.h>
145bc3cb74SMauro Carvalho Chehab #include <linux/slab.h>
155bc3cb74SMauro Carvalho Chehab #include <linux/types.h>
165bc3cb74SMauro Carvalho Chehab #include <linux/kernel.h>
175bc3cb74SMauro Carvalho Chehab #include <linux/version.h>
185bc3cb74SMauro Carvalho Chehab 
195bc3cb74SMauro Carvalho Chehab #include <linux/videodev2.h>
205bc3cb74SMauro Carvalho Chehab 
21f2d8b691SSakari Ailus #include <media/media-device.h> /* for media_set_bus_info() */
225bc3cb74SMauro Carvalho Chehab #include <media/v4l2-common.h>
235bc3cb74SMauro Carvalho Chehab #include <media/v4l2-ioctl.h>
245bc3cb74SMauro Carvalho Chehab #include <media/v4l2-ctrls.h>
255bc3cb74SMauro Carvalho Chehab #include <media/v4l2-fh.h>
265bc3cb74SMauro Carvalho Chehab #include <media/v4l2-event.h>
275bc3cb74SMauro Carvalho Chehab #include <media/v4l2-device.h>
28c139990eSJunghak Sung #include <media/videobuf2-v4l2.h>
2977fa4e07SShuah Khan #include <media/v4l2-mc.h>
30d862bc08SHans Verkuil #include <media/v4l2-mem2mem.h>
315bc3cb74SMauro Carvalho Chehab 
32aa32f4c0SHans Verkuil #include <trace/events/v4l2.h>
33aa32f4c0SHans Verkuil 
345bc3cb74SMauro Carvalho Chehab /* Zero out the end of the struct pointed to by p.  Everything after, but
355bc3cb74SMauro Carvalho Chehab  * not including, the specified field is cleared. */
365bc3cb74SMauro Carvalho Chehab #define CLEAR_AFTER_FIELD(p, field) \
375bc3cb74SMauro Carvalho Chehab 	memset((u8 *)(p) + offsetof(typeof(*(p)), field) + sizeof((p)->field), \
385bc3cb74SMauro Carvalho Chehab 	0, sizeof(*(p)) - offsetof(typeof(*(p)), field) - sizeof((p)->field))
395bc3cb74SMauro Carvalho Chehab 
4073f35418SHans Verkuil #define is_valid_ioctl(vfd, cmd) test_bit(_IOC_NR(cmd), (vfd)->valid_ioctls)
4173f35418SHans Verkuil 
425bc3cb74SMauro Carvalho Chehab struct std_descr {
435bc3cb74SMauro Carvalho Chehab 	v4l2_std_id std;
445bc3cb74SMauro Carvalho Chehab 	const char *descr;
455bc3cb74SMauro Carvalho Chehab };
465bc3cb74SMauro Carvalho Chehab 
475bc3cb74SMauro Carvalho Chehab static const struct std_descr standards[] = {
485bc3cb74SMauro Carvalho Chehab 	{ V4L2_STD_NTSC,	"NTSC"      },
495bc3cb74SMauro Carvalho Chehab 	{ V4L2_STD_NTSC_M,	"NTSC-M"    },
505bc3cb74SMauro Carvalho Chehab 	{ V4L2_STD_NTSC_M_JP,	"NTSC-M-JP" },
515bc3cb74SMauro Carvalho Chehab 	{ V4L2_STD_NTSC_M_KR,	"NTSC-M-KR" },
525bc3cb74SMauro Carvalho Chehab 	{ V4L2_STD_NTSC_443,	"NTSC-443"  },
535bc3cb74SMauro Carvalho Chehab 	{ V4L2_STD_PAL,		"PAL"       },
545bc3cb74SMauro Carvalho Chehab 	{ V4L2_STD_PAL_BG,	"PAL-BG"    },
555bc3cb74SMauro Carvalho Chehab 	{ V4L2_STD_PAL_B,	"PAL-B"     },
565bc3cb74SMauro Carvalho Chehab 	{ V4L2_STD_PAL_B1,	"PAL-B1"    },
575bc3cb74SMauro Carvalho Chehab 	{ V4L2_STD_PAL_G,	"PAL-G"     },
585bc3cb74SMauro Carvalho Chehab 	{ V4L2_STD_PAL_H,	"PAL-H"     },
595bc3cb74SMauro Carvalho Chehab 	{ V4L2_STD_PAL_I,	"PAL-I"     },
605bc3cb74SMauro Carvalho Chehab 	{ V4L2_STD_PAL_DK,	"PAL-DK"    },
615bc3cb74SMauro Carvalho Chehab 	{ V4L2_STD_PAL_D,	"PAL-D"     },
625bc3cb74SMauro Carvalho Chehab 	{ V4L2_STD_PAL_D1,	"PAL-D1"    },
635bc3cb74SMauro Carvalho Chehab 	{ V4L2_STD_PAL_K,	"PAL-K"     },
645bc3cb74SMauro Carvalho Chehab 	{ V4L2_STD_PAL_M,	"PAL-M"     },
655bc3cb74SMauro Carvalho Chehab 	{ V4L2_STD_PAL_N,	"PAL-N"     },
665bc3cb74SMauro Carvalho Chehab 	{ V4L2_STD_PAL_Nc,	"PAL-Nc"    },
675bc3cb74SMauro Carvalho Chehab 	{ V4L2_STD_PAL_60,	"PAL-60"    },
685bc3cb74SMauro Carvalho Chehab 	{ V4L2_STD_SECAM,	"SECAM"     },
695bc3cb74SMauro Carvalho Chehab 	{ V4L2_STD_SECAM_B,	"SECAM-B"   },
705bc3cb74SMauro Carvalho Chehab 	{ V4L2_STD_SECAM_G,	"SECAM-G"   },
715bc3cb74SMauro Carvalho Chehab 	{ V4L2_STD_SECAM_H,	"SECAM-H"   },
725bc3cb74SMauro Carvalho Chehab 	{ V4L2_STD_SECAM_DK,	"SECAM-DK"  },
735bc3cb74SMauro Carvalho Chehab 	{ V4L2_STD_SECAM_D,	"SECAM-D"   },
745bc3cb74SMauro Carvalho Chehab 	{ V4L2_STD_SECAM_K,	"SECAM-K"   },
755bc3cb74SMauro Carvalho Chehab 	{ V4L2_STD_SECAM_K1,	"SECAM-K1"  },
765bc3cb74SMauro Carvalho Chehab 	{ V4L2_STD_SECAM_L,	"SECAM-L"   },
775bc3cb74SMauro Carvalho Chehab 	{ V4L2_STD_SECAM_LC,	"SECAM-Lc"  },
785bc3cb74SMauro Carvalho Chehab 	{ 0,			"Unknown"   }
795bc3cb74SMauro Carvalho Chehab };
805bc3cb74SMauro Carvalho Chehab 
815bc3cb74SMauro Carvalho Chehab /* video4linux standard ID conversion to standard name
825bc3cb74SMauro Carvalho Chehab  */
835bc3cb74SMauro Carvalho Chehab const char *v4l2_norm_to_name(v4l2_std_id id)
845bc3cb74SMauro Carvalho Chehab {
855bc3cb74SMauro Carvalho Chehab 	u32 myid = id;
865bc3cb74SMauro Carvalho Chehab 	int i;
875bc3cb74SMauro Carvalho Chehab 
885bc3cb74SMauro Carvalho Chehab 	/* HACK: ppc32 architecture doesn't have __ucmpdi2 function to handle
894faf7066SMauro Carvalho Chehab 	   64 bit comparisons. So, on that architecture, with some gcc
905bc3cb74SMauro Carvalho Chehab 	   variants, compilation fails. Currently, the max value is 30bit wide.
915bc3cb74SMauro Carvalho Chehab 	 */
925bc3cb74SMauro Carvalho Chehab 	BUG_ON(myid != id);
935bc3cb74SMauro Carvalho Chehab 
945bc3cb74SMauro Carvalho Chehab 	for (i = 0; standards[i].std; i++)
955bc3cb74SMauro Carvalho Chehab 		if (myid == standards[i].std)
965bc3cb74SMauro Carvalho Chehab 			break;
975bc3cb74SMauro Carvalho Chehab 	return standards[i].descr;
985bc3cb74SMauro Carvalho Chehab }
995bc3cb74SMauro Carvalho Chehab EXPORT_SYMBOL(v4l2_norm_to_name);
1005bc3cb74SMauro Carvalho Chehab 
1015bc3cb74SMauro Carvalho Chehab /* Returns frame period for the given standard */
1025bc3cb74SMauro Carvalho Chehab void v4l2_video_std_frame_period(int id, struct v4l2_fract *frameperiod)
1035bc3cb74SMauro Carvalho Chehab {
1045bc3cb74SMauro Carvalho Chehab 	if (id & V4L2_STD_525_60) {
1055bc3cb74SMauro Carvalho Chehab 		frameperiod->numerator = 1001;
1065bc3cb74SMauro Carvalho Chehab 		frameperiod->denominator = 30000;
1075bc3cb74SMauro Carvalho Chehab 	} else {
1085bc3cb74SMauro Carvalho Chehab 		frameperiod->numerator = 1;
1095bc3cb74SMauro Carvalho Chehab 		frameperiod->denominator = 25;
1105bc3cb74SMauro Carvalho Chehab 	}
1115bc3cb74SMauro Carvalho Chehab }
1125bc3cb74SMauro Carvalho Chehab EXPORT_SYMBOL(v4l2_video_std_frame_period);
1135bc3cb74SMauro Carvalho Chehab 
1145bc3cb74SMauro Carvalho Chehab /* Fill in the fields of a v4l2_standard structure according to the
1155bc3cb74SMauro Carvalho Chehab    'id' and 'transmission' parameters.  Returns negative on error.  */
1165bc3cb74SMauro Carvalho Chehab int v4l2_video_std_construct(struct v4l2_standard *vs,
1175bc3cb74SMauro Carvalho Chehab 			     int id, const char *name)
1185bc3cb74SMauro Carvalho Chehab {
1195bc3cb74SMauro Carvalho Chehab 	vs->id = id;
1205bc3cb74SMauro Carvalho Chehab 	v4l2_video_std_frame_period(id, &vs->frameperiod);
1215bc3cb74SMauro Carvalho Chehab 	vs->framelines = (id & V4L2_STD_525_60) ? 525 : 625;
122c0decac1SMauro Carvalho Chehab 	strscpy(vs->name, name, sizeof(vs->name));
1235bc3cb74SMauro Carvalho Chehab 	return 0;
1245bc3cb74SMauro Carvalho Chehab }
1255bc3cb74SMauro Carvalho Chehab EXPORT_SYMBOL(v4l2_video_std_construct);
1265bc3cb74SMauro Carvalho Chehab 
127aa2f8871SNiklas Söderlund /* Fill in the fields of a v4l2_standard structure according to the
128aa2f8871SNiklas Söderlund  * 'id' and 'vs->index' parameters. Returns negative on error. */
129aa2f8871SNiklas Söderlund int v4l_video_std_enumstd(struct v4l2_standard *vs, v4l2_std_id id)
130aa2f8871SNiklas Söderlund {
131aa2f8871SNiklas Söderlund 	v4l2_std_id curr_id = 0;
132aa2f8871SNiklas Söderlund 	unsigned int index = vs->index, i, j = 0;
133aa2f8871SNiklas Söderlund 	const char *descr = "";
134aa2f8871SNiklas Söderlund 
135aa2f8871SNiklas Söderlund 	/* Return -ENODATA if the id for the current input
136aa2f8871SNiklas Söderlund 	   or output is 0, meaning that it doesn't support this API. */
137aa2f8871SNiklas Söderlund 	if (id == 0)
138aa2f8871SNiklas Söderlund 		return -ENODATA;
139aa2f8871SNiklas Söderlund 
140aa2f8871SNiklas Söderlund 	/* Return norm array in a canonical way */
141aa2f8871SNiklas Söderlund 	for (i = 0; i <= index && id; i++) {
142aa2f8871SNiklas Söderlund 		/* last std value in the standards array is 0, so this
143aa2f8871SNiklas Söderlund 		   while always ends there since (id & 0) == 0. */
144aa2f8871SNiklas Söderlund 		while ((id & standards[j].std) != standards[j].std)
145aa2f8871SNiklas Söderlund 			j++;
146aa2f8871SNiklas Söderlund 		curr_id = standards[j].std;
147aa2f8871SNiklas Söderlund 		descr = standards[j].descr;
148aa2f8871SNiklas Söderlund 		j++;
149aa2f8871SNiklas Söderlund 		if (curr_id == 0)
150aa2f8871SNiklas Söderlund 			break;
151aa2f8871SNiklas Söderlund 		if (curr_id != V4L2_STD_PAL &&
152aa2f8871SNiklas Söderlund 				curr_id != V4L2_STD_SECAM &&
153aa2f8871SNiklas Söderlund 				curr_id != V4L2_STD_NTSC)
154aa2f8871SNiklas Söderlund 			id &= ~curr_id;
155aa2f8871SNiklas Söderlund 	}
156aa2f8871SNiklas Söderlund 	if (i <= index)
157aa2f8871SNiklas Söderlund 		return -EINVAL;
158aa2f8871SNiklas Söderlund 
159aa2f8871SNiklas Söderlund 	v4l2_video_std_construct(vs, curr_id, descr);
160aa2f8871SNiklas Söderlund 	return 0;
161aa2f8871SNiklas Söderlund }
162aa2f8871SNiklas Söderlund 
1635bc3cb74SMauro Carvalho Chehab /* ----------------------------------------------------------------- */
1645bc3cb74SMauro Carvalho Chehab /* some arrays for pretty-printing debug messages of enum types      */
1655bc3cb74SMauro Carvalho Chehab 
1665bc3cb74SMauro Carvalho Chehab const char *v4l2_field_names[] = {
1675bc3cb74SMauro Carvalho Chehab 	[V4L2_FIELD_ANY]        = "any",
1685bc3cb74SMauro Carvalho Chehab 	[V4L2_FIELD_NONE]       = "none",
1695bc3cb74SMauro Carvalho Chehab 	[V4L2_FIELD_TOP]        = "top",
1705bc3cb74SMauro Carvalho Chehab 	[V4L2_FIELD_BOTTOM]     = "bottom",
1715bc3cb74SMauro Carvalho Chehab 	[V4L2_FIELD_INTERLACED] = "interlaced",
1725bc3cb74SMauro Carvalho Chehab 	[V4L2_FIELD_SEQ_TB]     = "seq-tb",
1735bc3cb74SMauro Carvalho Chehab 	[V4L2_FIELD_SEQ_BT]     = "seq-bt",
1745bc3cb74SMauro Carvalho Chehab 	[V4L2_FIELD_ALTERNATE]  = "alternate",
1755bc3cb74SMauro Carvalho Chehab 	[V4L2_FIELD_INTERLACED_TB] = "interlaced-tb",
1765bc3cb74SMauro Carvalho Chehab 	[V4L2_FIELD_INTERLACED_BT] = "interlaced-bt",
1775bc3cb74SMauro Carvalho Chehab };
1785bc3cb74SMauro Carvalho Chehab EXPORT_SYMBOL(v4l2_field_names);
1795bc3cb74SMauro Carvalho Chehab 
1805bc3cb74SMauro Carvalho Chehab const char *v4l2_type_names[] = {
181839aa56dSHans Verkuil 	[0]				   = "0",
1825bc3cb74SMauro Carvalho Chehab 	[V4L2_BUF_TYPE_VIDEO_CAPTURE]      = "vid-cap",
1835bc3cb74SMauro Carvalho Chehab 	[V4L2_BUF_TYPE_VIDEO_OVERLAY]      = "vid-overlay",
1845bc3cb74SMauro Carvalho Chehab 	[V4L2_BUF_TYPE_VIDEO_OUTPUT]       = "vid-out",
1855bc3cb74SMauro Carvalho Chehab 	[V4L2_BUF_TYPE_VBI_CAPTURE]        = "vbi-cap",
1865bc3cb74SMauro Carvalho Chehab 	[V4L2_BUF_TYPE_VBI_OUTPUT]         = "vbi-out",
1875bc3cb74SMauro Carvalho Chehab 	[V4L2_BUF_TYPE_SLICED_VBI_CAPTURE] = "sliced-vbi-cap",
1885bc3cb74SMauro Carvalho Chehab 	[V4L2_BUF_TYPE_SLICED_VBI_OUTPUT]  = "sliced-vbi-out",
1895bc3cb74SMauro Carvalho Chehab 	[V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY] = "vid-out-overlay",
1905bc3cb74SMauro Carvalho Chehab 	[V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE] = "vid-cap-mplane",
1915bc3cb74SMauro Carvalho Chehab 	[V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE] = "vid-out-mplane",
1926f3073b8SAntti Palosaari 	[V4L2_BUF_TYPE_SDR_CAPTURE]        = "sdr-cap",
1939effc72fSAntti Palosaari 	[V4L2_BUF_TYPE_SDR_OUTPUT]         = "sdr-out",
194fb9ffa6aSLaurent Pinchart 	[V4L2_BUF_TYPE_META_CAPTURE]       = "meta-cap",
19572148d1aSSakari Ailus 	[V4L2_BUF_TYPE_META_OUTPUT]	   = "meta-out",
1965bc3cb74SMauro Carvalho Chehab };
1975bc3cb74SMauro Carvalho Chehab EXPORT_SYMBOL(v4l2_type_names);
1985bc3cb74SMauro Carvalho Chehab 
1995bc3cb74SMauro Carvalho Chehab static const char *v4l2_memory_names[] = {
2005bc3cb74SMauro Carvalho Chehab 	[V4L2_MEMORY_MMAP]    = "mmap",
2015bc3cb74SMauro Carvalho Chehab 	[V4L2_MEMORY_USERPTR] = "userptr",
2025bc3cb74SMauro Carvalho Chehab 	[V4L2_MEMORY_OVERLAY] = "overlay",
203051c7788SSumit Semwal 	[V4L2_MEMORY_DMABUF] = "dmabuf",
2045bc3cb74SMauro Carvalho Chehab };
2055bc3cb74SMauro Carvalho Chehab 
206d9246240SHans Verkuil #define prt_names(a, arr) (((unsigned)(a)) < ARRAY_SIZE(arr) ? arr[a] : "unknown")
2075bc3cb74SMauro Carvalho Chehab 
2085bc3cb74SMauro Carvalho Chehab /* ------------------------------------------------------------------ */
2095bc3cb74SMauro Carvalho Chehab /* debug help functions                                               */
2105bc3cb74SMauro Carvalho Chehab 
2115bc3cb74SMauro Carvalho Chehab static void v4l_print_querycap(const void *arg, bool write_only)
2125bc3cb74SMauro Carvalho Chehab {
2135bc3cb74SMauro Carvalho Chehab 	const struct v4l2_capability *p = arg;
2145bc3cb74SMauro Carvalho Chehab 
2158720427cSMauro Carvalho Chehab 	pr_cont("driver=%.*s, card=%.*s, bus=%.*s, version=0x%08x, capabilities=0x%08x, device_caps=0x%08x\n",
21627d5a87cSHans Verkuil 		(int)sizeof(p->driver), p->driver,
21727d5a87cSHans Verkuil 		(int)sizeof(p->card), p->card,
21827d5a87cSHans Verkuil 		(int)sizeof(p->bus_info), p->bus_info,
2195bc3cb74SMauro Carvalho Chehab 		p->version, p->capabilities, p->device_caps);
2205bc3cb74SMauro Carvalho Chehab }
2215bc3cb74SMauro Carvalho Chehab 
2225bc3cb74SMauro Carvalho Chehab static void v4l_print_enuminput(const void *arg, bool write_only)
2235bc3cb74SMauro Carvalho Chehab {
2245bc3cb74SMauro Carvalho Chehab 	const struct v4l2_input *p = arg;
2255bc3cb74SMauro Carvalho Chehab 
2268720427cSMauro 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",
22727d5a87cSHans Verkuil 		p->index, (int)sizeof(p->name), p->name, p->type, p->audioset,
22827d5a87cSHans Verkuil 		p->tuner, (unsigned long long)p->std, p->status,
22927d5a87cSHans Verkuil 		p->capabilities);
2305bc3cb74SMauro Carvalho Chehab }
2315bc3cb74SMauro Carvalho Chehab 
2325bc3cb74SMauro Carvalho Chehab static void v4l_print_enumoutput(const void *arg, bool write_only)
2335bc3cb74SMauro Carvalho Chehab {
2345bc3cb74SMauro Carvalho Chehab 	const struct v4l2_output *p = arg;
2355bc3cb74SMauro Carvalho Chehab 
2368720427cSMauro Carvalho Chehab 	pr_cont("index=%u, name=%.*s, type=%u, audioset=0x%x, modulator=%u, std=0x%08Lx, capabilities=0x%x\n",
23727d5a87cSHans Verkuil 		p->index, (int)sizeof(p->name), p->name, p->type, p->audioset,
23827d5a87cSHans Verkuil 		p->modulator, (unsigned long long)p->std, p->capabilities);
2395bc3cb74SMauro Carvalho Chehab }
2405bc3cb74SMauro Carvalho Chehab 
2415bc3cb74SMauro Carvalho Chehab static void v4l_print_audio(const void *arg, bool write_only)
2425bc3cb74SMauro Carvalho Chehab {
2435bc3cb74SMauro Carvalho Chehab 	const struct v4l2_audio *p = arg;
2445bc3cb74SMauro Carvalho Chehab 
2455bc3cb74SMauro Carvalho Chehab 	if (write_only)
2465bc3cb74SMauro Carvalho Chehab 		pr_cont("index=%u, mode=0x%x\n", p->index, p->mode);
2475bc3cb74SMauro Carvalho Chehab 	else
24827d5a87cSHans Verkuil 		pr_cont("index=%u, name=%.*s, capability=0x%x, mode=0x%x\n",
24927d5a87cSHans Verkuil 			p->index, (int)sizeof(p->name), p->name,
25027d5a87cSHans Verkuil 			p->capability, p->mode);
2515bc3cb74SMauro Carvalho Chehab }
2525bc3cb74SMauro Carvalho Chehab 
2535bc3cb74SMauro Carvalho Chehab static void v4l_print_audioout(const void *arg, bool write_only)
2545bc3cb74SMauro Carvalho Chehab {
2555bc3cb74SMauro Carvalho Chehab 	const struct v4l2_audioout *p = arg;
2565bc3cb74SMauro Carvalho Chehab 
2575bc3cb74SMauro Carvalho Chehab 	if (write_only)
2585bc3cb74SMauro Carvalho Chehab 		pr_cont("index=%u\n", p->index);
2595bc3cb74SMauro Carvalho Chehab 	else
26027d5a87cSHans Verkuil 		pr_cont("index=%u, name=%.*s, capability=0x%x, mode=0x%x\n",
26127d5a87cSHans Verkuil 			p->index, (int)sizeof(p->name), p->name,
26227d5a87cSHans Verkuil 			p->capability, p->mode);
2635bc3cb74SMauro Carvalho Chehab }
2645bc3cb74SMauro Carvalho Chehab 
2655bc3cb74SMauro Carvalho Chehab static void v4l_print_fmtdesc(const void *arg, bool write_only)
2665bc3cb74SMauro Carvalho Chehab {
2675bc3cb74SMauro Carvalho Chehab 	const struct v4l2_fmtdesc *p = arg;
2685bc3cb74SMauro Carvalho Chehab 
269e927e1e0SSakari Ailus 	pr_cont("index=%u, type=%s, flags=0x%x, pixelformat=%p4cc, mbus_code=0x%04x, description='%.*s'\n",
2705bc3cb74SMauro Carvalho Chehab 		p->index, prt_names(p->type, v4l2_type_names),
271e927e1e0SSakari Ailus 		p->flags, &p->pixelformat, p->mbus_code,
27227d5a87cSHans Verkuil 		(int)sizeof(p->description), p->description);
2735bc3cb74SMauro Carvalho Chehab }
2745bc3cb74SMauro Carvalho Chehab 
2755bc3cb74SMauro Carvalho Chehab static void v4l_print_format(const void *arg, bool write_only)
2765bc3cb74SMauro Carvalho Chehab {
2775bc3cb74SMauro Carvalho Chehab 	const struct v4l2_format *p = arg;
2785bc3cb74SMauro Carvalho Chehab 	const struct v4l2_pix_format *pix;
2795bc3cb74SMauro Carvalho Chehab 	const struct v4l2_pix_format_mplane *mp;
2805bc3cb74SMauro Carvalho Chehab 	const struct v4l2_vbi_format *vbi;
2815bc3cb74SMauro Carvalho Chehab 	const struct v4l2_sliced_vbi_format *sliced;
2825bc3cb74SMauro Carvalho Chehab 	const struct v4l2_window *win;
283fb9ffa6aSLaurent Pinchart 	const struct v4l2_meta_format *meta;
28424bb30c8SSakari Ailus 	u32 pixelformat;
2857fe9f01cSSakari Ailus 	u32 planes;
2865bc3cb74SMauro Carvalho Chehab 	unsigned i;
2875bc3cb74SMauro Carvalho Chehab 
2885bc3cb74SMauro Carvalho Chehab 	pr_cont("type=%s", prt_names(p->type, v4l2_type_names));
2895bc3cb74SMauro Carvalho Chehab 	switch (p->type) {
2905bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_CAPTURE:
2915bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_OUTPUT:
2925bc3cb74SMauro Carvalho Chehab 		pix = &p->fmt.pix;
293e927e1e0SSakari 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",
294e927e1e0SSakari Ailus 			pix->width, pix->height, &pix->pixelformat,
2955bc3cb74SMauro Carvalho Chehab 			prt_names(pix->field, v4l2_field_names),
2965bc3cb74SMauro Carvalho Chehab 			pix->bytesperline, pix->sizeimage,
297736d96b5SHans Verkuil 			pix->colorspace, pix->flags, pix->ycbcr_enc,
29874fdcb2eSHans Verkuil 			pix->quantization, pix->xfer_func);
2995bc3cb74SMauro Carvalho Chehab 		break;
3005bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
3015bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
3025bc3cb74SMauro Carvalho Chehab 		mp = &p->fmt.pix_mp;
30324bb30c8SSakari Ailus 		pixelformat = mp->pixelformat;
304e927e1e0SSakari 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",
30524bb30c8SSakari Ailus 			mp->width, mp->height, &pixelformat,
3065bc3cb74SMauro Carvalho Chehab 			prt_names(mp->field, v4l2_field_names),
307736d96b5SHans Verkuil 			mp->colorspace, mp->num_planes, mp->flags,
30874fdcb2eSHans Verkuil 			mp->ycbcr_enc, mp->quantization, mp->xfer_func);
3097fe9f01cSSakari Ailus 		planes = min_t(u32, mp->num_planes, VIDEO_MAX_PLANES);
3107fe9f01cSSakari Ailus 		for (i = 0; i < planes; i++)
3115bc3cb74SMauro Carvalho Chehab 			printk(KERN_DEBUG "plane %u: bytesperline=%u sizeimage=%u\n", i,
3125bc3cb74SMauro Carvalho Chehab 					mp->plane_fmt[i].bytesperline,
3135bc3cb74SMauro Carvalho Chehab 					mp->plane_fmt[i].sizeimage);
3145bc3cb74SMauro Carvalho Chehab 		break;
3155bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_OVERLAY:
3165bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
3175bc3cb74SMauro Carvalho Chehab 		win = &p->fmt.win;
318560dde24SHans Verkuil 		/* Note: we can't print the clip list here since the clips
319560dde24SHans Verkuil 		 * pointer is a userspace pointer, not a kernelspace
320560dde24SHans Verkuil 		 * pointer. */
321560dde24SHans Verkuil 		pr_cont(", wxh=%dx%d, x,y=%d,%d, field=%s, chromakey=0x%08x, clipcount=%u, clips=%p, bitmap=%p, global_alpha=0x%02x\n",
322560dde24SHans Verkuil 			win->w.width, win->w.height, win->w.left, win->w.top,
3235bc3cb74SMauro Carvalho Chehab 			prt_names(win->field, v4l2_field_names),
324560dde24SHans Verkuil 			win->chromakey, win->clipcount, win->clips,
325560dde24SHans Verkuil 			win->bitmap, win->global_alpha);
3265bc3cb74SMauro Carvalho Chehab 		break;
3275bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VBI_CAPTURE:
3285bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VBI_OUTPUT:
3295bc3cb74SMauro Carvalho Chehab 		vbi = &p->fmt.vbi;
330e927e1e0SSakari Ailus 		pr_cont(", sampling_rate=%u, offset=%u, samples_per_line=%u, sample_format=%p4cc, start=%u,%u, count=%u,%u\n",
3315bc3cb74SMauro Carvalho Chehab 			vbi->sampling_rate, vbi->offset,
332e927e1e0SSakari Ailus 			vbi->samples_per_line, &vbi->sample_format,
3335bc3cb74SMauro Carvalho Chehab 			vbi->start[0], vbi->start[1],
3345bc3cb74SMauro Carvalho Chehab 			vbi->count[0], vbi->count[1]);
3355bc3cb74SMauro Carvalho Chehab 		break;
3365bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
3375bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
3385bc3cb74SMauro Carvalho Chehab 		sliced = &p->fmt.sliced;
3395bc3cb74SMauro Carvalho Chehab 		pr_cont(", service_set=0x%08x, io_size=%d\n",
3405bc3cb74SMauro Carvalho Chehab 				sliced->service_set, sliced->io_size);
3415bc3cb74SMauro Carvalho Chehab 		for (i = 0; i < 24; i++)
3425bc3cb74SMauro Carvalho Chehab 			printk(KERN_DEBUG "line[%02u]=0x%04x, 0x%04x\n", i,
3435bc3cb74SMauro Carvalho Chehab 				sliced->service_lines[0][i],
3445bc3cb74SMauro Carvalho Chehab 				sliced->service_lines[1][i]);
3455bc3cb74SMauro Carvalho Chehab 		break;
346582c52cbSAntti Palosaari 	case V4L2_BUF_TYPE_SDR_CAPTURE:
3479effc72fSAntti Palosaari 	case V4L2_BUF_TYPE_SDR_OUTPUT:
34824bb30c8SSakari Ailus 		pixelformat = p->fmt.sdr.pixelformat;
34924bb30c8SSakari Ailus 		pr_cont(", pixelformat=%p4cc\n", &pixelformat);
350582c52cbSAntti Palosaari 		break;
351fb9ffa6aSLaurent Pinchart 	case V4L2_BUF_TYPE_META_CAPTURE:
35272148d1aSSakari Ailus 	case V4L2_BUF_TYPE_META_OUTPUT:
353fb9ffa6aSLaurent Pinchart 		meta = &p->fmt.meta;
35424bb30c8SSakari Ailus 		pixelformat = meta->dataformat;
355e927e1e0SSakari Ailus 		pr_cont(", dataformat=%p4cc, buffersize=%u\n",
35624bb30c8SSakari Ailus 			&pixelformat, meta->buffersize);
357fb9ffa6aSLaurent Pinchart 		break;
3585bc3cb74SMauro Carvalho Chehab 	}
3595bc3cb74SMauro Carvalho Chehab }
3605bc3cb74SMauro Carvalho Chehab 
3615bc3cb74SMauro Carvalho Chehab static void v4l_print_framebuffer(const void *arg, bool write_only)
3625bc3cb74SMauro Carvalho Chehab {
3635bc3cb74SMauro Carvalho Chehab 	const struct v4l2_framebuffer *p = arg;
3645bc3cb74SMauro Carvalho Chehab 
365e927e1e0SSakari 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",
366e927e1e0SSakari Ailus 		p->capability, p->flags, p->base, p->fmt.width, p->fmt.height,
367e927e1e0SSakari Ailus 		&p->fmt.pixelformat, p->fmt.bytesperline, p->fmt.sizeimage,
3685bc3cb74SMauro Carvalho Chehab 		p->fmt.colorspace);
3695bc3cb74SMauro Carvalho Chehab }
3705bc3cb74SMauro Carvalho Chehab 
3715bc3cb74SMauro Carvalho Chehab static void v4l_print_buftype(const void *arg, bool write_only)
3725bc3cb74SMauro Carvalho Chehab {
3735bc3cb74SMauro Carvalho Chehab 	pr_cont("type=%s\n", prt_names(*(u32 *)arg, v4l2_type_names));
3745bc3cb74SMauro Carvalho Chehab }
3755bc3cb74SMauro Carvalho Chehab 
3765bc3cb74SMauro Carvalho Chehab static void v4l_print_modulator(const void *arg, bool write_only)
3775bc3cb74SMauro Carvalho Chehab {
3785bc3cb74SMauro Carvalho Chehab 	const struct v4l2_modulator *p = arg;
3795bc3cb74SMauro Carvalho Chehab 
3805bc3cb74SMauro Carvalho Chehab 	if (write_only)
381560dde24SHans Verkuil 		pr_cont("index=%u, txsubchans=0x%x\n", p->index, p->txsubchans);
3825bc3cb74SMauro Carvalho Chehab 	else
3838720427cSMauro Carvalho Chehab 		pr_cont("index=%u, name=%.*s, capability=0x%x, rangelow=%u, rangehigh=%u, txsubchans=0x%x\n",
38427d5a87cSHans Verkuil 			p->index, (int)sizeof(p->name), p->name, p->capability,
3855bc3cb74SMauro Carvalho Chehab 			p->rangelow, p->rangehigh, p->txsubchans);
3865bc3cb74SMauro Carvalho Chehab }
3875bc3cb74SMauro Carvalho Chehab 
3885bc3cb74SMauro Carvalho Chehab static void v4l_print_tuner(const void *arg, bool write_only)
3895bc3cb74SMauro Carvalho Chehab {
3905bc3cb74SMauro Carvalho Chehab 	const struct v4l2_tuner *p = arg;
3915bc3cb74SMauro Carvalho Chehab 
3925bc3cb74SMauro Carvalho Chehab 	if (write_only)
3935bc3cb74SMauro Carvalho Chehab 		pr_cont("index=%u, audmode=%u\n", p->index, p->audmode);
3945bc3cb74SMauro Carvalho Chehab 	else
3958720427cSMauro 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",
39627d5a87cSHans Verkuil 			p->index, (int)sizeof(p->name), p->name, p->type,
3975bc3cb74SMauro Carvalho Chehab 			p->capability, p->rangelow,
3985bc3cb74SMauro Carvalho Chehab 			p->rangehigh, p->signal, p->afc,
3995bc3cb74SMauro Carvalho Chehab 			p->rxsubchans, p->audmode);
4005bc3cb74SMauro Carvalho Chehab }
4015bc3cb74SMauro Carvalho Chehab 
4025bc3cb74SMauro Carvalho Chehab static void v4l_print_frequency(const void *arg, bool write_only)
4035bc3cb74SMauro Carvalho Chehab {
4045bc3cb74SMauro Carvalho Chehab 	const struct v4l2_frequency *p = arg;
4055bc3cb74SMauro Carvalho Chehab 
4065bc3cb74SMauro Carvalho Chehab 	pr_cont("tuner=%u, type=%u, frequency=%u\n",
4075bc3cb74SMauro Carvalho Chehab 				p->tuner, p->type, p->frequency);
4085bc3cb74SMauro Carvalho Chehab }
4095bc3cb74SMauro Carvalho Chehab 
4105bc3cb74SMauro Carvalho Chehab static void v4l_print_standard(const void *arg, bool write_only)
4115bc3cb74SMauro Carvalho Chehab {
4125bc3cb74SMauro Carvalho Chehab 	const struct v4l2_standard *p = arg;
4135bc3cb74SMauro Carvalho Chehab 
4148720427cSMauro Carvalho Chehab 	pr_cont("index=%u, id=0x%Lx, name=%.*s, fps=%u/%u, framelines=%u\n",
4158720427cSMauro Carvalho Chehab 		p->index,
41627d5a87cSHans Verkuil 		(unsigned long long)p->id, (int)sizeof(p->name), p->name,
4175bc3cb74SMauro Carvalho Chehab 		p->frameperiod.numerator,
4185bc3cb74SMauro Carvalho Chehab 		p->frameperiod.denominator,
4195bc3cb74SMauro Carvalho Chehab 		p->framelines);
4205bc3cb74SMauro Carvalho Chehab }
4215bc3cb74SMauro Carvalho Chehab 
4225bc3cb74SMauro Carvalho Chehab static void v4l_print_std(const void *arg, bool write_only)
4235bc3cb74SMauro Carvalho Chehab {
4245bc3cb74SMauro Carvalho Chehab 	pr_cont("std=0x%08Lx\n", *(const long long unsigned *)arg);
4255bc3cb74SMauro Carvalho Chehab }
4265bc3cb74SMauro Carvalho Chehab 
4275bc3cb74SMauro Carvalho Chehab static void v4l_print_hw_freq_seek(const void *arg, bool write_only)
4285bc3cb74SMauro Carvalho Chehab {
4295bc3cb74SMauro Carvalho Chehab 	const struct v4l2_hw_freq_seek *p = arg;
4305bc3cb74SMauro Carvalho Chehab 
4318720427cSMauro Carvalho Chehab 	pr_cont("tuner=%u, type=%u, seek_upward=%u, wrap_around=%u, spacing=%u, rangelow=%u, rangehigh=%u\n",
43279e8c7beSMauro Carvalho Chehab 		p->tuner, p->type, p->seek_upward, p->wrap_around, p->spacing,
43379e8c7beSMauro Carvalho Chehab 		p->rangelow, p->rangehigh);
4345bc3cb74SMauro Carvalho Chehab }
4355bc3cb74SMauro Carvalho Chehab 
4365bc3cb74SMauro Carvalho Chehab static void v4l_print_requestbuffers(const void *arg, bool write_only)
4375bc3cb74SMauro Carvalho Chehab {
4385bc3cb74SMauro Carvalho Chehab 	const struct v4l2_requestbuffers *p = arg;
4395bc3cb74SMauro Carvalho Chehab 
4405bc3cb74SMauro Carvalho Chehab 	pr_cont("count=%d, type=%s, memory=%s\n",
4415bc3cb74SMauro Carvalho Chehab 		p->count,
4425bc3cb74SMauro Carvalho Chehab 		prt_names(p->type, v4l2_type_names),
4435bc3cb74SMauro Carvalho Chehab 		prt_names(p->memory, v4l2_memory_names));
4445bc3cb74SMauro Carvalho Chehab }
4455bc3cb74SMauro Carvalho Chehab 
4465bc3cb74SMauro Carvalho Chehab static void v4l_print_buffer(const void *arg, bool write_only)
4475bc3cb74SMauro Carvalho Chehab {
4485bc3cb74SMauro Carvalho Chehab 	const struct v4l2_buffer *p = arg;
4495bc3cb74SMauro Carvalho Chehab 	const struct v4l2_timecode *tc = &p->timecode;
4505bc3cb74SMauro Carvalho Chehab 	const struct v4l2_plane *plane;
4515bc3cb74SMauro Carvalho Chehab 	int i;
4525bc3cb74SMauro Carvalho Chehab 
45348e15418SHans Verkuil 	pr_cont("%02d:%02d:%02d.%06ld index=%d, type=%s, request_fd=%d, flags=0x%08x, field=%s, sequence=%d, memory=%s",
454577c89b0SArnd Bergmann 			(int)p->timestamp.tv_sec / 3600,
455577c89b0SArnd Bergmann 			((int)p->timestamp.tv_sec / 60) % 60,
456577c89b0SArnd Bergmann 			((int)p->timestamp.tv_sec % 60),
4575bc3cb74SMauro Carvalho Chehab 			(long)p->timestamp.tv_usec,
4585bc3cb74SMauro Carvalho Chehab 			p->index,
45962fed26fSHans Verkuil 			prt_names(p->type, v4l2_type_names), p->request_fd,
4605bc3cb74SMauro Carvalho Chehab 			p->flags, prt_names(p->field, v4l2_field_names),
4615bc3cb74SMauro Carvalho Chehab 			p->sequence, prt_names(p->memory, v4l2_memory_names));
4625bc3cb74SMauro Carvalho Chehab 
4635bc3cb74SMauro Carvalho Chehab 	if (V4L2_TYPE_IS_MULTIPLANAR(p->type) && p->m.planes) {
4645bc3cb74SMauro Carvalho Chehab 		pr_cont("\n");
4655bc3cb74SMauro Carvalho Chehab 		for (i = 0; i < p->length; ++i) {
4665bc3cb74SMauro Carvalho Chehab 			plane = &p->m.planes[i];
4675bc3cb74SMauro Carvalho Chehab 			printk(KERN_DEBUG
4688720427cSMauro Carvalho Chehab 				"plane %d: bytesused=%d, data_offset=0x%08x, offset/userptr=0x%lx, length=%d\n",
4695bc3cb74SMauro Carvalho Chehab 				i, plane->bytesused, plane->data_offset,
4705bc3cb74SMauro Carvalho Chehab 				plane->m.userptr, plane->length);
4715bc3cb74SMauro Carvalho Chehab 		}
4725bc3cb74SMauro Carvalho Chehab 	} else {
473560dde24SHans Verkuil 		pr_cont(", bytesused=%d, offset/userptr=0x%lx, length=%d\n",
4745bc3cb74SMauro Carvalho Chehab 			p->bytesused, p->m.userptr, p->length);
4755bc3cb74SMauro Carvalho Chehab 	}
4765bc3cb74SMauro Carvalho Chehab 
4778720427cSMauro Carvalho Chehab 	printk(KERN_DEBUG "timecode=%02d:%02d:%02d type=%d, flags=0x%08x, frames=%d, userbits=0x%08x\n",
4785bc3cb74SMauro Carvalho Chehab 			tc->hours, tc->minutes, tc->seconds,
4795bc3cb74SMauro Carvalho Chehab 			tc->type, tc->flags, tc->frames, *(__u32 *)tc->userbits);
4805bc3cb74SMauro Carvalho Chehab }
4815bc3cb74SMauro Carvalho Chehab 
482b799d09aSTomasz Stanislawski static void v4l_print_exportbuffer(const void *arg, bool write_only)
483b799d09aSTomasz Stanislawski {
484b799d09aSTomasz Stanislawski 	const struct v4l2_exportbuffer *p = arg;
485b799d09aSTomasz Stanislawski 
486b799d09aSTomasz Stanislawski 	pr_cont("fd=%d, type=%s, index=%u, plane=%u, flags=0x%08x\n",
487b799d09aSTomasz Stanislawski 		p->fd, prt_names(p->type, v4l2_type_names),
488b799d09aSTomasz Stanislawski 		p->index, p->plane, p->flags);
489b799d09aSTomasz Stanislawski }
490b799d09aSTomasz Stanislawski 
4915bc3cb74SMauro Carvalho Chehab static void v4l_print_create_buffers(const void *arg, bool write_only)
4925bc3cb74SMauro Carvalho Chehab {
4935bc3cb74SMauro Carvalho Chehab 	const struct v4l2_create_buffers *p = arg;
4945bc3cb74SMauro Carvalho Chehab 
495319c4bd4SHelen Koike 	pr_cont("index=%d, count=%d, memory=%s, capabilities=0x%08x, ",
496319c4bd4SHelen Koike 		p->index, p->count, prt_names(p->memory, v4l2_memory_names),
497319c4bd4SHelen Koike 		p->capabilities);
4985bc3cb74SMauro Carvalho Chehab 	v4l_print_format(&p->format, write_only);
4995bc3cb74SMauro Carvalho Chehab }
5005bc3cb74SMauro Carvalho Chehab 
5015bc3cb74SMauro Carvalho Chehab static void v4l_print_streamparm(const void *arg, bool write_only)
5025bc3cb74SMauro Carvalho Chehab {
5035bc3cb74SMauro Carvalho Chehab 	const struct v4l2_streamparm *p = arg;
5045bc3cb74SMauro Carvalho Chehab 
5055bc3cb74SMauro Carvalho Chehab 	pr_cont("type=%s", prt_names(p->type, v4l2_type_names));
5065bc3cb74SMauro Carvalho Chehab 
5075bc3cb74SMauro Carvalho Chehab 	if (p->type == V4L2_BUF_TYPE_VIDEO_CAPTURE ||
5085bc3cb74SMauro Carvalho Chehab 	    p->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
5095bc3cb74SMauro Carvalho Chehab 		const struct v4l2_captureparm *c = &p->parm.capture;
5105bc3cb74SMauro Carvalho Chehab 
5118720427cSMauro Carvalho Chehab 		pr_cont(", capability=0x%x, capturemode=0x%x, timeperframe=%d/%d, extendedmode=%d, readbuffers=%d\n",
5125bc3cb74SMauro Carvalho Chehab 			c->capability, c->capturemode,
5135bc3cb74SMauro Carvalho Chehab 			c->timeperframe.numerator, c->timeperframe.denominator,
5145bc3cb74SMauro Carvalho Chehab 			c->extendedmode, c->readbuffers);
5155bc3cb74SMauro Carvalho Chehab 	} else if (p->type == V4L2_BUF_TYPE_VIDEO_OUTPUT ||
5165bc3cb74SMauro Carvalho Chehab 		   p->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
5175bc3cb74SMauro Carvalho Chehab 		const struct v4l2_outputparm *c = &p->parm.output;
5185bc3cb74SMauro Carvalho Chehab 
5198720427cSMauro Carvalho Chehab 		pr_cont(", capability=0x%x, outputmode=0x%x, timeperframe=%d/%d, extendedmode=%d, writebuffers=%d\n",
5205bc3cb74SMauro Carvalho Chehab 			c->capability, c->outputmode,
5215bc3cb74SMauro Carvalho Chehab 			c->timeperframe.numerator, c->timeperframe.denominator,
5225bc3cb74SMauro Carvalho Chehab 			c->extendedmode, c->writebuffers);
523560dde24SHans Verkuil 	} else {
524560dde24SHans Verkuil 		pr_cont("\n");
5255bc3cb74SMauro Carvalho Chehab 	}
5265bc3cb74SMauro Carvalho Chehab }
5275bc3cb74SMauro Carvalho Chehab 
5285bc3cb74SMauro Carvalho Chehab static void v4l_print_queryctrl(const void *arg, bool write_only)
5295bc3cb74SMauro Carvalho Chehab {
5305bc3cb74SMauro Carvalho Chehab 	const struct v4l2_queryctrl *p = arg;
5315bc3cb74SMauro Carvalho Chehab 
5328720427cSMauro Carvalho Chehab 	pr_cont("id=0x%x, type=%d, name=%.*s, min/max=%d/%d, step=%d, default=%d, flags=0x%08x\n",
53327d5a87cSHans Verkuil 			p->id, p->type, (int)sizeof(p->name), p->name,
5345bc3cb74SMauro Carvalho Chehab 			p->minimum, p->maximum,
5355bc3cb74SMauro Carvalho Chehab 			p->step, p->default_value, p->flags);
5365bc3cb74SMauro Carvalho Chehab }
5375bc3cb74SMauro Carvalho Chehab 
538e6bee368SHans Verkuil static void v4l_print_query_ext_ctrl(const void *arg, bool write_only)
539e6bee368SHans Verkuil {
540e6bee368SHans Verkuil 	const struct v4l2_query_ext_ctrl *p = arg;
541e6bee368SHans Verkuil 
5428720427cSMauro 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",
543e6bee368SHans Verkuil 			p->id, p->type, (int)sizeof(p->name), p->name,
544e6bee368SHans Verkuil 			p->minimum, p->maximum,
545e6bee368SHans Verkuil 			p->step, p->default_value, p->flags,
546e6bee368SHans Verkuil 			p->elem_size, p->elems, p->nr_of_dims,
5470176077aSHans Verkuil 			p->dims[0], p->dims[1], p->dims[2], p->dims[3]);
548e6bee368SHans Verkuil }
549e6bee368SHans Verkuil 
5505bc3cb74SMauro Carvalho Chehab static void v4l_print_querymenu(const void *arg, bool write_only)
5515bc3cb74SMauro Carvalho Chehab {
5525bc3cb74SMauro Carvalho Chehab 	const struct v4l2_querymenu *p = arg;
5535bc3cb74SMauro Carvalho Chehab 
5545bc3cb74SMauro Carvalho Chehab 	pr_cont("id=0x%x, index=%d\n", p->id, p->index);
5555bc3cb74SMauro Carvalho Chehab }
5565bc3cb74SMauro Carvalho Chehab 
5575bc3cb74SMauro Carvalho Chehab static void v4l_print_control(const void *arg, bool write_only)
5585bc3cb74SMauro Carvalho Chehab {
5595bc3cb74SMauro Carvalho Chehab 	const struct v4l2_control *p = arg;
560a69a7a33SEzequiel Garcia 	const char *name = v4l2_ctrl_get_name(p->id);
5615bc3cb74SMauro Carvalho Chehab 
562a69a7a33SEzequiel Garcia 	if (name)
563a69a7a33SEzequiel Garcia 		pr_cont("name=%s, ", name);
5645bc3cb74SMauro Carvalho Chehab 	pr_cont("id=0x%x, value=%d\n", p->id, p->value);
5655bc3cb74SMauro Carvalho Chehab }
5665bc3cb74SMauro Carvalho Chehab 
5675bc3cb74SMauro Carvalho Chehab static void v4l_print_ext_controls(const void *arg, bool write_only)
5685bc3cb74SMauro Carvalho Chehab {
5695bc3cb74SMauro Carvalho Chehab 	const struct v4l2_ext_controls *p = arg;
5705bc3cb74SMauro Carvalho Chehab 	int i;
5715bc3cb74SMauro Carvalho Chehab 
572f23317adSAlexandre Courbot 	pr_cont("which=0x%x, count=%d, error_idx=%d, request_fd=%d",
573f23317adSAlexandre Courbot 			p->which, p->count, p->error_idx, p->request_fd);
5745bc3cb74SMauro Carvalho Chehab 	for (i = 0; i < p->count; i++) {
575a69a7a33SEzequiel Garcia 		unsigned int id = p->controls[i].id;
576a69a7a33SEzequiel Garcia 		const char *name = v4l2_ctrl_get_name(id);
577a69a7a33SEzequiel Garcia 
578a69a7a33SEzequiel Garcia 		if (name)
579a69a7a33SEzequiel Garcia 			pr_cont(", name=%s", name);
580017ab36aSHans Verkuil 		if (!p->controls[i].size)
581a69a7a33SEzequiel Garcia 			pr_cont(", id/val=0x%x/0x%x", id, p->controls[i].value);
5825bc3cb74SMauro Carvalho Chehab 		else
583a69a7a33SEzequiel Garcia 			pr_cont(", id/size=0x%x/%u", id, p->controls[i].size);
5845bc3cb74SMauro Carvalho Chehab 	}
5855bc3cb74SMauro Carvalho Chehab 	pr_cont("\n");
5865bc3cb74SMauro Carvalho Chehab }
5875bc3cb74SMauro Carvalho Chehab 
5885bc3cb74SMauro Carvalho Chehab static void v4l_print_cropcap(const void *arg, bool write_only)
5895bc3cb74SMauro Carvalho Chehab {
5905bc3cb74SMauro Carvalho Chehab 	const struct v4l2_cropcap *p = arg;
5915bc3cb74SMauro Carvalho Chehab 
5928720427cSMauro 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",
5935bc3cb74SMauro Carvalho Chehab 		prt_names(p->type, v4l2_type_names),
5945bc3cb74SMauro Carvalho Chehab 		p->bounds.width, p->bounds.height,
5955bc3cb74SMauro Carvalho Chehab 		p->bounds.left, p->bounds.top,
5965bc3cb74SMauro Carvalho Chehab 		p->defrect.width, p->defrect.height,
5975bc3cb74SMauro Carvalho Chehab 		p->defrect.left, p->defrect.top,
5985bc3cb74SMauro Carvalho Chehab 		p->pixelaspect.numerator, p->pixelaspect.denominator);
5995bc3cb74SMauro Carvalho Chehab }
6005bc3cb74SMauro Carvalho Chehab 
6015bc3cb74SMauro Carvalho Chehab static void v4l_print_crop(const void *arg, bool write_only)
6025bc3cb74SMauro Carvalho Chehab {
6035bc3cb74SMauro Carvalho Chehab 	const struct v4l2_crop *p = arg;
6045bc3cb74SMauro Carvalho Chehab 
6055bc3cb74SMauro Carvalho Chehab 	pr_cont("type=%s, wxh=%dx%d, x,y=%d,%d\n",
6065bc3cb74SMauro Carvalho Chehab 		prt_names(p->type, v4l2_type_names),
6075bc3cb74SMauro Carvalho Chehab 		p->c.width, p->c.height,
6085bc3cb74SMauro Carvalho Chehab 		p->c.left, p->c.top);
6095bc3cb74SMauro Carvalho Chehab }
6105bc3cb74SMauro Carvalho Chehab 
6115bc3cb74SMauro Carvalho Chehab static void v4l_print_selection(const void *arg, bool write_only)
6125bc3cb74SMauro Carvalho Chehab {
6135bc3cb74SMauro Carvalho Chehab 	const struct v4l2_selection *p = arg;
6145bc3cb74SMauro Carvalho Chehab 
6155bc3cb74SMauro Carvalho Chehab 	pr_cont("type=%s, target=%d, flags=0x%x, wxh=%dx%d, x,y=%d,%d\n",
6165bc3cb74SMauro Carvalho Chehab 		prt_names(p->type, v4l2_type_names),
6175bc3cb74SMauro Carvalho Chehab 		p->target, p->flags,
6185bc3cb74SMauro Carvalho Chehab 		p->r.width, p->r.height, p->r.left, p->r.top);
6195bc3cb74SMauro Carvalho Chehab }
6205bc3cb74SMauro Carvalho Chehab 
6215bc3cb74SMauro Carvalho Chehab static void v4l_print_jpegcompression(const void *arg, bool write_only)
6225bc3cb74SMauro Carvalho Chehab {
6235bc3cb74SMauro Carvalho Chehab 	const struct v4l2_jpegcompression *p = arg;
6245bc3cb74SMauro Carvalho Chehab 
6258720427cSMauro Carvalho Chehab 	pr_cont("quality=%d, APPn=%d, APP_len=%d, COM_len=%d, jpeg_markers=0x%x\n",
6265bc3cb74SMauro Carvalho Chehab 		p->quality, p->APPn, p->APP_len,
6275bc3cb74SMauro Carvalho Chehab 		p->COM_len, p->jpeg_markers);
6285bc3cb74SMauro Carvalho Chehab }
6295bc3cb74SMauro Carvalho Chehab 
6305bc3cb74SMauro Carvalho Chehab static void v4l_print_enc_idx(const void *arg, bool write_only)
6315bc3cb74SMauro Carvalho Chehab {
6325bc3cb74SMauro Carvalho Chehab 	const struct v4l2_enc_idx *p = arg;
6335bc3cb74SMauro Carvalho Chehab 
6345bc3cb74SMauro Carvalho Chehab 	pr_cont("entries=%d, entries_cap=%d\n",
6355bc3cb74SMauro Carvalho Chehab 			p->entries, p->entries_cap);
6365bc3cb74SMauro Carvalho Chehab }
6375bc3cb74SMauro Carvalho Chehab 
6385bc3cb74SMauro Carvalho Chehab static void v4l_print_encoder_cmd(const void *arg, bool write_only)
6395bc3cb74SMauro Carvalho Chehab {
6405bc3cb74SMauro Carvalho Chehab 	const struct v4l2_encoder_cmd *p = arg;
6415bc3cb74SMauro Carvalho Chehab 
6425bc3cb74SMauro Carvalho Chehab 	pr_cont("cmd=%d, flags=0x%x\n",
6435bc3cb74SMauro Carvalho Chehab 			p->cmd, p->flags);
6445bc3cb74SMauro Carvalho Chehab }
6455bc3cb74SMauro Carvalho Chehab 
6465bc3cb74SMauro Carvalho Chehab static void v4l_print_decoder_cmd(const void *arg, bool write_only)
6475bc3cb74SMauro Carvalho Chehab {
6485bc3cb74SMauro Carvalho Chehab 	const struct v4l2_decoder_cmd *p = arg;
6495bc3cb74SMauro Carvalho Chehab 
6505bc3cb74SMauro Carvalho Chehab 	pr_cont("cmd=%d, flags=0x%x\n", p->cmd, p->flags);
6515bc3cb74SMauro Carvalho Chehab 
6525bc3cb74SMauro Carvalho Chehab 	if (p->cmd == V4L2_DEC_CMD_START)
6535bc3cb74SMauro Carvalho Chehab 		pr_info("speed=%d, format=%u\n",
6545bc3cb74SMauro Carvalho Chehab 				p->start.speed, p->start.format);
6555bc3cb74SMauro Carvalho Chehab 	else if (p->cmd == V4L2_DEC_CMD_STOP)
6565bc3cb74SMauro Carvalho Chehab 		pr_info("pts=%llu\n", p->stop.pts);
6575bc3cb74SMauro Carvalho Chehab }
6585bc3cb74SMauro Carvalho Chehab 
65996b03d2aSHans Verkuil static void v4l_print_dbg_chip_info(const void *arg, bool write_only)
66079b0c640SHans Verkuil {
66196b03d2aSHans Verkuil 	const struct v4l2_dbg_chip_info *p = arg;
66279b0c640SHans Verkuil 
66379b0c640SHans Verkuil 	pr_cont("type=%u, ", p->match.type);
6643eef2510SHans Verkuil 	if (p->match.type == V4L2_CHIP_MATCH_I2C_DRIVER)
66579b0c640SHans Verkuil 		pr_cont("name=%.*s, ",
66679b0c640SHans Verkuil 				(int)sizeof(p->match.name), p->match.name);
66779b0c640SHans Verkuil 	else
66879b0c640SHans Verkuil 		pr_cont("addr=%u, ", p->match.addr);
66979b0c640SHans Verkuil 	pr_cont("name=%.*s\n", (int)sizeof(p->name), p->name);
67079b0c640SHans Verkuil }
67179b0c640SHans Verkuil 
6725bc3cb74SMauro Carvalho Chehab static void v4l_print_dbg_register(const void *arg, bool write_only)
6735bc3cb74SMauro Carvalho Chehab {
6745bc3cb74SMauro Carvalho Chehab 	const struct v4l2_dbg_register *p = arg;
6755bc3cb74SMauro Carvalho Chehab 
6765bc3cb74SMauro Carvalho Chehab 	pr_cont("type=%u, ", p->match.type);
6773eef2510SHans Verkuil 	if (p->match.type == V4L2_CHIP_MATCH_I2C_DRIVER)
67827d5a87cSHans Verkuil 		pr_cont("name=%.*s, ",
67927d5a87cSHans Verkuil 				(int)sizeof(p->match.name), p->match.name);
6805bc3cb74SMauro Carvalho Chehab 	else
6815bc3cb74SMauro Carvalho Chehab 		pr_cont("addr=%u, ", p->match.addr);
6825bc3cb74SMauro Carvalho Chehab 	pr_cont("reg=0x%llx, val=0x%llx\n",
6835bc3cb74SMauro Carvalho Chehab 			p->reg, p->val);
6845bc3cb74SMauro Carvalho Chehab }
6855bc3cb74SMauro Carvalho Chehab 
6865bc3cb74SMauro Carvalho Chehab static void v4l_print_dv_timings(const void *arg, bool write_only)
6875bc3cb74SMauro Carvalho Chehab {
6885bc3cb74SMauro Carvalho Chehab 	const struct v4l2_dv_timings *p = arg;
6895bc3cb74SMauro Carvalho Chehab 
6905bc3cb74SMauro Carvalho Chehab 	switch (p->type) {
6915bc3cb74SMauro Carvalho Chehab 	case V4L2_DV_BT_656_1120:
6928720427cSMauro 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",
6935bc3cb74SMauro Carvalho Chehab 				p->bt.interlaced, p->bt.pixelclock,
6945bc3cb74SMauro Carvalho Chehab 				p->bt.width, p->bt.height,
6955bc3cb74SMauro Carvalho Chehab 				p->bt.polarities, p->bt.hfrontporch,
6965bc3cb74SMauro Carvalho Chehab 				p->bt.hsync, p->bt.hbackporch,
6975bc3cb74SMauro Carvalho Chehab 				p->bt.vfrontporch, p->bt.vsync,
6985bc3cb74SMauro Carvalho Chehab 				p->bt.vbackporch, p->bt.il_vfrontporch,
6995bc3cb74SMauro Carvalho Chehab 				p->bt.il_vsync, p->bt.il_vbackporch,
7005bc3cb74SMauro Carvalho Chehab 				p->bt.standards, p->bt.flags);
7015bc3cb74SMauro Carvalho Chehab 		break;
7025bc3cb74SMauro Carvalho Chehab 	default:
7035bc3cb74SMauro Carvalho Chehab 		pr_cont("type=%d\n", p->type);
7045bc3cb74SMauro Carvalho Chehab 		break;
7055bc3cb74SMauro Carvalho Chehab 	}
7065bc3cb74SMauro Carvalho Chehab }
7075bc3cb74SMauro Carvalho Chehab 
7085bc3cb74SMauro Carvalho Chehab static void v4l_print_enum_dv_timings(const void *arg, bool write_only)
7095bc3cb74SMauro Carvalho Chehab {
7105bc3cb74SMauro Carvalho Chehab 	const struct v4l2_enum_dv_timings *p = arg;
7115bc3cb74SMauro Carvalho Chehab 
7125bc3cb74SMauro Carvalho Chehab 	pr_cont("index=%u, ", p->index);
7135bc3cb74SMauro Carvalho Chehab 	v4l_print_dv_timings(&p->timings, write_only);
7145bc3cb74SMauro Carvalho Chehab }
7155bc3cb74SMauro Carvalho Chehab 
7165bc3cb74SMauro Carvalho Chehab static void v4l_print_dv_timings_cap(const void *arg, bool write_only)
7175bc3cb74SMauro Carvalho Chehab {
7185bc3cb74SMauro Carvalho Chehab 	const struct v4l2_dv_timings_cap *p = arg;
7195bc3cb74SMauro Carvalho Chehab 
7205bc3cb74SMauro Carvalho Chehab 	switch (p->type) {
7215bc3cb74SMauro Carvalho Chehab 	case V4L2_DV_BT_656_1120:
7228720427cSMauro Carvalho Chehab 		pr_cont("type=bt-656/1120, width=%u-%u, height=%u-%u, pixelclock=%llu-%llu, standards=0x%x, capabilities=0x%x\n",
7235bc3cb74SMauro Carvalho Chehab 			p->bt.min_width, p->bt.max_width,
7245bc3cb74SMauro Carvalho Chehab 			p->bt.min_height, p->bt.max_height,
7255bc3cb74SMauro Carvalho Chehab 			p->bt.min_pixelclock, p->bt.max_pixelclock,
7265bc3cb74SMauro Carvalho Chehab 			p->bt.standards, p->bt.capabilities);
7275bc3cb74SMauro Carvalho Chehab 		break;
7285bc3cb74SMauro Carvalho Chehab 	default:
7295bc3cb74SMauro Carvalho Chehab 		pr_cont("type=%u\n", p->type);
7305bc3cb74SMauro Carvalho Chehab 		break;
7315bc3cb74SMauro Carvalho Chehab 	}
7325bc3cb74SMauro Carvalho Chehab }
7335bc3cb74SMauro Carvalho Chehab 
7345bc3cb74SMauro Carvalho Chehab static void v4l_print_frmsizeenum(const void *arg, bool write_only)
7355bc3cb74SMauro Carvalho Chehab {
7365bc3cb74SMauro Carvalho Chehab 	const struct v4l2_frmsizeenum *p = arg;
7375bc3cb74SMauro Carvalho Chehab 
738e927e1e0SSakari Ailus 	pr_cont("index=%u, pixelformat=%p4cc, type=%u",
739e927e1e0SSakari Ailus 		p->index, &p->pixel_format, p->type);
7405bc3cb74SMauro Carvalho Chehab 	switch (p->type) {
7415bc3cb74SMauro Carvalho Chehab 	case V4L2_FRMSIZE_TYPE_DISCRETE:
742560dde24SHans Verkuil 		pr_cont(", wxh=%ux%u\n",
7435bc3cb74SMauro Carvalho Chehab 			p->discrete.width, p->discrete.height);
7445bc3cb74SMauro Carvalho Chehab 		break;
7455bc3cb74SMauro Carvalho Chehab 	case V4L2_FRMSIZE_TYPE_STEPWISE:
746560dde24SHans Verkuil 		pr_cont(", min=%ux%u, max=%ux%u, step=%ux%u\n",
7472489477eSRicardo Ribalda 				p->stepwise.min_width,
7482489477eSRicardo Ribalda 				p->stepwise.min_height,
7492489477eSRicardo Ribalda 				p->stepwise.max_width,
7502489477eSRicardo Ribalda 				p->stepwise.max_height,
7512489477eSRicardo Ribalda 				p->stepwise.step_width,
7522489477eSRicardo Ribalda 				p->stepwise.step_height);
7535bc3cb74SMauro Carvalho Chehab 		break;
7545bc3cb74SMauro Carvalho Chehab 	case V4L2_FRMSIZE_TYPE_CONTINUOUS:
7555bc3cb74SMauro Carvalho Chehab 	default:
7565bc3cb74SMauro Carvalho Chehab 		pr_cont("\n");
7575bc3cb74SMauro Carvalho Chehab 		break;
7585bc3cb74SMauro Carvalho Chehab 	}
7595bc3cb74SMauro Carvalho Chehab }
7605bc3cb74SMauro Carvalho Chehab 
7615bc3cb74SMauro Carvalho Chehab static void v4l_print_frmivalenum(const void *arg, bool write_only)
7625bc3cb74SMauro Carvalho Chehab {
7635bc3cb74SMauro Carvalho Chehab 	const struct v4l2_frmivalenum *p = arg;
7645bc3cb74SMauro Carvalho Chehab 
765e927e1e0SSakari Ailus 	pr_cont("index=%u, pixelformat=%p4cc, wxh=%ux%u, type=%u",
766e927e1e0SSakari Ailus 		p->index, &p->pixel_format, p->width, p->height, p->type);
7675bc3cb74SMauro Carvalho Chehab 	switch (p->type) {
7685bc3cb74SMauro Carvalho Chehab 	case V4L2_FRMIVAL_TYPE_DISCRETE:
769560dde24SHans Verkuil 		pr_cont(", fps=%d/%d\n",
7705bc3cb74SMauro Carvalho Chehab 				p->discrete.numerator,
7715bc3cb74SMauro Carvalho Chehab 				p->discrete.denominator);
7725bc3cb74SMauro Carvalho Chehab 		break;
7735bc3cb74SMauro Carvalho Chehab 	case V4L2_FRMIVAL_TYPE_STEPWISE:
774560dde24SHans Verkuil 		pr_cont(", min=%d/%d, max=%d/%d, step=%d/%d\n",
7755bc3cb74SMauro Carvalho Chehab 				p->stepwise.min.numerator,
7765bc3cb74SMauro Carvalho Chehab 				p->stepwise.min.denominator,
7775bc3cb74SMauro Carvalho Chehab 				p->stepwise.max.numerator,
7785bc3cb74SMauro Carvalho Chehab 				p->stepwise.max.denominator,
7795bc3cb74SMauro Carvalho Chehab 				p->stepwise.step.numerator,
7805bc3cb74SMauro Carvalho Chehab 				p->stepwise.step.denominator);
7815bc3cb74SMauro Carvalho Chehab 		break;
7825bc3cb74SMauro Carvalho Chehab 	case V4L2_FRMIVAL_TYPE_CONTINUOUS:
7835bc3cb74SMauro Carvalho Chehab 	default:
7845bc3cb74SMauro Carvalho Chehab 		pr_cont("\n");
7855bc3cb74SMauro Carvalho Chehab 		break;
7865bc3cb74SMauro Carvalho Chehab 	}
7875bc3cb74SMauro Carvalho Chehab }
7885bc3cb74SMauro Carvalho Chehab 
7895bc3cb74SMauro Carvalho Chehab static void v4l_print_event(const void *arg, bool write_only)
7905bc3cb74SMauro Carvalho Chehab {
7915bc3cb74SMauro Carvalho Chehab 	const struct v4l2_event *p = arg;
7925bc3cb74SMauro Carvalho Chehab 	const struct v4l2_event_ctrl *c;
7935bc3cb74SMauro Carvalho Chehab 
7941a6c0b36SArnd Bergmann 	pr_cont("type=0x%x, pending=%u, sequence=%u, id=%u, timestamp=%llu.%9.9llu\n",
7955bc3cb74SMauro Carvalho Chehab 			p->type, p->pending, p->sequence, p->id,
7965bc3cb74SMauro Carvalho Chehab 			p->timestamp.tv_sec, p->timestamp.tv_nsec);
7975bc3cb74SMauro Carvalho Chehab 	switch (p->type) {
7985bc3cb74SMauro Carvalho Chehab 	case V4L2_EVENT_VSYNC:
7995bc3cb74SMauro Carvalho Chehab 		printk(KERN_DEBUG "field=%s\n",
8005bc3cb74SMauro Carvalho Chehab 			prt_names(p->u.vsync.field, v4l2_field_names));
8015bc3cb74SMauro Carvalho Chehab 		break;
8025bc3cb74SMauro Carvalho Chehab 	case V4L2_EVENT_CTRL:
8035bc3cb74SMauro Carvalho Chehab 		c = &p->u.ctrl;
8045bc3cb74SMauro Carvalho Chehab 		printk(KERN_DEBUG "changes=0x%x, type=%u, ",
8055bc3cb74SMauro Carvalho Chehab 			c->changes, c->type);
8065bc3cb74SMauro Carvalho Chehab 		if (c->type == V4L2_CTRL_TYPE_INTEGER64)
8075bc3cb74SMauro Carvalho Chehab 			pr_cont("value64=%lld, ", c->value64);
8085bc3cb74SMauro Carvalho Chehab 		else
8095bc3cb74SMauro Carvalho Chehab 			pr_cont("value=%d, ", c->value);
8108720427cSMauro Carvalho Chehab 		pr_cont("flags=0x%x, minimum=%d, maximum=%d, step=%d, default_value=%d\n",
8115bc3cb74SMauro Carvalho Chehab 			c->flags, c->minimum, c->maximum,
8125bc3cb74SMauro Carvalho Chehab 			c->step, c->default_value);
8135bc3cb74SMauro Carvalho Chehab 		break;
8145bc3cb74SMauro Carvalho Chehab 	case V4L2_EVENT_FRAME_SYNC:
8155bc3cb74SMauro Carvalho Chehab 		pr_cont("frame_sequence=%u\n",
8165bc3cb74SMauro Carvalho Chehab 			p->u.frame_sync.frame_sequence);
8175bc3cb74SMauro Carvalho Chehab 		break;
8185bc3cb74SMauro Carvalho Chehab 	}
8195bc3cb74SMauro Carvalho Chehab }
8205bc3cb74SMauro Carvalho Chehab 
8215bc3cb74SMauro Carvalho Chehab static void v4l_print_event_subscription(const void *arg, bool write_only)
8225bc3cb74SMauro Carvalho Chehab {
8235bc3cb74SMauro Carvalho Chehab 	const struct v4l2_event_subscription *p = arg;
8245bc3cb74SMauro Carvalho Chehab 
8255bc3cb74SMauro Carvalho Chehab 	pr_cont("type=0x%x, id=0x%x, flags=0x%x\n",
8265bc3cb74SMauro Carvalho Chehab 			p->type, p->id, p->flags);
8275bc3cb74SMauro Carvalho Chehab }
8285bc3cb74SMauro Carvalho Chehab 
8295bc3cb74SMauro Carvalho Chehab static void v4l_print_sliced_vbi_cap(const void *arg, bool write_only)
8305bc3cb74SMauro Carvalho Chehab {
8315bc3cb74SMauro Carvalho Chehab 	const struct v4l2_sliced_vbi_cap *p = arg;
8325bc3cb74SMauro Carvalho Chehab 	int i;
8335bc3cb74SMauro Carvalho Chehab 
8345bc3cb74SMauro Carvalho Chehab 	pr_cont("type=%s, service_set=0x%08x\n",
8355bc3cb74SMauro Carvalho Chehab 			prt_names(p->type, v4l2_type_names), p->service_set);
8365bc3cb74SMauro Carvalho Chehab 	for (i = 0; i < 24; i++)
8375bc3cb74SMauro Carvalho Chehab 		printk(KERN_DEBUG "line[%02u]=0x%04x, 0x%04x\n", i,
8385bc3cb74SMauro Carvalho Chehab 				p->service_lines[0][i],
8395bc3cb74SMauro Carvalho Chehab 				p->service_lines[1][i]);
8405bc3cb74SMauro Carvalho Chehab }
8415bc3cb74SMauro Carvalho Chehab 
8425bc3cb74SMauro Carvalho Chehab static void v4l_print_freq_band(const void *arg, bool write_only)
8435bc3cb74SMauro Carvalho Chehab {
8445bc3cb74SMauro Carvalho Chehab 	const struct v4l2_frequency_band *p = arg;
8455bc3cb74SMauro Carvalho Chehab 
8468720427cSMauro Carvalho Chehab 	pr_cont("tuner=%u, type=%u, index=%u, capability=0x%x, rangelow=%u, rangehigh=%u, modulation=0x%x\n",
8475bc3cb74SMauro Carvalho Chehab 			p->tuner, p->type, p->index,
8485bc3cb74SMauro Carvalho Chehab 			p->capability, p->rangelow,
8495bc3cb74SMauro Carvalho Chehab 			p->rangehigh, p->modulation);
8505bc3cb74SMauro Carvalho Chehab }
8515bc3cb74SMauro Carvalho Chehab 
852dd519bb3SHans Verkuil static void v4l_print_edid(const void *arg, bool write_only)
853dd519bb3SHans Verkuil {
854dd519bb3SHans Verkuil 	const struct v4l2_edid *p = arg;
855dd519bb3SHans Verkuil 
856dd519bb3SHans Verkuil 	pr_cont("pad=%u, start_block=%u, blocks=%u\n",
857dd519bb3SHans Verkuil 		p->pad, p->start_block, p->blocks);
858dd519bb3SHans Verkuil }
859dd519bb3SHans Verkuil 
8605bc3cb74SMauro Carvalho Chehab static void v4l_print_u32(const void *arg, bool write_only)
8615bc3cb74SMauro Carvalho Chehab {
8625bc3cb74SMauro Carvalho Chehab 	pr_cont("value=%u\n", *(const u32 *)arg);
8635bc3cb74SMauro Carvalho Chehab }
8645bc3cb74SMauro Carvalho Chehab 
8655bc3cb74SMauro Carvalho Chehab static void v4l_print_newline(const void *arg, bool write_only)
8665bc3cb74SMauro Carvalho Chehab {
8675bc3cb74SMauro Carvalho Chehab 	pr_cont("\n");
8685bc3cb74SMauro Carvalho Chehab }
8695bc3cb74SMauro Carvalho Chehab 
8705bc3cb74SMauro Carvalho Chehab static void v4l_print_default(const void *arg, bool write_only)
8715bc3cb74SMauro Carvalho Chehab {
8725bc3cb74SMauro Carvalho Chehab 	pr_cont("driver-specific ioctl\n");
8735bc3cb74SMauro Carvalho Chehab }
8745bc3cb74SMauro Carvalho Chehab 
875861f92cbSRicardo Ribalda static bool check_ext_ctrls(struct v4l2_ext_controls *c, unsigned long ioctl)
8765bc3cb74SMauro Carvalho Chehab {
8775bc3cb74SMauro Carvalho Chehab 	__u32 i;
8785bc3cb74SMauro Carvalho Chehab 
8795bc3cb74SMauro Carvalho Chehab 	/* zero the reserved fields */
880f23317adSAlexandre Courbot 	c->reserved[0] = 0;
8815bc3cb74SMauro Carvalho Chehab 	for (i = 0; i < c->count; i++)
8825bc3cb74SMauro Carvalho Chehab 		c->controls[i].reserved2[0] = 0;
8835bc3cb74SMauro Carvalho Chehab 
884861f92cbSRicardo Ribalda 	switch (c->which) {
885861f92cbSRicardo Ribalda 	case V4L2_CID_PRIVATE_BASE:
886861f92cbSRicardo Ribalda 		/*
887861f92cbSRicardo Ribalda 		 * V4L2_CID_PRIVATE_BASE cannot be used as control class
888861f92cbSRicardo Ribalda 		 * when using extended controls.
889861f92cbSRicardo Ribalda 		 * Only when passed in through VIDIOC_G_CTRL and VIDIOC_S_CTRL
890861f92cbSRicardo Ribalda 		 * is it allowed for backwards compatibility.
8915bc3cb74SMauro Carvalho Chehab 		 */
892861f92cbSRicardo Ribalda 		if (ioctl == VIDIOC_G_CTRL || ioctl == VIDIOC_S_CTRL)
893861f92cbSRicardo Ribalda 			return false;
894861f92cbSRicardo Ribalda 		break;
895861f92cbSRicardo Ribalda 	case V4L2_CTRL_WHICH_DEF_VAL:
896861f92cbSRicardo Ribalda 		/* Default value cannot be changed */
897861f92cbSRicardo Ribalda 		if (ioctl == VIDIOC_S_EXT_CTRLS ||
898861f92cbSRicardo Ribalda 		    ioctl == VIDIOC_TRY_EXT_CTRLS) {
899861f92cbSRicardo Ribalda 			c->error_idx = c->count;
900861f92cbSRicardo Ribalda 			return false;
901861f92cbSRicardo Ribalda 		}
902861f92cbSRicardo Ribalda 		return true;
903861f92cbSRicardo Ribalda 	case V4L2_CTRL_WHICH_CUR_VAL:
904861f92cbSRicardo Ribalda 		return true;
905861f92cbSRicardo Ribalda 	case V4L2_CTRL_WHICH_REQUEST_VAL:
906861f92cbSRicardo Ribalda 		c->error_idx = c->count;
907861f92cbSRicardo Ribalda 		return false;
908861f92cbSRicardo Ribalda 	}
909861f92cbSRicardo Ribalda 
9105bc3cb74SMauro Carvalho Chehab 	/* Check that all controls are from the same control class. */
9115bc3cb74SMauro Carvalho Chehab 	for (i = 0; i < c->count; i++) {
9120f8017beSRicardo Ribalda 		if (V4L2_CTRL_ID2WHICH(c->controls[i].id) != c->which) {
913861f92cbSRicardo Ribalda 			c->error_idx = ioctl == VIDIOC_TRY_EXT_CTRLS ? i :
914861f92cbSRicardo Ribalda 								      c->count;
915861f92cbSRicardo Ribalda 			return false;
9165bc3cb74SMauro Carvalho Chehab 		}
9175bc3cb74SMauro Carvalho Chehab 	}
918861f92cbSRicardo Ribalda 	return true;
9195bc3cb74SMauro Carvalho Chehab }
9205bc3cb74SMauro Carvalho Chehab 
9214b20259fSHans Verkuil static int check_fmt(struct file *file, enum v4l2_buf_type type)
9225bc3cb74SMauro Carvalho Chehab {
92396f49c1aSVandana BN 	const u32 vid_caps = V4L2_CAP_VIDEO_CAPTURE |
92496f49c1aSVandana BN 			     V4L2_CAP_VIDEO_CAPTURE_MPLANE |
92596f49c1aSVandana BN 			     V4L2_CAP_VIDEO_OUTPUT |
92696f49c1aSVandana BN 			     V4L2_CAP_VIDEO_OUTPUT_MPLANE |
92796f49c1aSVandana BN 			     V4L2_CAP_VIDEO_M2M | V4L2_CAP_VIDEO_M2M_MPLANE;
92896f49c1aSVandana BN 	const u32 meta_caps = V4L2_CAP_META_CAPTURE |
92996f49c1aSVandana BN 			      V4L2_CAP_META_OUTPUT;
9304b20259fSHans Verkuil 	struct video_device *vfd = video_devdata(file);
9314b20259fSHans Verkuil 	const struct v4l2_ioctl_ops *ops = vfd->ioctl_ops;
932238e4a5bSHans Verkuil 	bool is_vid = vfd->vfl_type == VFL_TYPE_VIDEO &&
93396f49c1aSVandana BN 		      (vfd->device_caps & vid_caps);
9344b20259fSHans Verkuil 	bool is_vbi = vfd->vfl_type == VFL_TYPE_VBI;
935582c52cbSAntti Palosaari 	bool is_sdr = vfd->vfl_type == VFL_TYPE_SDR;
936b2fe22d0SNick Dyer 	bool is_tch = vfd->vfl_type == VFL_TYPE_TOUCH;
937238e4a5bSHans Verkuil 	bool is_meta = vfd->vfl_type == VFL_TYPE_VIDEO &&
93896f49c1aSVandana BN 		       (vfd->device_caps & meta_caps);
9394b20259fSHans Verkuil 	bool is_rx = vfd->vfl_dir != VFL_DIR_TX;
9404b20259fSHans Verkuil 	bool is_tx = vfd->vfl_dir != VFL_DIR_RX;
9414b20259fSHans Verkuil 
9425bc3cb74SMauro Carvalho Chehab 	if (ops == NULL)
9435bc3cb74SMauro Carvalho Chehab 		return -EINVAL;
9445bc3cb74SMauro Carvalho Chehab 
9455bc3cb74SMauro Carvalho Chehab 	switch (type) {
9465bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_CAPTURE:
947b2fe22d0SNick Dyer 		if ((is_vid || is_tch) && is_rx &&
9484b20259fSHans Verkuil 		    (ops->vidioc_g_fmt_vid_cap || ops->vidioc_g_fmt_vid_cap_mplane))
9495bc3cb74SMauro Carvalho Chehab 			return 0;
9505bc3cb74SMauro Carvalho Chehab 		break;
9515bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
952095c21d3SHans Verkuil 		if ((is_vid || is_tch) && is_rx && ops->vidioc_g_fmt_vid_cap_mplane)
9535bc3cb74SMauro Carvalho Chehab 			return 0;
9545bc3cb74SMauro Carvalho Chehab 		break;
9555bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_OVERLAY:
9564b20259fSHans Verkuil 		if (is_vid && is_rx && ops->vidioc_g_fmt_vid_overlay)
9575bc3cb74SMauro Carvalho Chehab 			return 0;
9585bc3cb74SMauro Carvalho Chehab 		break;
9595bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_OUTPUT:
9604b20259fSHans Verkuil 		if (is_vid && is_tx &&
9614b20259fSHans Verkuil 		    (ops->vidioc_g_fmt_vid_out || ops->vidioc_g_fmt_vid_out_mplane))
9625bc3cb74SMauro Carvalho Chehab 			return 0;
9635bc3cb74SMauro Carvalho Chehab 		break;
9645bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
9654b20259fSHans Verkuil 		if (is_vid && is_tx && ops->vidioc_g_fmt_vid_out_mplane)
9665bc3cb74SMauro Carvalho Chehab 			return 0;
9675bc3cb74SMauro Carvalho Chehab 		break;
9685bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
9694b20259fSHans Verkuil 		if (is_vid && is_tx && ops->vidioc_g_fmt_vid_out_overlay)
9705bc3cb74SMauro Carvalho Chehab 			return 0;
9715bc3cb74SMauro Carvalho Chehab 		break;
9725bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VBI_CAPTURE:
9734b20259fSHans Verkuil 		if (is_vbi && is_rx && ops->vidioc_g_fmt_vbi_cap)
9745bc3cb74SMauro Carvalho Chehab 			return 0;
9755bc3cb74SMauro Carvalho Chehab 		break;
9765bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VBI_OUTPUT:
9774b20259fSHans Verkuil 		if (is_vbi && is_tx && ops->vidioc_g_fmt_vbi_out)
9785bc3cb74SMauro Carvalho Chehab 			return 0;
9795bc3cb74SMauro Carvalho Chehab 		break;
9805bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
9814b20259fSHans Verkuil 		if (is_vbi && is_rx && ops->vidioc_g_fmt_sliced_vbi_cap)
9825bc3cb74SMauro Carvalho Chehab 			return 0;
9835bc3cb74SMauro Carvalho Chehab 		break;
9845bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
9854b20259fSHans Verkuil 		if (is_vbi && is_tx && ops->vidioc_g_fmt_sliced_vbi_out)
9865bc3cb74SMauro Carvalho Chehab 			return 0;
9875bc3cb74SMauro Carvalho Chehab 		break;
988582c52cbSAntti Palosaari 	case V4L2_BUF_TYPE_SDR_CAPTURE:
989582c52cbSAntti Palosaari 		if (is_sdr && is_rx && ops->vidioc_g_fmt_sdr_cap)
990582c52cbSAntti Palosaari 			return 0;
991582c52cbSAntti Palosaari 		break;
9929effc72fSAntti Palosaari 	case V4L2_BUF_TYPE_SDR_OUTPUT:
9939effc72fSAntti Palosaari 		if (is_sdr && is_tx && ops->vidioc_g_fmt_sdr_out)
9949effc72fSAntti Palosaari 			return 0;
9959effc72fSAntti Palosaari 		break;
996fb9ffa6aSLaurent Pinchart 	case V4L2_BUF_TYPE_META_CAPTURE:
99796f49c1aSVandana BN 		if (is_meta && is_rx && ops->vidioc_g_fmt_meta_cap)
998fb9ffa6aSLaurent Pinchart 			return 0;
999fb9ffa6aSLaurent Pinchart 		break;
100072148d1aSSakari Ailus 	case V4L2_BUF_TYPE_META_OUTPUT:
100196f49c1aSVandana BN 		if (is_meta && is_tx && ops->vidioc_g_fmt_meta_out)
100272148d1aSSakari Ailus 			return 0;
100372148d1aSSakari Ailus 		break;
1004633c98e5SHans Verkuil 	default:
10055bc3cb74SMauro Carvalho Chehab 		break;
10065bc3cb74SMauro Carvalho Chehab 	}
10075bc3cb74SMauro Carvalho Chehab 	return -EINVAL;
10085bc3cb74SMauro Carvalho Chehab }
10095bc3cb74SMauro Carvalho Chehab 
1010d52e2381SLaurent Pinchart static void v4l_sanitize_format(struct v4l2_format *fmt)
1011d52e2381SLaurent Pinchart {
1012d52e2381SLaurent Pinchart 	unsigned int offset;
1013d52e2381SLaurent Pinchart 
101414c8e80eSEzequiel Garcia 	/* Make sure num_planes is not bogus */
101514c8e80eSEzequiel Garcia 	if (fmt->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE ||
101614c8e80eSEzequiel Garcia 	    fmt->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)
101714c8e80eSEzequiel Garcia 		fmt->fmt.pix_mp.num_planes = min_t(u32, fmt->fmt.pix_mp.num_planes,
101814c8e80eSEzequiel Garcia 					       VIDEO_MAX_PLANES);
101914c8e80eSEzequiel Garcia 
1020d52e2381SLaurent Pinchart 	/*
1021d52e2381SLaurent Pinchart 	 * The v4l2_pix_format structure has been extended with fields that were
1022d52e2381SLaurent Pinchart 	 * not previously required to be set to zero by applications. The priv
1023d52e2381SLaurent Pinchart 	 * field, when set to a magic value, indicates the the extended fields
1024d52e2381SLaurent Pinchart 	 * are valid. Otherwise they will contain undefined values. To simplify
1025d52e2381SLaurent Pinchart 	 * the API towards drivers zero the extended fields and set the priv
1026d52e2381SLaurent Pinchart 	 * field to the magic value when the extended pixel format structure
1027d52e2381SLaurent Pinchart 	 * isn't used by applications.
1028d52e2381SLaurent Pinchart 	 */
1029d52e2381SLaurent Pinchart 
1030d52e2381SLaurent Pinchart 	if (fmt->type != V4L2_BUF_TYPE_VIDEO_CAPTURE &&
1031d52e2381SLaurent Pinchart 	    fmt->type != V4L2_BUF_TYPE_VIDEO_OUTPUT)
1032d52e2381SLaurent Pinchart 		return;
1033d52e2381SLaurent Pinchart 
1034d52e2381SLaurent Pinchart 	if (fmt->fmt.pix.priv == V4L2_PIX_FMT_PRIV_MAGIC)
1035d52e2381SLaurent Pinchart 		return;
1036d52e2381SLaurent Pinchart 
1037d52e2381SLaurent Pinchart 	fmt->fmt.pix.priv = V4L2_PIX_FMT_PRIV_MAGIC;
1038d52e2381SLaurent Pinchart 
1039d52e2381SLaurent Pinchart 	offset = offsetof(struct v4l2_pix_format, priv)
1040d52e2381SLaurent Pinchart 	       + sizeof(fmt->fmt.pix.priv);
1041d52e2381SLaurent Pinchart 	memset(((void *)&fmt->fmt.pix) + offset, 0,
1042d52e2381SLaurent Pinchart 	       sizeof(fmt->fmt.pix) - offset);
1043d52e2381SLaurent Pinchart }
1044d52e2381SLaurent Pinchart 
10455bc3cb74SMauro Carvalho Chehab static int v4l_querycap(const struct v4l2_ioctl_ops *ops,
10465bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
10475bc3cb74SMauro Carvalho Chehab {
10485bc3cb74SMauro Carvalho Chehab 	struct v4l2_capability *cap = (struct v4l2_capability *)arg;
10497bbe7813SHans Verkuil 	struct video_device *vfd = video_devdata(file);
1050d52e2381SLaurent Pinchart 	int ret;
10515bc3cb74SMauro Carvalho Chehab 
10525bc3cb74SMauro Carvalho Chehab 	cap->version = LINUX_VERSION_CODE;
10537bbe7813SHans Verkuil 	cap->device_caps = vfd->device_caps;
10547bbe7813SHans Verkuil 	cap->capabilities = vfd->device_caps | V4L2_CAP_DEVICE_CAPS;
1055d52e2381SLaurent Pinchart 
1056f2d8b691SSakari Ailus 	media_set_bus_info(cap->bus_info, sizeof(cap->bus_info),
1057f2d8b691SSakari Ailus 			   vfd->dev_parent);
1058f2d8b691SSakari Ailus 
1059d52e2381SLaurent Pinchart 	ret = ops->vidioc_querycap(file, fh, cap);
1060d52e2381SLaurent Pinchart 
1061454a4e72SHans Verkuil 	/*
10623c135050SHans Verkuil 	 * Drivers must not change device_caps, so check for this and
10633c135050SHans Verkuil 	 * warn if this happened.
1064454a4e72SHans Verkuil 	 */
10653c135050SHans Verkuil 	WARN_ON(cap->device_caps != vfd->device_caps);
10663c135050SHans Verkuil 	/*
10673c135050SHans Verkuil 	 * Check that capabilities is a superset of
10683c135050SHans Verkuil 	 * vfd->device_caps | V4L2_CAP_DEVICE_CAPS
10693c135050SHans Verkuil 	 */
10703c135050SHans Verkuil 	WARN_ON((cap->capabilities &
10713c135050SHans Verkuil 		 (vfd->device_caps | V4L2_CAP_DEVICE_CAPS)) !=
10723c135050SHans Verkuil 		(vfd->device_caps | V4L2_CAP_DEVICE_CAPS));
10733c135050SHans Verkuil 	cap->capabilities |= V4L2_CAP_EXT_PIX_FORMAT;
1074796a2bd2SHans Verkuil 	cap->device_caps |= V4L2_CAP_EXT_PIX_FORMAT;
1075d52e2381SLaurent Pinchart 
1076d52e2381SLaurent Pinchart 	return ret;
10775bc3cb74SMauro Carvalho Chehab }
10785bc3cb74SMauro Carvalho Chehab 
1079f645e625SNiklas Söderlund static int v4l_g_input(const struct v4l2_ioctl_ops *ops,
1080f645e625SNiklas Söderlund 		       struct file *file, void *fh, void *arg)
1081f645e625SNiklas Söderlund {
1082f645e625SNiklas Söderlund 	struct video_device *vfd = video_devdata(file);
1083f645e625SNiklas Söderlund 
1084f645e625SNiklas Söderlund 	if (vfd->device_caps & V4L2_CAP_IO_MC) {
1085f645e625SNiklas Söderlund 		*(int *)arg = 0;
1086f645e625SNiklas Söderlund 		return 0;
1087f645e625SNiklas Söderlund 	}
1088f645e625SNiklas Söderlund 
1089f645e625SNiklas Söderlund 	return ops->vidioc_g_input(file, fh, arg);
1090f645e625SNiklas Söderlund }
1091f645e625SNiklas Söderlund 
1092f645e625SNiklas Söderlund static int v4l_g_output(const struct v4l2_ioctl_ops *ops,
1093f645e625SNiklas Söderlund 			struct file *file, void *fh, void *arg)
1094f645e625SNiklas Söderlund {
1095f645e625SNiklas Söderlund 	struct video_device *vfd = video_devdata(file);
1096f645e625SNiklas Söderlund 
1097f645e625SNiklas Söderlund 	if (vfd->device_caps & V4L2_CAP_IO_MC) {
1098f645e625SNiklas Söderlund 		*(int *)arg = 0;
1099f645e625SNiklas Söderlund 		return 0;
1100f645e625SNiklas Söderlund 	}
1101f645e625SNiklas Söderlund 
1102f645e625SNiklas Söderlund 	return ops->vidioc_g_output(file, fh, arg);
1103f645e625SNiklas Söderlund }
1104f645e625SNiklas Söderlund 
11055bc3cb74SMauro Carvalho Chehab static int v4l_s_input(const struct v4l2_ioctl_ops *ops,
11065bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
11075bc3cb74SMauro Carvalho Chehab {
110877fa4e07SShuah Khan 	struct video_device *vfd = video_devdata(file);
110977fa4e07SShuah Khan 	int ret;
111077fa4e07SShuah Khan 
111177fa4e07SShuah Khan 	ret = v4l_enable_media_source(vfd);
111277fa4e07SShuah Khan 	if (ret)
111377fa4e07SShuah Khan 		return ret;
1114f645e625SNiklas Söderlund 
1115f645e625SNiklas Söderlund 	if (vfd->device_caps & V4L2_CAP_IO_MC)
1116f645e625SNiklas Söderlund 		return  *(int *)arg ? -EINVAL : 0;
1117f645e625SNiklas Söderlund 
11185bc3cb74SMauro Carvalho Chehab 	return ops->vidioc_s_input(file, fh, *(unsigned int *)arg);
11195bc3cb74SMauro Carvalho Chehab }
11205bc3cb74SMauro Carvalho Chehab 
11215bc3cb74SMauro Carvalho Chehab static int v4l_s_output(const struct v4l2_ioctl_ops *ops,
11225bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
11235bc3cb74SMauro Carvalho Chehab {
1124f645e625SNiklas Söderlund 	struct video_device *vfd = video_devdata(file);
1125f645e625SNiklas Söderlund 
1126f645e625SNiklas Söderlund 	if (vfd->device_caps & V4L2_CAP_IO_MC)
1127f645e625SNiklas Söderlund 		return  *(int *)arg ? -EINVAL : 0;
1128f645e625SNiklas Söderlund 
11295bc3cb74SMauro Carvalho Chehab 	return ops->vidioc_s_output(file, fh, *(unsigned int *)arg);
11305bc3cb74SMauro Carvalho Chehab }
11315bc3cb74SMauro Carvalho Chehab 
11325bc3cb74SMauro Carvalho Chehab static int v4l_g_priority(const struct v4l2_ioctl_ops *ops,
11335bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
11345bc3cb74SMauro Carvalho Chehab {
11355bc3cb74SMauro Carvalho Chehab 	struct video_device *vfd;
11365bc3cb74SMauro Carvalho Chehab 	u32 *p = arg;
11375bc3cb74SMauro Carvalho Chehab 
11385bc3cb74SMauro Carvalho Chehab 	vfd = video_devdata(file);
113959b702eaSLaurent Pinchart 	*p = v4l2_prio_max(vfd->prio);
11405bc3cb74SMauro Carvalho Chehab 	return 0;
11415bc3cb74SMauro Carvalho Chehab }
11425bc3cb74SMauro Carvalho Chehab 
11435bc3cb74SMauro Carvalho Chehab static int v4l_s_priority(const struct v4l2_ioctl_ops *ops,
11445bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
11455bc3cb74SMauro Carvalho Chehab {
11465bc3cb74SMauro Carvalho Chehab 	struct video_device *vfd;
11475bc3cb74SMauro Carvalho Chehab 	struct v4l2_fh *vfh;
11485bc3cb74SMauro Carvalho Chehab 	u32 *p = arg;
11495bc3cb74SMauro Carvalho Chehab 
11505bc3cb74SMauro Carvalho Chehab 	vfd = video_devdata(file);
11512438e78aSHans Verkuil 	if (!test_bit(V4L2_FL_USES_V4L2_FH, &vfd->flags))
11522438e78aSHans Verkuil 		return -ENOTTY;
11535bc3cb74SMauro Carvalho Chehab 	vfh = file->private_data;
115459b702eaSLaurent Pinchart 	return v4l2_prio_change(vfd->prio, &vfh->prio, *p);
11555bc3cb74SMauro Carvalho Chehab }
11565bc3cb74SMauro Carvalho Chehab 
11575bc3cb74SMauro Carvalho Chehab static int v4l_enuminput(const struct v4l2_ioctl_ops *ops,
11585bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
11595bc3cb74SMauro Carvalho Chehab {
116073f35418SHans Verkuil 	struct video_device *vfd = video_devdata(file);
11615bc3cb74SMauro Carvalho Chehab 	struct v4l2_input *p = arg;
11625bc3cb74SMauro Carvalho Chehab 
11635bc3cb74SMauro Carvalho Chehab 	/*
116402fa6282SHans Verkuil 	 * We set the flags for CAP_DV_TIMINGS &
11655bc3cb74SMauro Carvalho Chehab 	 * CAP_STD here based on ioctl handler provided by the
11665bc3cb74SMauro Carvalho Chehab 	 * driver. If the driver doesn't support these
11675bc3cb74SMauro Carvalho Chehab 	 * for a specific input, it must override these flags.
11685bc3cb74SMauro Carvalho Chehab 	 */
116973f35418SHans Verkuil 	if (is_valid_ioctl(vfd, VIDIOC_S_STD))
11705bc3cb74SMauro Carvalho Chehab 		p->capabilities |= V4L2_IN_CAP_STD;
11715bc3cb74SMauro Carvalho Chehab 
1172f645e625SNiklas Söderlund 	if (vfd->device_caps & V4L2_CAP_IO_MC) {
1173f645e625SNiklas Söderlund 		if (p->index)
1174f645e625SNiklas Söderlund 			return -EINVAL;
1175f645e625SNiklas Söderlund 		strscpy(p->name, vfd->name, sizeof(p->name));
1176f645e625SNiklas Söderlund 		p->type = V4L2_INPUT_TYPE_CAMERA;
1177f645e625SNiklas Söderlund 		return 0;
1178f645e625SNiklas Söderlund 	}
1179f645e625SNiklas Söderlund 
11805bc3cb74SMauro Carvalho Chehab 	return ops->vidioc_enum_input(file, fh, p);
11815bc3cb74SMauro Carvalho Chehab }
11825bc3cb74SMauro Carvalho Chehab 
11835bc3cb74SMauro Carvalho Chehab static int v4l_enumoutput(const struct v4l2_ioctl_ops *ops,
11845bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
11855bc3cb74SMauro Carvalho Chehab {
118673f35418SHans Verkuil 	struct video_device *vfd = video_devdata(file);
11875bc3cb74SMauro Carvalho Chehab 	struct v4l2_output *p = arg;
11885bc3cb74SMauro Carvalho Chehab 
11895bc3cb74SMauro Carvalho Chehab 	/*
119002fa6282SHans Verkuil 	 * We set the flags for CAP_DV_TIMINGS &
11915bc3cb74SMauro Carvalho Chehab 	 * CAP_STD here based on ioctl handler provided by the
11925bc3cb74SMauro Carvalho Chehab 	 * driver. If the driver doesn't support these
11935bc3cb74SMauro Carvalho Chehab 	 * for a specific output, it must override these flags.
11945bc3cb74SMauro Carvalho Chehab 	 */
119573f35418SHans Verkuil 	if (is_valid_ioctl(vfd, VIDIOC_S_STD))
11965bc3cb74SMauro Carvalho Chehab 		p->capabilities |= V4L2_OUT_CAP_STD;
11975bc3cb74SMauro Carvalho Chehab 
1198f645e625SNiklas Söderlund 	if (vfd->device_caps & V4L2_CAP_IO_MC) {
1199f645e625SNiklas Söderlund 		if (p->index)
1200f645e625SNiklas Söderlund 			return -EINVAL;
1201f645e625SNiklas Söderlund 		strscpy(p->name, vfd->name, sizeof(p->name));
1202f645e625SNiklas Söderlund 		p->type = V4L2_OUTPUT_TYPE_ANALOG;
1203f645e625SNiklas Söderlund 		return 0;
1204f645e625SNiklas Söderlund 	}
1205f645e625SNiklas Söderlund 
12065bc3cb74SMauro Carvalho Chehab 	return ops->vidioc_enum_output(file, fh, p);
12075bc3cb74SMauro Carvalho Chehab }
12085bc3cb74SMauro Carvalho Chehab 
1209ba300204SHans Verkuil static void v4l_fill_fmtdesc(struct v4l2_fmtdesc *fmt)
1210ba300204SHans Verkuil {
1211ba300204SHans Verkuil 	const unsigned sz = sizeof(fmt->description);
1212ba300204SHans Verkuil 	const char *descr = NULL;
1213ba300204SHans Verkuil 	u32 flags = 0;
1214ba300204SHans Verkuil 
1215ba300204SHans Verkuil 	/*
1216ba300204SHans Verkuil 	 * We depart from the normal coding style here since the descriptions
1217ba300204SHans Verkuil 	 * should be aligned so it is easy to see which descriptions will be
1218ba300204SHans Verkuil 	 * longer than 31 characters (the max length for a description).
1219ba300204SHans Verkuil 	 * And frankly, this is easier to read anyway.
1220ba300204SHans Verkuil 	 *
1221ba300204SHans Verkuil 	 * Note that gcc will use O(log N) comparisons to find the right case.
1222ba300204SHans Verkuil 	 */
1223ba300204SHans Verkuil 	switch (fmt->pixelformat) {
1224ba300204SHans Verkuil 	/* Max description length mask:	descr = "0123456789012345678901234567890" */
1225ba300204SHans Verkuil 	case V4L2_PIX_FMT_RGB332:	descr = "8-bit RGB 3-3-2"; break;
1226ba300204SHans Verkuil 	case V4L2_PIX_FMT_RGB444:	descr = "16-bit A/XRGB 4-4-4-4"; break;
1227ba300204SHans Verkuil 	case V4L2_PIX_FMT_ARGB444:	descr = "16-bit ARGB 4-4-4-4"; break;
1228ba300204SHans Verkuil 	case V4L2_PIX_FMT_XRGB444:	descr = "16-bit XRGB 4-4-4-4"; break;
12294747bd0fSHans Verkuil 	case V4L2_PIX_FMT_RGBA444:	descr = "16-bit RGBA 4-4-4-4"; break;
12304747bd0fSHans Verkuil 	case V4L2_PIX_FMT_RGBX444:	descr = "16-bit RGBX 4-4-4-4"; break;
12314747bd0fSHans Verkuil 	case V4L2_PIX_FMT_ABGR444:	descr = "16-bit ABGR 4-4-4-4"; break;
12324747bd0fSHans Verkuil 	case V4L2_PIX_FMT_XBGR444:	descr = "16-bit XBGR 4-4-4-4"; break;
12334747bd0fSHans Verkuil 	case V4L2_PIX_FMT_BGRA444:	descr = "16-bit BGRA 4-4-4-4"; break;
12344747bd0fSHans Verkuil 	case V4L2_PIX_FMT_BGRX444:	descr = "16-bit BGRX 4-4-4-4"; break;
1235ba300204SHans Verkuil 	case V4L2_PIX_FMT_RGB555:	descr = "16-bit A/XRGB 1-5-5-5"; break;
1236ba300204SHans Verkuil 	case V4L2_PIX_FMT_ARGB555:	descr = "16-bit ARGB 1-5-5-5"; break;
1237ba300204SHans Verkuil 	case V4L2_PIX_FMT_XRGB555:	descr = "16-bit XRGB 1-5-5-5"; break;
12384747bd0fSHans Verkuil 	case V4L2_PIX_FMT_ABGR555:	descr = "16-bit ABGR 1-5-5-5"; break;
12394747bd0fSHans Verkuil 	case V4L2_PIX_FMT_XBGR555:	descr = "16-bit XBGR 1-5-5-5"; break;
12404747bd0fSHans Verkuil 	case V4L2_PIX_FMT_RGBA555:	descr = "16-bit RGBA 5-5-5-1"; break;
12414747bd0fSHans Verkuil 	case V4L2_PIX_FMT_RGBX555:	descr = "16-bit RGBX 5-5-5-1"; break;
12424747bd0fSHans Verkuil 	case V4L2_PIX_FMT_BGRA555:	descr = "16-bit BGRA 5-5-5-1"; break;
12434747bd0fSHans Verkuil 	case V4L2_PIX_FMT_BGRX555:	descr = "16-bit BGRX 5-5-5-1"; break;
1244ba300204SHans Verkuil 	case V4L2_PIX_FMT_RGB565:	descr = "16-bit RGB 5-6-5"; break;
1245ba300204SHans Verkuil 	case V4L2_PIX_FMT_RGB555X:	descr = "16-bit A/XRGB 1-5-5-5 BE"; break;
1246ba300204SHans Verkuil 	case V4L2_PIX_FMT_ARGB555X:	descr = "16-bit ARGB 1-5-5-5 BE"; break;
1247ba300204SHans Verkuil 	case V4L2_PIX_FMT_XRGB555X:	descr = "16-bit XRGB 1-5-5-5 BE"; break;
1248ba300204SHans Verkuil 	case V4L2_PIX_FMT_RGB565X:	descr = "16-bit RGB 5-6-5 BE"; break;
1249ba300204SHans Verkuil 	case V4L2_PIX_FMT_BGR666:	descr = "18-bit BGRX 6-6-6-14"; break;
1250ba300204SHans Verkuil 	case V4L2_PIX_FMT_BGR24:	descr = "24-bit BGR 8-8-8"; break;
1251ba300204SHans Verkuil 	case V4L2_PIX_FMT_RGB24:	descr = "24-bit RGB 8-8-8"; break;
1252ba300204SHans Verkuil 	case V4L2_PIX_FMT_BGR32:	descr = "32-bit BGRA/X 8-8-8-8"; break;
1253ba300204SHans Verkuil 	case V4L2_PIX_FMT_ABGR32:	descr = "32-bit BGRA 8-8-8-8"; break;
1254ba300204SHans Verkuil 	case V4L2_PIX_FMT_XBGR32:	descr = "32-bit BGRX 8-8-8-8"; break;
1255ba300204SHans Verkuil 	case V4L2_PIX_FMT_RGB32:	descr = "32-bit A/XRGB 8-8-8-8"; break;
1256ba300204SHans Verkuil 	case V4L2_PIX_FMT_ARGB32:	descr = "32-bit ARGB 8-8-8-8"; break;
1257ba300204SHans Verkuil 	case V4L2_PIX_FMT_XRGB32:	descr = "32-bit XRGB 8-8-8-8"; break;
12584747bd0fSHans Verkuil 	case V4L2_PIX_FMT_BGRA32:	descr = "32-bit ABGR 8-8-8-8"; break;
12594747bd0fSHans Verkuil 	case V4L2_PIX_FMT_BGRX32:	descr = "32-bit XBGR 8-8-8-8"; break;
12604747bd0fSHans Verkuil 	case V4L2_PIX_FMT_RGBA32:	descr = "32-bit RGBA 8-8-8-8"; break;
12614747bd0fSHans Verkuil 	case V4L2_PIX_FMT_RGBX32:	descr = "32-bit RGBX 8-8-8-8"; break;
1262ba300204SHans Verkuil 	case V4L2_PIX_FMT_GREY:		descr = "8-bit Greyscale"; break;
1263ba300204SHans Verkuil 	case V4L2_PIX_FMT_Y4:		descr = "4-bit Greyscale"; break;
1264ba300204SHans Verkuil 	case V4L2_PIX_FMT_Y6:		descr = "6-bit Greyscale"; break;
1265ba300204SHans Verkuil 	case V4L2_PIX_FMT_Y10:		descr = "10-bit Greyscale"; break;
1266ba300204SHans Verkuil 	case V4L2_PIX_FMT_Y12:		descr = "12-bit Greyscale"; break;
1267ae9753a0SDaniel Glöckner 	case V4L2_PIX_FMT_Y14:		descr = "14-bit Greyscale"; break;
1268ba300204SHans Verkuil 	case V4L2_PIX_FMT_Y16:		descr = "16-bit Greyscale"; break;
12692e5e435fSRicardo Ribalda 	case V4L2_PIX_FMT_Y16_BE:	descr = "16-bit Greyscale BE"; break;
1270ba300204SHans Verkuil 	case V4L2_PIX_FMT_Y10BPACK:	descr = "10-bit Greyscale (Packed)"; break;
12716e15bec4STodor Tomov 	case V4L2_PIX_FMT_Y10P:		descr = "10-bit Greyscale (MIPI Packed)"; break;
1272*b87f5e25SDaniel Scally 	case V4L2_PIX_FMT_IPU3_Y10:	descr = "10-bit greyscale (IPU3 Packed)"; break;
12735b382290SLaurent Pinchart 	case V4L2_PIX_FMT_Y8I:		descr = "Interleaved 8-bit Greyscale"; break;
12745b382290SLaurent Pinchart 	case V4L2_PIX_FMT_Y12I:		descr = "Interleaved 12-bit Greyscale"; break;
12755b382290SLaurent Pinchart 	case V4L2_PIX_FMT_Z16:		descr = "16-bit Depth"; break;
12765df082e2SEvgeni Raikhel 	case V4L2_PIX_FMT_INZI:		descr = "Planar 10:16 Greyscale Depth"; break;
127792799ef7SSergey Dorodnicov 	case V4L2_PIX_FMT_CNF4:		descr = "4-bit Depth Confidence (Packed)"; break;
1278ba300204SHans Verkuil 	case V4L2_PIX_FMT_PAL8:		descr = "8-bit Palette"; break;
1279ba300204SHans Verkuil 	case V4L2_PIX_FMT_UV8:		descr = "8-bit Chrominance UV 4-4"; break;
1280ba300204SHans Verkuil 	case V4L2_PIX_FMT_YVU410:	descr = "Planar YVU 4:1:0"; break;
1281ba300204SHans Verkuil 	case V4L2_PIX_FMT_YVU420:	descr = "Planar YVU 4:2:0"; break;
1282ba300204SHans Verkuil 	case V4L2_PIX_FMT_YUYV:		descr = "YUYV 4:2:2"; break;
1283ba300204SHans Verkuil 	case V4L2_PIX_FMT_YYUV:		descr = "YYUV 4:2:2"; break;
1284ba300204SHans Verkuil 	case V4L2_PIX_FMT_YVYU:		descr = "YVYU 4:2:2"; break;
1285ba300204SHans Verkuil 	case V4L2_PIX_FMT_UYVY:		descr = "UYVY 4:2:2"; break;
1286ba300204SHans Verkuil 	case V4L2_PIX_FMT_VYUY:		descr = "VYUY 4:2:2"; break;
1287fcbafafbSPhilipp Zabel 	case V4L2_PIX_FMT_YUV422P:	descr = "Planar YUV 4:2:2"; break;
1288ba300204SHans Verkuil 	case V4L2_PIX_FMT_YUV411P:	descr = "Planar YUV 4:1:1"; break;
1289ba300204SHans Verkuil 	case V4L2_PIX_FMT_Y41P:		descr = "YUV 4:1:1 (Packed)"; break;
1290ba300204SHans Verkuil 	case V4L2_PIX_FMT_YUV444:	descr = "16-bit A/XYUV 4-4-4-4"; break;
1291ba300204SHans Verkuil 	case V4L2_PIX_FMT_YUV555:	descr = "16-bit A/XYUV 1-5-5-5"; break;
1292ba300204SHans Verkuil 	case V4L2_PIX_FMT_YUV565:	descr = "16-bit YUV 5-6-5"; break;
12930376a51fSMirela Rabulea 	case V4L2_PIX_FMT_YUV24:	descr = "24-bit YUV 4:4:4 8-8-8"; break;
1294ba300204SHans Verkuil 	case V4L2_PIX_FMT_YUV32:	descr = "32-bit A/XYUV 8-8-8-8"; break;
1295a7fe4ca7SVivek Kasireddy 	case V4L2_PIX_FMT_AYUV32:	descr = "32-bit AYUV 8-8-8-8"; break;
1296a7fe4ca7SVivek Kasireddy 	case V4L2_PIX_FMT_XYUV32:	descr = "32-bit XYUV 8-8-8-8"; break;
1297a7fe4ca7SVivek Kasireddy 	case V4L2_PIX_FMT_VUYA32:	descr = "32-bit VUYA 8-8-8-8"; break;
1298a7fe4ca7SVivek Kasireddy 	case V4L2_PIX_FMT_VUYX32:	descr = "32-bit VUYX 8-8-8-8"; break;
1299ba300204SHans Verkuil 	case V4L2_PIX_FMT_YUV410:	descr = "Planar YUV 4:1:0"; break;
1300ba300204SHans Verkuil 	case V4L2_PIX_FMT_YUV420:	descr = "Planar YUV 4:2:0"; break;
1301ba300204SHans Verkuil 	case V4L2_PIX_FMT_HI240:	descr = "8-bit Dithered RGB (BTTV)"; break;
1302ba300204SHans Verkuil 	case V4L2_PIX_FMT_M420:		descr = "YUV 4:2:0 (M420)"; break;
1303ba300204SHans Verkuil 	case V4L2_PIX_FMT_NV12:		descr = "Y/CbCr 4:2:0"; break;
1304ba300204SHans Verkuil 	case V4L2_PIX_FMT_NV21:		descr = "Y/CrCb 4:2:0"; break;
1305ba300204SHans Verkuil 	case V4L2_PIX_FMT_NV16:		descr = "Y/CbCr 4:2:2"; break;
1306ba300204SHans Verkuil 	case V4L2_PIX_FMT_NV61:		descr = "Y/CrCb 4:2:2"; break;
1307ba300204SHans Verkuil 	case V4L2_PIX_FMT_NV24:		descr = "Y/CbCr 4:4:4"; break;
1308ba300204SHans Verkuil 	case V4L2_PIX_FMT_NV42:		descr = "Y/CrCb 4:4:4"; break;
1309683f71ebSEzequiel Garcia 	case V4L2_PIX_FMT_NV12_4L4:	descr = "Y/CbCr 4:2:0 (4x4 Linear)"; break;
131078eee7b5SEzequiel Garcia 	case V4L2_PIX_FMT_NV12_16L16:	descr = "Y/CbCr 4:2:0 (16x16 Linear)"; break;
1311b84f60a3SEzequiel Garcia 	case V4L2_PIX_FMT_NV12_32L32:   descr = "Y/CbCr 4:2:0 (32x32 Linear)"; break;
1312ba300204SHans Verkuil 	case V4L2_PIX_FMT_NV12M:	descr = "Y/CbCr 4:2:0 (N-C)"; break;
1313ba300204SHans Verkuil 	case V4L2_PIX_FMT_NV21M:	descr = "Y/CrCb 4:2:0 (N-C)"; break;
1314ba300204SHans Verkuil 	case V4L2_PIX_FMT_NV16M:	descr = "Y/CbCr 4:2:2 (N-C)"; break;
1315ba300204SHans Verkuil 	case V4L2_PIX_FMT_NV61M:	descr = "Y/CrCb 4:2:2 (N-C)"; break;
1316ba300204SHans Verkuil 	case V4L2_PIX_FMT_NV12MT:	descr = "Y/CbCr 4:2:0 (64x32 MB, N-C)"; break;
1317ba300204SHans Verkuil 	case V4L2_PIX_FMT_NV12MT_16X16:	descr = "Y/CbCr 4:2:0 (16x16 MB, N-C)"; break;
1318ba300204SHans Verkuil 	case V4L2_PIX_FMT_YUV420M:	descr = "Planar YUV 4:2:0 (N-C)"; break;
1319ba300204SHans Verkuil 	case V4L2_PIX_FMT_YVU420M:	descr = "Planar YVU 4:2:0 (N-C)"; break;
1320d65fae92SLaurent Pinchart 	case V4L2_PIX_FMT_YUV422M:	descr = "Planar YUV 4:2:2 (N-C)"; break;
1321d65fae92SLaurent Pinchart 	case V4L2_PIX_FMT_YVU422M:	descr = "Planar YVU 4:2:2 (N-C)"; break;
1322d65fae92SLaurent Pinchart 	case V4L2_PIX_FMT_YUV444M:	descr = "Planar YUV 4:4:4 (N-C)"; break;
1323d65fae92SLaurent Pinchart 	case V4L2_PIX_FMT_YVU444M:	descr = "Planar YVU 4:4:4 (N-C)"; break;
1324ba300204SHans Verkuil 	case V4L2_PIX_FMT_SBGGR8:	descr = "8-bit Bayer BGBG/GRGR"; break;
1325ba300204SHans Verkuil 	case V4L2_PIX_FMT_SGBRG8:	descr = "8-bit Bayer GBGB/RGRG"; break;
1326ba300204SHans Verkuil 	case V4L2_PIX_FMT_SGRBG8:	descr = "8-bit Bayer GRGR/BGBG"; break;
1327ba300204SHans Verkuil 	case V4L2_PIX_FMT_SRGGB8:	descr = "8-bit Bayer RGRG/GBGB"; break;
1328ba300204SHans Verkuil 	case V4L2_PIX_FMT_SBGGR10:	descr = "10-bit Bayer BGBG/GRGR"; break;
1329ba300204SHans Verkuil 	case V4L2_PIX_FMT_SGBRG10:	descr = "10-bit Bayer GBGB/RGRG"; break;
1330ba300204SHans Verkuil 	case V4L2_PIX_FMT_SGRBG10:	descr = "10-bit Bayer GRGR/BGBG"; break;
1331ba300204SHans Verkuil 	case V4L2_PIX_FMT_SRGGB10:	descr = "10-bit Bayer RGRG/GBGB"; break;
1332ba300204SHans Verkuil 	case V4L2_PIX_FMT_SBGGR10P:	descr = "10-bit Bayer BGBG/GRGR Packed"; break;
1333ba300204SHans Verkuil 	case V4L2_PIX_FMT_SGBRG10P:	descr = "10-bit Bayer GBGB/RGRG Packed"; break;
1334ba300204SHans Verkuil 	case V4L2_PIX_FMT_SGRBG10P:	descr = "10-bit Bayer GRGR/BGBG Packed"; break;
1335ba300204SHans Verkuil 	case V4L2_PIX_FMT_SRGGB10P:	descr = "10-bit Bayer RGRG/GBGB Packed"; break;
1336e8391b76SYong Zhi 	case V4L2_PIX_FMT_IPU3_SBGGR10: descr = "10-bit bayer BGGR IPU3 Packed"; break;
1337e8391b76SYong Zhi 	case V4L2_PIX_FMT_IPU3_SGBRG10: descr = "10-bit bayer GBRG IPU3 Packed"; break;
1338e8391b76SYong Zhi 	case V4L2_PIX_FMT_IPU3_SGRBG10: descr = "10-bit bayer GRBG IPU3 Packed"; break;
1339e8391b76SYong Zhi 	case V4L2_PIX_FMT_IPU3_SRGGB10: descr = "10-bit bayer RGGB IPU3 Packed"; break;
1340ba300204SHans Verkuil 	case V4L2_PIX_FMT_SBGGR10ALAW8:	descr = "8-bit Bayer BGBG/GRGR (A-law)"; break;
1341ba300204SHans Verkuil 	case V4L2_PIX_FMT_SGBRG10ALAW8:	descr = "8-bit Bayer GBGB/RGRG (A-law)"; break;
1342ba300204SHans Verkuil 	case V4L2_PIX_FMT_SGRBG10ALAW8:	descr = "8-bit Bayer GRGR/BGBG (A-law)"; break;
1343ba300204SHans Verkuil 	case V4L2_PIX_FMT_SRGGB10ALAW8:	descr = "8-bit Bayer RGRG/GBGB (A-law)"; break;
1344ba300204SHans Verkuil 	case V4L2_PIX_FMT_SBGGR10DPCM8:	descr = "8-bit Bayer BGBG/GRGR (DPCM)"; break;
1345ba300204SHans Verkuil 	case V4L2_PIX_FMT_SGBRG10DPCM8:	descr = "8-bit Bayer GBGB/RGRG (DPCM)"; break;
1346ba300204SHans Verkuil 	case V4L2_PIX_FMT_SGRBG10DPCM8:	descr = "8-bit Bayer GRGR/BGBG (DPCM)"; break;
1347ba300204SHans Verkuil 	case V4L2_PIX_FMT_SRGGB10DPCM8:	descr = "8-bit Bayer RGRG/GBGB (DPCM)"; break;
1348d1b3437eSSakari Ailus 	case V4L2_PIX_FMT_SBGGR12:	descr = "12-bit Bayer BGBG/GRGR"; break;
1349d1b3437eSSakari Ailus 	case V4L2_PIX_FMT_SGBRG12:	descr = "12-bit Bayer GBGB/RGRG"; break;
1350d1b3437eSSakari Ailus 	case V4L2_PIX_FMT_SGRBG12:	descr = "12-bit Bayer GRGR/BGBG"; break;
1351d1b3437eSSakari Ailus 	case V4L2_PIX_FMT_SRGGB12:	descr = "12-bit Bayer RGRG/GBGB"; break;
1352d1b3437eSSakari Ailus 	case V4L2_PIX_FMT_SBGGR12P:	descr = "12-bit Bayer BGBG/GRGR Packed"; break;
1353d1b3437eSSakari Ailus 	case V4L2_PIX_FMT_SGBRG12P:	descr = "12-bit Bayer GBGB/RGRG Packed"; break;
1354d1b3437eSSakari Ailus 	case V4L2_PIX_FMT_SGRBG12P:	descr = "12-bit Bayer GRGR/BGBG Packed"; break;
1355d1b3437eSSakari Ailus 	case V4L2_PIX_FMT_SRGGB12P:	descr = "12-bit Bayer RGRG/GBGB Packed"; break;
1356d12127edSSakari Ailus 	case V4L2_PIX_FMT_SBGGR14:	descr = "14-bit Bayer BGBG/GRGR"; break;
1357d12127edSSakari Ailus 	case V4L2_PIX_FMT_SGBRG14:	descr = "14-bit Bayer GBGB/RGRG"; break;
1358d12127edSSakari Ailus 	case V4L2_PIX_FMT_SGRBG14:	descr = "14-bit Bayer GRGR/BGBG"; break;
1359d12127edSSakari Ailus 	case V4L2_PIX_FMT_SRGGB14:	descr = "14-bit Bayer RGRG/GBGB"; break;
136083b15832SSakari Ailus 	case V4L2_PIX_FMT_SBGGR14P:	descr = "14-bit Bayer BGBG/GRGR Packed"; break;
136183b15832SSakari Ailus 	case V4L2_PIX_FMT_SGBRG14P:	descr = "14-bit Bayer GBGB/RGRG Packed"; break;
136283b15832SSakari Ailus 	case V4L2_PIX_FMT_SGRBG14P:	descr = "14-bit Bayer GRGR/BGBG Packed"; break;
136383b15832SSakari Ailus 	case V4L2_PIX_FMT_SRGGB14P:	descr = "14-bit Bayer RGRG/GBGB Packed"; break;
1364b9a4b13cSSakari Ailus 	case V4L2_PIX_FMT_SBGGR16:	descr = "16-bit Bayer BGBG/GRGR"; break;
1365b9a4b13cSSakari Ailus 	case V4L2_PIX_FMT_SGBRG16:	descr = "16-bit Bayer GBGB/RGRG"; break;
1366b9a4b13cSSakari Ailus 	case V4L2_PIX_FMT_SGRBG16:	descr = "16-bit Bayer GRGR/BGBG"; break;
1367b9a4b13cSSakari Ailus 	case V4L2_PIX_FMT_SRGGB16:	descr = "16-bit Bayer RGRG/GBGB"; break;
136899b74277SMauro Carvalho Chehab 	case V4L2_PIX_FMT_SN9C20X_I420:	descr = "GSPCA SN9C20X I420"; break;
1369ba300204SHans Verkuil 	case V4L2_PIX_FMT_SPCA501:	descr = "GSPCA SPCA501"; break;
1370ba300204SHans Verkuil 	case V4L2_PIX_FMT_SPCA505:	descr = "GSPCA SPCA505"; break;
1371ba300204SHans Verkuil 	case V4L2_PIX_FMT_SPCA508:	descr = "GSPCA SPCA508"; break;
1372ba300204SHans Verkuil 	case V4L2_PIX_FMT_STV0680:	descr = "GSPCA STV0680"; break;
1373ba300204SHans Verkuil 	case V4L2_PIX_FMT_TM6000:	descr = "A/V + VBI Mux Packet"; break;
1374ba300204SHans Verkuil 	case V4L2_PIX_FMT_CIT_YYVYUY:	descr = "GSPCA CIT YYVYUY"; break;
1375ba300204SHans Verkuil 	case V4L2_PIX_FMT_KONICA420:	descr = "GSPCA KONICA420"; break;
1376ffe5350cSAlexandre Courbot 	case V4L2_PIX_FMT_MM21:		descr = "Mediatek 8-bit Block Format"; break;
137766b2ab27SRicardo Ribalda Delgado 	case V4L2_PIX_FMT_HSV24:	descr = "24-bit HSV 8-8-8"; break;
137866b2ab27SRicardo Ribalda Delgado 	case V4L2_PIX_FMT_HSV32:	descr = "32-bit XHSV 8-8-8-8"; break;
137948fc10aaSAntti Palosaari 	case V4L2_SDR_FMT_CU8:		descr = "Complex U8"; break;
138048fc10aaSAntti Palosaari 	case V4L2_SDR_FMT_CU16LE:	descr = "Complex U16LE"; break;
1381ba300204SHans Verkuil 	case V4L2_SDR_FMT_CS8:		descr = "Complex S8"; break;
1382ba300204SHans Verkuil 	case V4L2_SDR_FMT_CS14LE:	descr = "Complex S14LE"; break;
1383ba300204SHans Verkuil 	case V4L2_SDR_FMT_RU12LE:	descr = "Real U12LE"; break;
1384c28f2118SRamesh Shanmugasundaram 	case V4L2_SDR_FMT_PCU16BE:	descr = "Planar Complex U16BE"; break;
1385c28f2118SRamesh Shanmugasundaram 	case V4L2_SDR_FMT_PCU18BE:	descr = "Planar Complex U18BE"; break;
1386c28f2118SRamesh Shanmugasundaram 	case V4L2_SDR_FMT_PCU20BE:	descr = "Planar Complex U20BE"; break;
13874747bd0fSHans Verkuil 	case V4L2_TCH_FMT_DELTA_TD16:	descr = "16-bit Signed Deltas"; break;
13884747bd0fSHans Verkuil 	case V4L2_TCH_FMT_DELTA_TD08:	descr = "8-bit Signed Deltas"; break;
13894747bd0fSHans Verkuil 	case V4L2_TCH_FMT_TU16:		descr = "16-bit Unsigned Touch Data"; break;
13904747bd0fSHans Verkuil 	case V4L2_TCH_FMT_TU08:		descr = "8-bit Unsigned Touch Data"; break;
139114d66538SLaurent Pinchart 	case V4L2_META_FMT_VSP1_HGO:	descr = "R-Car VSP1 1-D Histogram"; break;
13925deb1c04SNiklas Söderlund 	case V4L2_META_FMT_VSP1_HGT:	descr = "R-Car VSP1 2-D Histogram"; break;
13934747bd0fSHans Verkuil 	case V4L2_META_FMT_UVC:		descr = "UVC Payload Header Metadata"; break;
13944747bd0fSHans Verkuil 	case V4L2_META_FMT_D4XX:	descr = "Intel D4xx UVC Metadata"; break;
139578892b6bSVandana BN 	case V4L2_META_FMT_VIVID:       descr = "Vivid Metadata"; break;
1396df22026aSShunqian Zheng 	case V4L2_META_FMT_RK_ISP1_PARAMS:	descr = "Rockchip ISP1 3A Parameters"; break;
1397df22026aSShunqian Zheng 	case V4L2_META_FMT_RK_ISP1_STAT_3A:	descr = "Rockchip ISP1 3A Statistics"; break;
139872a74c8fSMing Qian 	case V4L2_PIX_FMT_NV12M_8L128:	descr = "NV12M (8x128 Linear)"; break;
139972a74c8fSMing Qian 	case V4L2_PIX_FMT_NV12M_10BE_8L128:	descr = "10-bit NV12M (8x128 Linear, BE)"; break;
1400ba300204SHans Verkuil 
1401ba300204SHans Verkuil 	default:
1402ba300204SHans Verkuil 		/* Compressed formats */
1403ba300204SHans Verkuil 		flags = V4L2_FMT_FLAG_COMPRESSED;
1404ba300204SHans Verkuil 		switch (fmt->pixelformat) {
1405ba300204SHans Verkuil 		/* Max description length mask:	descr = "0123456789012345678901234567890" */
1406ba300204SHans Verkuil 		case V4L2_PIX_FMT_MJPEG:	descr = "Motion-JPEG"; break;
1407ba300204SHans Verkuil 		case V4L2_PIX_FMT_JPEG:		descr = "JFIF JPEG"; break;
1408ba300204SHans Verkuil 		case V4L2_PIX_FMT_DV:		descr = "1394"; break;
1409ba300204SHans Verkuil 		case V4L2_PIX_FMT_MPEG:		descr = "MPEG-1/2/4"; break;
1410ba300204SHans Verkuil 		case V4L2_PIX_FMT_H264:		descr = "H.264"; break;
1411ba300204SHans Verkuil 		case V4L2_PIX_FMT_H264_NO_SC:	descr = "H.264 (No Start Codes)"; break;
1412ba300204SHans Verkuil 		case V4L2_PIX_FMT_H264_MVC:	descr = "H.264 MVC"; break;
14137bb3c32aSEzequiel Garcia 		case V4L2_PIX_FMT_H264_SLICE:	descr = "H.264 Parsed Slice Data"; break;
1414ba300204SHans Verkuil 		case V4L2_PIX_FMT_H263:		descr = "H.263"; break;
1415ba300204SHans Verkuil 		case V4L2_PIX_FMT_MPEG1:	descr = "MPEG-1 ES"; break;
1416ba300204SHans Verkuil 		case V4L2_PIX_FMT_MPEG2:	descr = "MPEG-2 ES"; break;
1417c27bb30eSPaul Kocialkowski 		case V4L2_PIX_FMT_MPEG2_SLICE:	descr = "MPEG-2 Parsed Slice Data"; break;
14184747bd0fSHans Verkuil 		case V4L2_PIX_FMT_MPEG4:	descr = "MPEG-4 Part 2 ES"; break;
1419ba300204SHans Verkuil 		case V4L2_PIX_FMT_XVID:		descr = "Xvid"; break;
1420ba300204SHans Verkuil 		case V4L2_PIX_FMT_VC1_ANNEX_G:	descr = "VC-1 (SMPTE 412M Annex G)"; break;
1421ba300204SHans Verkuil 		case V4L2_PIX_FMT_VC1_ANNEX_L:	descr = "VC-1 (SMPTE 412M Annex L)"; break;
1422ba300204SHans Verkuil 		case V4L2_PIX_FMT_VP8:		descr = "VP8"; break;
1423a57d6acaSPawel Osciak 		case V4L2_PIX_FMT_VP8_FRAME:    descr = "VP8 Frame"; break;
1424fa14a564SWu-Cheng Li 		case V4L2_PIX_FMT_VP9:		descr = "VP9"; break;
1425b88dbe38SAndrzej Pietrasiewicz 		case V4L2_PIX_FMT_VP9_FRAME:    descr = "VP9 Frame"; break;
14261c791727SSmitha T Murthy 		case V4L2_PIX_FMT_HEVC:		descr = "HEVC"; break; /* aka H.265 */
1427256fa392SPaul Kocialkowski 		case V4L2_PIX_FMT_HEVC_SLICE:	descr = "HEVC Parsed Slice Data"; break;
142862c3fce0SHans Verkuil 		case V4L2_PIX_FMT_FWHT:		descr = "FWHT"; break; /* used in vicodec */
1429f05a51b9SHans Verkuil 		case V4L2_PIX_FMT_FWHT_STATELESS:	descr = "FWHT Stateless"; break; /* used in vicodec */
1430ba300204SHans Verkuil 		case V4L2_PIX_FMT_CPIA1:	descr = "GSPCA CPiA YUV"; break;
1431ba300204SHans Verkuil 		case V4L2_PIX_FMT_WNVA:		descr = "WNVA"; break;
1432ba300204SHans Verkuil 		case V4L2_PIX_FMT_SN9C10X:	descr = "GSPCA SN9C10X"; break;
1433ba300204SHans Verkuil 		case V4L2_PIX_FMT_PWC1:		descr = "Raw Philips Webcam Type (Old)"; break;
1434ba300204SHans Verkuil 		case V4L2_PIX_FMT_PWC2:		descr = "Raw Philips Webcam Type (New)"; break;
1435ba300204SHans Verkuil 		case V4L2_PIX_FMT_ET61X251:	descr = "GSPCA ET61X251"; break;
1436ba300204SHans Verkuil 		case V4L2_PIX_FMT_SPCA561:	descr = "GSPCA SPCA561"; break;
1437ba300204SHans Verkuil 		case V4L2_PIX_FMT_PAC207:	descr = "GSPCA PAC207"; break;
1438ba300204SHans Verkuil 		case V4L2_PIX_FMT_MR97310A:	descr = "GSPCA MR97310A"; break;
1439ba300204SHans Verkuil 		case V4L2_PIX_FMT_JL2005BCD:	descr = "GSPCA JL2005BCD"; break;
1440ba300204SHans Verkuil 		case V4L2_PIX_FMT_SN9C2028:	descr = "GSPCA SN9C2028"; break;
1441ba300204SHans Verkuil 		case V4L2_PIX_FMT_SQ905C:	descr = "GSPCA SQ905C"; break;
1442ba300204SHans Verkuil 		case V4L2_PIX_FMT_PJPG:		descr = "GSPCA PJPG"; break;
1443ba300204SHans Verkuil 		case V4L2_PIX_FMT_OV511:	descr = "GSPCA OV511"; break;
1444ba300204SHans Verkuil 		case V4L2_PIX_FMT_OV518:	descr = "GSPCA OV518"; break;
1445ba300204SHans Verkuil 		case V4L2_PIX_FMT_JPGL:		descr = "JPEG Lite"; break;
1446ba300204SHans Verkuil 		case V4L2_PIX_FMT_SE401:	descr = "GSPCA SE401"; break;
1447ba300204SHans Verkuil 		case V4L2_PIX_FMT_S5C_UYVY_JPG:	descr = "S5C73MX interleaved UYVY/JPEG"; break;
1448d4de6634STiffany Lin 		case V4L2_PIX_FMT_MT21C:	descr = "Mediatek Compressed Format"; break;
14492308d5afSStanimir Varbanov 		case V4L2_PIX_FMT_QC08C:	descr = "QCOM Compressed 8-bit Format"; break;
14502308d5afSStanimir Varbanov 		case V4L2_PIX_FMT_QC10C:	descr = "QCOM Compressed 10-bit Format"; break;
1451ba300204SHans Verkuil 		default:
1452ba300204SHans Verkuil 			if (fmt->description[0])
1453ba300204SHans Verkuil 				return;
1454c2286cc0SSakari Ailus 			WARN(1, "Unknown pixelformat 0x%08x\n", fmt->pixelformat);
1455ba300204SHans Verkuil 			flags = 0;
1456e927e1e0SSakari Ailus 			snprintf(fmt->description, sz, "%p4cc",
1457e927e1e0SSakari Ailus 				 &fmt->pixelformat);
1458ba300204SHans Verkuil 			break;
1459ba300204SHans Verkuil 		}
1460ba300204SHans Verkuil 	}
1461ba300204SHans Verkuil 
1462ba300204SHans Verkuil 	if (descr)
1463e7dd89ceSHans Petter Selasky 		WARN_ON(strscpy(fmt->description, descr, sz) < 0);
14647c490e25SHans Verkuil 	fmt->flags |= flags;
1465ba300204SHans Verkuil }
1466ba300204SHans Verkuil 
14675bc3cb74SMauro Carvalho Chehab static int v4l_enum_fmt(const struct v4l2_ioctl_ops *ops,
14685bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
14695bc3cb74SMauro Carvalho Chehab {
14707e98b7b5SBoris Brezillon 	struct video_device *vdev = video_devdata(file);
14715bc3cb74SMauro Carvalho Chehab 	struct v4l2_fmtdesc *p = arg;
1472b2469c81SHans Verkuil 	int ret = check_fmt(file, p->type);
1473e5b6b07aSLaurent Pinchart 	u32 mbus_code;
1474f0d2b7a8SBoris Brezillon 	u32 cap_mask;
1475b2469c81SHans Verkuil 
1476b2469c81SHans Verkuil 	if (ret)
1477b2469c81SHans Verkuil 		return ret;
1478b2469c81SHans Verkuil 	ret = -EINVAL;
14795bc3cb74SMauro Carvalho Chehab 
1480e5b6b07aSLaurent Pinchart 	if (!(vdev->device_caps & V4L2_CAP_IO_MC))
1481e5b6b07aSLaurent Pinchart 		p->mbus_code = 0;
1482e5b6b07aSLaurent Pinchart 
1483e5b6b07aSLaurent Pinchart 	mbus_code = p->mbus_code;
1484e5b6b07aSLaurent Pinchart 	CLEAR_AFTER_FIELD(p, type);
1485e5b6b07aSLaurent Pinchart 	p->mbus_code = mbus_code;
1486e5b6b07aSLaurent Pinchart 
14875bc3cb74SMauro Carvalho Chehab 	switch (p->type) {
14885bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_CAPTURE:
14897e98b7b5SBoris Brezillon 	case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
1490f0d2b7a8SBoris Brezillon 		cap_mask = V4L2_CAP_VIDEO_CAPTURE_MPLANE |
1491f0d2b7a8SBoris Brezillon 			   V4L2_CAP_VIDEO_M2M_MPLANE;
1492f0d2b7a8SBoris Brezillon 		if (!!(vdev->device_caps & cap_mask) !=
14937e98b7b5SBoris Brezillon 		    (p->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE))
14947e98b7b5SBoris Brezillon 			break;
14957e98b7b5SBoris Brezillon 
1496b2469c81SHans Verkuil 		if (unlikely(!ops->vidioc_enum_fmt_vid_cap))
14975bc3cb74SMauro Carvalho Chehab 			break;
1498ba300204SHans Verkuil 		ret = ops->vidioc_enum_fmt_vid_cap(file, fh, arg);
1499ba300204SHans Verkuil 		break;
15005bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_OVERLAY:
1501b2469c81SHans Verkuil 		if (unlikely(!ops->vidioc_enum_fmt_vid_overlay))
15025bc3cb74SMauro Carvalho Chehab 			break;
1503ba300204SHans Verkuil 		ret = ops->vidioc_enum_fmt_vid_overlay(file, fh, arg);
1504ba300204SHans Verkuil 		break;
15055bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_OUTPUT:
15067e98b7b5SBoris Brezillon 	case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
1507f0d2b7a8SBoris Brezillon 		cap_mask = V4L2_CAP_VIDEO_OUTPUT_MPLANE |
1508f0d2b7a8SBoris Brezillon 			   V4L2_CAP_VIDEO_M2M_MPLANE;
1509f0d2b7a8SBoris Brezillon 		if (!!(vdev->device_caps & cap_mask) !=
15107e98b7b5SBoris Brezillon 		    (p->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE))
15117e98b7b5SBoris Brezillon 			break;
15127e98b7b5SBoris Brezillon 
1513b2469c81SHans Verkuil 		if (unlikely(!ops->vidioc_enum_fmt_vid_out))
15145bc3cb74SMauro Carvalho Chehab 			break;
1515ba300204SHans Verkuil 		ret = ops->vidioc_enum_fmt_vid_out(file, fh, arg);
1516ba300204SHans Verkuil 		break;
1517582c52cbSAntti Palosaari 	case V4L2_BUF_TYPE_SDR_CAPTURE:
1518b2469c81SHans Verkuil 		if (unlikely(!ops->vidioc_enum_fmt_sdr_cap))
1519582c52cbSAntti Palosaari 			break;
1520ba300204SHans Verkuil 		ret = ops->vidioc_enum_fmt_sdr_cap(file, fh, arg);
1521ba300204SHans Verkuil 		break;
15229effc72fSAntti Palosaari 	case V4L2_BUF_TYPE_SDR_OUTPUT:
1523b2469c81SHans Verkuil 		if (unlikely(!ops->vidioc_enum_fmt_sdr_out))
15249effc72fSAntti Palosaari 			break;
15259effc72fSAntti Palosaari 		ret = ops->vidioc_enum_fmt_sdr_out(file, fh, arg);
15269effc72fSAntti Palosaari 		break;
1527fb9ffa6aSLaurent Pinchart 	case V4L2_BUF_TYPE_META_CAPTURE:
1528b2469c81SHans Verkuil 		if (unlikely(!ops->vidioc_enum_fmt_meta_cap))
1529fb9ffa6aSLaurent Pinchart 			break;
1530fb9ffa6aSLaurent Pinchart 		ret = ops->vidioc_enum_fmt_meta_cap(file, fh, arg);
1531fb9ffa6aSLaurent Pinchart 		break;
153272148d1aSSakari Ailus 	case V4L2_BUF_TYPE_META_OUTPUT:
153372148d1aSSakari Ailus 		if (unlikely(!ops->vidioc_enum_fmt_meta_out))
153472148d1aSSakari Ailus 			break;
153572148d1aSSakari Ailus 		ret = ops->vidioc_enum_fmt_meta_out(file, fh, arg);
153672148d1aSSakari Ailus 		break;
15375bc3cb74SMauro Carvalho Chehab 	}
1538ba300204SHans Verkuil 	if (ret == 0)
1539ba300204SHans Verkuil 		v4l_fill_fmtdesc(p);
1540ba300204SHans Verkuil 	return ret;
15415bc3cb74SMauro Carvalho Chehab }
15425bc3cb74SMauro Carvalho Chehab 
1543545b618cSVandana BN static void v4l_pix_format_touch(struct v4l2_pix_format *p)
1544545b618cSVandana BN {
1545545b618cSVandana BN 	/*
1546545b618cSVandana BN 	 * The v4l2_pix_format structure contains fields that make no sense for
1547545b618cSVandana BN 	 * touch. Set them to default values in this case.
1548545b618cSVandana BN 	 */
1549545b618cSVandana BN 
1550545b618cSVandana BN 	p->field = V4L2_FIELD_NONE;
1551545b618cSVandana BN 	p->colorspace = V4L2_COLORSPACE_RAW;
1552545b618cSVandana BN 	p->flags = 0;
1553545b618cSVandana BN 	p->ycbcr_enc = 0;
1554545b618cSVandana BN 	p->quantization = 0;
1555545b618cSVandana BN 	p->xfer_func = 0;
1556545b618cSVandana BN }
1557545b618cSVandana BN 
15585bc3cb74SMauro Carvalho Chehab static int v4l_g_fmt(const struct v4l2_ioctl_ops *ops,
15595bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
15605bc3cb74SMauro Carvalho Chehab {
15615bc3cb74SMauro Carvalho Chehab 	struct v4l2_format *p = arg;
1562545b618cSVandana BN 	struct video_device *vfd = video_devdata(file);
1563b2469c81SHans Verkuil 	int ret = check_fmt(file, p->type);
1564b2469c81SHans Verkuil 
1565b2469c81SHans Verkuil 	if (ret)
1566b2469c81SHans Verkuil 		return ret;
1567d52e2381SLaurent Pinchart 
1568e5ce558aSHans Verkuil 	/*
1569e5ce558aSHans Verkuil 	 * fmt can't be cleared for these overlay types due to the 'clips'
1570e5ce558aSHans Verkuil 	 * 'clipcount' and 'bitmap' pointers in struct v4l2_window.
1571e5ce558aSHans Verkuil 	 * Those are provided by the user. So handle these two overlay types
1572e5ce558aSHans Verkuil 	 * first, and then just do a simple memset for the other types.
1573e5ce558aSHans Verkuil 	 */
1574e5ce558aSHans Verkuil 	switch (p->type) {
1575e5ce558aSHans Verkuil 	case V4L2_BUF_TYPE_VIDEO_OVERLAY:
1576e5ce558aSHans Verkuil 	case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY: {
15773f65c6f6SArnd Bergmann 		struct v4l2_clip *clips = p->fmt.win.clips;
1578e5ce558aSHans Verkuil 		u32 clipcount = p->fmt.win.clipcount;
15794d1afa51SHans Verkuil 		void __user *bitmap = p->fmt.win.bitmap;
1580e5ce558aSHans Verkuil 
1581e5ce558aSHans Verkuil 		memset(&p->fmt, 0, sizeof(p->fmt));
1582e5ce558aSHans Verkuil 		p->fmt.win.clips = clips;
1583e5ce558aSHans Verkuil 		p->fmt.win.clipcount = clipcount;
1584e5ce558aSHans Verkuil 		p->fmt.win.bitmap = bitmap;
1585e5ce558aSHans Verkuil 		break;
1586e5ce558aSHans Verkuil 	}
1587e5ce558aSHans Verkuil 	default:
1588e5ce558aSHans Verkuil 		memset(&p->fmt, 0, sizeof(p->fmt));
1589e5ce558aSHans Verkuil 		break;
1590e5ce558aSHans Verkuil 	}
1591e5ce558aSHans Verkuil 
15925bc3cb74SMauro Carvalho Chehab 	switch (p->type) {
15935bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_CAPTURE:
1594b2469c81SHans Verkuil 		if (unlikely(!ops->vidioc_g_fmt_vid_cap))
15955bc3cb74SMauro Carvalho Chehab 			break;
159648f2650aSHans Verkuil 		p->fmt.pix.priv = V4L2_PIX_FMT_PRIV_MAGIC;
1597d52e2381SLaurent Pinchart 		ret = ops->vidioc_g_fmt_vid_cap(file, fh, arg);
159848f2650aSHans Verkuil 		/* just in case the driver zeroed it again */
1599d52e2381SLaurent Pinchart 		p->fmt.pix.priv = V4L2_PIX_FMT_PRIV_MAGIC;
1600545b618cSVandana BN 		if (vfd->vfl_type == VFL_TYPE_TOUCH)
1601545b618cSVandana BN 			v4l_pix_format_touch(&p->fmt.pix);
1602d52e2381SLaurent Pinchart 		return ret;
16035bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
16045bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_g_fmt_vid_cap_mplane(file, fh, arg);
16055bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_OVERLAY:
16065bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_g_fmt_vid_overlay(file, fh, arg);
16074b20259fSHans Verkuil 	case V4L2_BUF_TYPE_VBI_CAPTURE:
16084b20259fSHans Verkuil 		return ops->vidioc_g_fmt_vbi_cap(file, fh, arg);
16094b20259fSHans Verkuil 	case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
16104b20259fSHans Verkuil 		return ops->vidioc_g_fmt_sliced_vbi_cap(file, fh, arg);
16115bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_OUTPUT:
1612b2469c81SHans Verkuil 		if (unlikely(!ops->vidioc_g_fmt_vid_out))
16135bc3cb74SMauro Carvalho Chehab 			break;
161448f2650aSHans Verkuil 		p->fmt.pix.priv = V4L2_PIX_FMT_PRIV_MAGIC;
1615d52e2381SLaurent Pinchart 		ret = ops->vidioc_g_fmt_vid_out(file, fh, arg);
161648f2650aSHans Verkuil 		/* just in case the driver zeroed it again */
1617d52e2381SLaurent Pinchart 		p->fmt.pix.priv = V4L2_PIX_FMT_PRIV_MAGIC;
1618d52e2381SLaurent Pinchart 		return ret;
16195bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
16205bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_g_fmt_vid_out_mplane(file, fh, arg);
16215bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
16225bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_g_fmt_vid_out_overlay(file, fh, arg);
16235bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VBI_OUTPUT:
16245bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_g_fmt_vbi_out(file, fh, arg);
16255bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
16265bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_g_fmt_sliced_vbi_out(file, fh, arg);
1627582c52cbSAntti Palosaari 	case V4L2_BUF_TYPE_SDR_CAPTURE:
1628582c52cbSAntti Palosaari 		return ops->vidioc_g_fmt_sdr_cap(file, fh, arg);
16299effc72fSAntti Palosaari 	case V4L2_BUF_TYPE_SDR_OUTPUT:
16309effc72fSAntti Palosaari 		return ops->vidioc_g_fmt_sdr_out(file, fh, arg);
1631fb9ffa6aSLaurent Pinchart 	case V4L2_BUF_TYPE_META_CAPTURE:
1632fb9ffa6aSLaurent Pinchart 		return ops->vidioc_g_fmt_meta_cap(file, fh, arg);
163372148d1aSSakari Ailus 	case V4L2_BUF_TYPE_META_OUTPUT:
163472148d1aSSakari Ailus 		return ops->vidioc_g_fmt_meta_out(file, fh, arg);
16355bc3cb74SMauro Carvalho Chehab 	}
16365bc3cb74SMauro Carvalho Chehab 	return -EINVAL;
16375bc3cb74SMauro Carvalho Chehab }
16385bc3cb74SMauro Carvalho Chehab 
16395bc3cb74SMauro Carvalho Chehab static int v4l_s_fmt(const struct v4l2_ioctl_ops *ops,
16405bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
16415bc3cb74SMauro Carvalho Chehab {
16425bc3cb74SMauro Carvalho Chehab 	struct v4l2_format *p = arg;
16434b20259fSHans Verkuil 	struct video_device *vfd = video_devdata(file);
1644b2469c81SHans Verkuil 	int ret = check_fmt(file, p->type);
16454e1e0eb0SEzequiel Garcia 	unsigned int i;
1646b2469c81SHans Verkuil 
1647b2469c81SHans Verkuil 	if (ret)
1648b2469c81SHans Verkuil 		return ret;
16495bc3cb74SMauro Carvalho Chehab 
165077fa4e07SShuah Khan 	ret = v4l_enable_media_source(vfd);
165177fa4e07SShuah Khan 	if (ret)
165277fa4e07SShuah Khan 		return ret;
1653d52e2381SLaurent Pinchart 	v4l_sanitize_format(p);
1654d52e2381SLaurent Pinchart 
16555bc3cb74SMauro Carvalho Chehab 	switch (p->type) {
16565bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_CAPTURE:
1657b2469c81SHans Verkuil 		if (unlikely(!ops->vidioc_s_fmt_vid_cap))
16585bc3cb74SMauro Carvalho Chehab 			break;
16595bc3cb74SMauro Carvalho Chehab 		CLEAR_AFTER_FIELD(p, fmt.pix);
166048f2650aSHans Verkuil 		ret = ops->vidioc_s_fmt_vid_cap(file, fh, arg);
166148f2650aSHans Verkuil 		/* just in case the driver zeroed it again */
166248f2650aSHans Verkuil 		p->fmt.pix.priv = V4L2_PIX_FMT_PRIV_MAGIC;
1663b2469c81SHans Verkuil 		if (vfd->vfl_type == VFL_TYPE_TOUCH)
1664b2fe22d0SNick Dyer 			v4l_pix_format_touch(&p->fmt.pix);
166548f2650aSHans Verkuil 		return ret;
16665bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
1667b2469c81SHans Verkuil 		if (unlikely(!ops->vidioc_s_fmt_vid_cap_mplane))
16685bc3cb74SMauro Carvalho Chehab 			break;
1669c49148e8SLaurent Pinchart 		CLEAR_AFTER_FIELD(p, fmt.pix_mp.xfer_func);
16704e1e0eb0SEzequiel Garcia 		for (i = 0; i < p->fmt.pix_mp.num_planes; i++)
1671dd91642aSThierry Reding 			CLEAR_AFTER_FIELD(&p->fmt.pix_mp.plane_fmt[i],
1672dd91642aSThierry Reding 					  bytesperline);
16735bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_s_fmt_vid_cap_mplane(file, fh, arg);
16745bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_OVERLAY:
1675b2469c81SHans Verkuil 		if (unlikely(!ops->vidioc_s_fmt_vid_overlay))
16765bc3cb74SMauro Carvalho Chehab 			break;
16775bc3cb74SMauro Carvalho Chehab 		CLEAR_AFTER_FIELD(p, fmt.win);
16785bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_s_fmt_vid_overlay(file, fh, arg);
16794b20259fSHans Verkuil 	case V4L2_BUF_TYPE_VBI_CAPTURE:
1680b2469c81SHans Verkuil 		if (unlikely(!ops->vidioc_s_fmt_vbi_cap))
16814b20259fSHans Verkuil 			break;
1682ee8951e5SHans Verkuil 		CLEAR_AFTER_FIELD(p, fmt.vbi.flags);
16834b20259fSHans Verkuil 		return ops->vidioc_s_fmt_vbi_cap(file, fh, arg);
16844b20259fSHans Verkuil 	case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
1685b2469c81SHans Verkuil 		if (unlikely(!ops->vidioc_s_fmt_sliced_vbi_cap))
16864b20259fSHans Verkuil 			break;
1687ee8951e5SHans Verkuil 		CLEAR_AFTER_FIELD(p, fmt.sliced.io_size);
16884b20259fSHans Verkuil 		return ops->vidioc_s_fmt_sliced_vbi_cap(file, fh, arg);
16895bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_OUTPUT:
1690b2469c81SHans Verkuil 		if (unlikely(!ops->vidioc_s_fmt_vid_out))
16915bc3cb74SMauro Carvalho Chehab 			break;
16925bc3cb74SMauro Carvalho Chehab 		CLEAR_AFTER_FIELD(p, fmt.pix);
169348f2650aSHans Verkuil 		ret = ops->vidioc_s_fmt_vid_out(file, fh, arg);
169448f2650aSHans Verkuil 		/* just in case the driver zeroed it again */
169548f2650aSHans Verkuil 		p->fmt.pix.priv = V4L2_PIX_FMT_PRIV_MAGIC;
169648f2650aSHans Verkuil 		return ret;
16975bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
1698b2469c81SHans Verkuil 		if (unlikely(!ops->vidioc_s_fmt_vid_out_mplane))
16995bc3cb74SMauro Carvalho Chehab 			break;
1700c49148e8SLaurent Pinchart 		CLEAR_AFTER_FIELD(p, fmt.pix_mp.xfer_func);
17014e1e0eb0SEzequiel Garcia 		for (i = 0; i < p->fmt.pix_mp.num_planes; i++)
1702dd91642aSThierry Reding 			CLEAR_AFTER_FIELD(&p->fmt.pix_mp.plane_fmt[i],
1703dd91642aSThierry Reding 					  bytesperline);
17045bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_s_fmt_vid_out_mplane(file, fh, arg);
17055bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
1706b2469c81SHans Verkuil 		if (unlikely(!ops->vidioc_s_fmt_vid_out_overlay))
17075bc3cb74SMauro Carvalho Chehab 			break;
17085bc3cb74SMauro Carvalho Chehab 		CLEAR_AFTER_FIELD(p, fmt.win);
17095bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_s_fmt_vid_out_overlay(file, fh, arg);
17105bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VBI_OUTPUT:
1711b2469c81SHans Verkuil 		if (unlikely(!ops->vidioc_s_fmt_vbi_out))
17125bc3cb74SMauro Carvalho Chehab 			break;
1713ee8951e5SHans Verkuil 		CLEAR_AFTER_FIELD(p, fmt.vbi.flags);
17145bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_s_fmt_vbi_out(file, fh, arg);
17155bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
1716b2469c81SHans Verkuil 		if (unlikely(!ops->vidioc_s_fmt_sliced_vbi_out))
17175bc3cb74SMauro Carvalho Chehab 			break;
1718ee8951e5SHans Verkuil 		CLEAR_AFTER_FIELD(p, fmt.sliced.io_size);
17195bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_s_fmt_sliced_vbi_out(file, fh, arg);
1720582c52cbSAntti Palosaari 	case V4L2_BUF_TYPE_SDR_CAPTURE:
1721b2469c81SHans Verkuil 		if (unlikely(!ops->vidioc_s_fmt_sdr_cap))
1722582c52cbSAntti Palosaari 			break;
1723ee8951e5SHans Verkuil 		CLEAR_AFTER_FIELD(p, fmt.sdr.buffersize);
1724582c52cbSAntti Palosaari 		return ops->vidioc_s_fmt_sdr_cap(file, fh, arg);
17259effc72fSAntti Palosaari 	case V4L2_BUF_TYPE_SDR_OUTPUT:
1726b2469c81SHans Verkuil 		if (unlikely(!ops->vidioc_s_fmt_sdr_out))
17279effc72fSAntti Palosaari 			break;
1728ee8951e5SHans Verkuil 		CLEAR_AFTER_FIELD(p, fmt.sdr.buffersize);
17299effc72fSAntti Palosaari 		return ops->vidioc_s_fmt_sdr_out(file, fh, arg);
1730fb9ffa6aSLaurent Pinchart 	case V4L2_BUF_TYPE_META_CAPTURE:
1731b2469c81SHans Verkuil 		if (unlikely(!ops->vidioc_s_fmt_meta_cap))
1732fb9ffa6aSLaurent Pinchart 			break;
1733fb9ffa6aSLaurent Pinchart 		CLEAR_AFTER_FIELD(p, fmt.meta);
1734fb9ffa6aSLaurent Pinchart 		return ops->vidioc_s_fmt_meta_cap(file, fh, arg);
173572148d1aSSakari Ailus 	case V4L2_BUF_TYPE_META_OUTPUT:
173672148d1aSSakari Ailus 		if (unlikely(!ops->vidioc_s_fmt_meta_out))
173772148d1aSSakari Ailus 			break;
173872148d1aSSakari Ailus 		CLEAR_AFTER_FIELD(p, fmt.meta);
173972148d1aSSakari Ailus 		return ops->vidioc_s_fmt_meta_out(file, fh, arg);
17405bc3cb74SMauro Carvalho Chehab 	}
17415bc3cb74SMauro Carvalho Chehab 	return -EINVAL;
17425bc3cb74SMauro Carvalho Chehab }
17435bc3cb74SMauro Carvalho Chehab 
17445bc3cb74SMauro Carvalho Chehab static int v4l_try_fmt(const struct v4l2_ioctl_ops *ops,
17455bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
17465bc3cb74SMauro Carvalho Chehab {
17475bc3cb74SMauro Carvalho Chehab 	struct v4l2_format *p = arg;
1748999a4312SHans Verkuil 	struct video_device *vfd = video_devdata(file);
1749b2469c81SHans Verkuil 	int ret = check_fmt(file, p->type);
17504e1e0eb0SEzequiel Garcia 	unsigned int i;
1751b2469c81SHans Verkuil 
1752b2469c81SHans Verkuil 	if (ret)
1753b2469c81SHans Verkuil 		return ret;
17545bc3cb74SMauro Carvalho Chehab 
1755d52e2381SLaurent Pinchart 	v4l_sanitize_format(p);
1756d52e2381SLaurent Pinchart 
17575bc3cb74SMauro Carvalho Chehab 	switch (p->type) {
17585bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_CAPTURE:
1759b2469c81SHans Verkuil 		if (unlikely(!ops->vidioc_try_fmt_vid_cap))
17605bc3cb74SMauro Carvalho Chehab 			break;
17615bc3cb74SMauro Carvalho Chehab 		CLEAR_AFTER_FIELD(p, fmt.pix);
176248f2650aSHans Verkuil 		ret = ops->vidioc_try_fmt_vid_cap(file, fh, arg);
176348f2650aSHans Verkuil 		/* just in case the driver zeroed it again */
176448f2650aSHans Verkuil 		p->fmt.pix.priv = V4L2_PIX_FMT_PRIV_MAGIC;
1765999a4312SHans Verkuil 		if (vfd->vfl_type == VFL_TYPE_TOUCH)
1766999a4312SHans Verkuil 			v4l_pix_format_touch(&p->fmt.pix);
176748f2650aSHans Verkuil 		return ret;
17685bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
1769b2469c81SHans Verkuil 		if (unlikely(!ops->vidioc_try_fmt_vid_cap_mplane))
17705bc3cb74SMauro Carvalho Chehab 			break;
1771c49148e8SLaurent Pinchart 		CLEAR_AFTER_FIELD(p, fmt.pix_mp.xfer_func);
17724e1e0eb0SEzequiel Garcia 		for (i = 0; i < p->fmt.pix_mp.num_planes; i++)
1773dd91642aSThierry Reding 			CLEAR_AFTER_FIELD(&p->fmt.pix_mp.plane_fmt[i],
1774dd91642aSThierry Reding 					  bytesperline);
17755bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_try_fmt_vid_cap_mplane(file, fh, arg);
17765bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_OVERLAY:
1777b2469c81SHans Verkuil 		if (unlikely(!ops->vidioc_try_fmt_vid_overlay))
17785bc3cb74SMauro Carvalho Chehab 			break;
17795bc3cb74SMauro Carvalho Chehab 		CLEAR_AFTER_FIELD(p, fmt.win);
17805bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_try_fmt_vid_overlay(file, fh, arg);
17814b20259fSHans Verkuil 	case V4L2_BUF_TYPE_VBI_CAPTURE:
1782b2469c81SHans Verkuil 		if (unlikely(!ops->vidioc_try_fmt_vbi_cap))
17834b20259fSHans Verkuil 			break;
1784ee8951e5SHans Verkuil 		CLEAR_AFTER_FIELD(p, fmt.vbi.flags);
17854b20259fSHans Verkuil 		return ops->vidioc_try_fmt_vbi_cap(file, fh, arg);
17864b20259fSHans Verkuil 	case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
1787b2469c81SHans Verkuil 		if (unlikely(!ops->vidioc_try_fmt_sliced_vbi_cap))
17884b20259fSHans Verkuil 			break;
1789ee8951e5SHans Verkuil 		CLEAR_AFTER_FIELD(p, fmt.sliced.io_size);
17904b20259fSHans Verkuil 		return ops->vidioc_try_fmt_sliced_vbi_cap(file, fh, arg);
17915bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_OUTPUT:
1792b2469c81SHans Verkuil 		if (unlikely(!ops->vidioc_try_fmt_vid_out))
17935bc3cb74SMauro Carvalho Chehab 			break;
17945bc3cb74SMauro Carvalho Chehab 		CLEAR_AFTER_FIELD(p, fmt.pix);
179548f2650aSHans Verkuil 		ret = ops->vidioc_try_fmt_vid_out(file, fh, arg);
179648f2650aSHans Verkuil 		/* just in case the driver zeroed it again */
179748f2650aSHans Verkuil 		p->fmt.pix.priv = V4L2_PIX_FMT_PRIV_MAGIC;
179848f2650aSHans Verkuil 		return ret;
17995bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
1800b2469c81SHans Verkuil 		if (unlikely(!ops->vidioc_try_fmt_vid_out_mplane))
18015bc3cb74SMauro Carvalho Chehab 			break;
1802c49148e8SLaurent Pinchart 		CLEAR_AFTER_FIELD(p, fmt.pix_mp.xfer_func);
18034e1e0eb0SEzequiel Garcia 		for (i = 0; i < p->fmt.pix_mp.num_planes; i++)
1804dd91642aSThierry Reding 			CLEAR_AFTER_FIELD(&p->fmt.pix_mp.plane_fmt[i],
1805dd91642aSThierry Reding 					  bytesperline);
18065bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_try_fmt_vid_out_mplane(file, fh, arg);
18075bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
1808b2469c81SHans Verkuil 		if (unlikely(!ops->vidioc_try_fmt_vid_out_overlay))
18095bc3cb74SMauro Carvalho Chehab 			break;
18105bc3cb74SMauro Carvalho Chehab 		CLEAR_AFTER_FIELD(p, fmt.win);
18115bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_try_fmt_vid_out_overlay(file, fh, arg);
18125bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VBI_OUTPUT:
1813b2469c81SHans Verkuil 		if (unlikely(!ops->vidioc_try_fmt_vbi_out))
18145bc3cb74SMauro Carvalho Chehab 			break;
1815ee8951e5SHans Verkuil 		CLEAR_AFTER_FIELD(p, fmt.vbi.flags);
18165bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_try_fmt_vbi_out(file, fh, arg);
18175bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
1818b2469c81SHans Verkuil 		if (unlikely(!ops->vidioc_try_fmt_sliced_vbi_out))
18195bc3cb74SMauro Carvalho Chehab 			break;
1820ee8951e5SHans Verkuil 		CLEAR_AFTER_FIELD(p, fmt.sliced.io_size);
18215bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_try_fmt_sliced_vbi_out(file, fh, arg);
1822582c52cbSAntti Palosaari 	case V4L2_BUF_TYPE_SDR_CAPTURE:
1823b2469c81SHans Verkuil 		if (unlikely(!ops->vidioc_try_fmt_sdr_cap))
1824582c52cbSAntti Palosaari 			break;
1825ee8951e5SHans Verkuil 		CLEAR_AFTER_FIELD(p, fmt.sdr.buffersize);
1826582c52cbSAntti Palosaari 		return ops->vidioc_try_fmt_sdr_cap(file, fh, arg);
18279effc72fSAntti Palosaari 	case V4L2_BUF_TYPE_SDR_OUTPUT:
1828b2469c81SHans Verkuil 		if (unlikely(!ops->vidioc_try_fmt_sdr_out))
18299effc72fSAntti Palosaari 			break;
1830ee8951e5SHans Verkuil 		CLEAR_AFTER_FIELD(p, fmt.sdr.buffersize);
18319effc72fSAntti Palosaari 		return ops->vidioc_try_fmt_sdr_out(file, fh, arg);
1832fb9ffa6aSLaurent Pinchart 	case V4L2_BUF_TYPE_META_CAPTURE:
1833b2469c81SHans Verkuil 		if (unlikely(!ops->vidioc_try_fmt_meta_cap))
1834fb9ffa6aSLaurent Pinchart 			break;
1835fb9ffa6aSLaurent Pinchart 		CLEAR_AFTER_FIELD(p, fmt.meta);
1836fb9ffa6aSLaurent Pinchart 		return ops->vidioc_try_fmt_meta_cap(file, fh, arg);
183772148d1aSSakari Ailus 	case V4L2_BUF_TYPE_META_OUTPUT:
183872148d1aSSakari Ailus 		if (unlikely(!ops->vidioc_try_fmt_meta_out))
183972148d1aSSakari Ailus 			break;
184072148d1aSSakari Ailus 		CLEAR_AFTER_FIELD(p, fmt.meta);
184172148d1aSSakari Ailus 		return ops->vidioc_try_fmt_meta_out(file, fh, arg);
18425bc3cb74SMauro Carvalho Chehab 	}
18435bc3cb74SMauro Carvalho Chehab 	return -EINVAL;
18445bc3cb74SMauro Carvalho Chehab }
18455bc3cb74SMauro Carvalho Chehab 
18465bc3cb74SMauro Carvalho Chehab static int v4l_streamon(const struct v4l2_ioctl_ops *ops,
18475bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
18485bc3cb74SMauro Carvalho Chehab {
18495bc3cb74SMauro Carvalho Chehab 	return ops->vidioc_streamon(file, fh, *(unsigned int *)arg);
18505bc3cb74SMauro Carvalho Chehab }
18515bc3cb74SMauro Carvalho Chehab 
18525bc3cb74SMauro Carvalho Chehab static int v4l_streamoff(const struct v4l2_ioctl_ops *ops,
18535bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
18545bc3cb74SMauro Carvalho Chehab {
18555bc3cb74SMauro Carvalho Chehab 	return ops->vidioc_streamoff(file, fh, *(unsigned int *)arg);
18565bc3cb74SMauro Carvalho Chehab }
18575bc3cb74SMauro Carvalho Chehab 
18585bc3cb74SMauro Carvalho Chehab static int v4l_g_tuner(const struct v4l2_ioctl_ops *ops,
18595bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
18605bc3cb74SMauro Carvalho Chehab {
18615bc3cb74SMauro Carvalho Chehab 	struct video_device *vfd = video_devdata(file);
18625bc3cb74SMauro Carvalho Chehab 	struct v4l2_tuner *p = arg;
18635bc3cb74SMauro Carvalho Chehab 	int err;
18645bc3cb74SMauro Carvalho Chehab 
18655bc3cb74SMauro Carvalho Chehab 	p->type = (vfd->vfl_type == VFL_TYPE_RADIO) ?
18665bc3cb74SMauro Carvalho Chehab 			V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV;
18675bc3cb74SMauro Carvalho Chehab 	err = ops->vidioc_g_tuner(file, fh, p);
18685bc3cb74SMauro Carvalho Chehab 	if (!err)
18695bc3cb74SMauro Carvalho Chehab 		p->capability |= V4L2_TUNER_CAP_FREQ_BANDS;
18705bc3cb74SMauro Carvalho Chehab 	return err;
18715bc3cb74SMauro Carvalho Chehab }
18725bc3cb74SMauro Carvalho Chehab 
18735bc3cb74SMauro Carvalho Chehab static int v4l_s_tuner(const struct v4l2_ioctl_ops *ops,
18745bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
18755bc3cb74SMauro Carvalho Chehab {
18765bc3cb74SMauro Carvalho Chehab 	struct video_device *vfd = video_devdata(file);
18775bc3cb74SMauro Carvalho Chehab 	struct v4l2_tuner *p = arg;
187877fa4e07SShuah Khan 	int ret;
18795bc3cb74SMauro Carvalho Chehab 
188077fa4e07SShuah Khan 	ret = v4l_enable_media_source(vfd);
188177fa4e07SShuah Khan 	if (ret)
188277fa4e07SShuah Khan 		return ret;
18835bc3cb74SMauro Carvalho Chehab 	p->type = (vfd->vfl_type == VFL_TYPE_RADIO) ?
18845bc3cb74SMauro Carvalho Chehab 			V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV;
18855bc3cb74SMauro Carvalho Chehab 	return ops->vidioc_s_tuner(file, fh, p);
18865bc3cb74SMauro Carvalho Chehab }
18875bc3cb74SMauro Carvalho Chehab 
18885bc3cb74SMauro Carvalho Chehab static int v4l_g_modulator(const struct v4l2_ioctl_ops *ops,
18895bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
18905bc3cb74SMauro Carvalho Chehab {
18914124a3c4SAntti Palosaari 	struct video_device *vfd = video_devdata(file);
18925bc3cb74SMauro Carvalho Chehab 	struct v4l2_modulator *p = arg;
18935bc3cb74SMauro Carvalho Chehab 	int err;
18945bc3cb74SMauro Carvalho Chehab 
18954124a3c4SAntti Palosaari 	if (vfd->vfl_type == VFL_TYPE_RADIO)
18964124a3c4SAntti Palosaari 		p->type = V4L2_TUNER_RADIO;
18974124a3c4SAntti Palosaari 
18985bc3cb74SMauro Carvalho Chehab 	err = ops->vidioc_g_modulator(file, fh, p);
18995bc3cb74SMauro Carvalho Chehab 	if (!err)
19005bc3cb74SMauro Carvalho Chehab 		p->capability |= V4L2_TUNER_CAP_FREQ_BANDS;
19015bc3cb74SMauro Carvalho Chehab 	return err;
19025bc3cb74SMauro Carvalho Chehab }
19035bc3cb74SMauro Carvalho Chehab 
19044124a3c4SAntti Palosaari static int v4l_s_modulator(const struct v4l2_ioctl_ops *ops,
19054124a3c4SAntti Palosaari 				struct file *file, void *fh, void *arg)
19064124a3c4SAntti Palosaari {
19074124a3c4SAntti Palosaari 	struct video_device *vfd = video_devdata(file);
19084124a3c4SAntti Palosaari 	struct v4l2_modulator *p = arg;
19094124a3c4SAntti Palosaari 
19104124a3c4SAntti Palosaari 	if (vfd->vfl_type == VFL_TYPE_RADIO)
19114124a3c4SAntti Palosaari 		p->type = V4L2_TUNER_RADIO;
19124124a3c4SAntti Palosaari 
19134124a3c4SAntti Palosaari 	return ops->vidioc_s_modulator(file, fh, p);
19144124a3c4SAntti Palosaari }
19154124a3c4SAntti Palosaari 
19165bc3cb74SMauro Carvalho Chehab static int v4l_g_frequency(const struct v4l2_ioctl_ops *ops,
19175bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
19185bc3cb74SMauro Carvalho Chehab {
19195bc3cb74SMauro Carvalho Chehab 	struct video_device *vfd = video_devdata(file);
19205bc3cb74SMauro Carvalho Chehab 	struct v4l2_frequency *p = arg;
19215bc3cb74SMauro Carvalho Chehab 
192284099a28SAntti Palosaari 	if (vfd->vfl_type == VFL_TYPE_SDR)
1923f3c3ececSAntti Palosaari 		p->type = V4L2_TUNER_SDR;
192484099a28SAntti Palosaari 	else
19255bc3cb74SMauro Carvalho Chehab 		p->type = (vfd->vfl_type == VFL_TYPE_RADIO) ?
19265bc3cb74SMauro Carvalho Chehab 				V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV;
19275bc3cb74SMauro Carvalho Chehab 	return ops->vidioc_g_frequency(file, fh, p);
19285bc3cb74SMauro Carvalho Chehab }
19295bc3cb74SMauro Carvalho Chehab 
19305bc3cb74SMauro Carvalho Chehab static int v4l_s_frequency(const struct v4l2_ioctl_ops *ops,
19315bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
19325bc3cb74SMauro Carvalho Chehab {
19335bc3cb74SMauro Carvalho Chehab 	struct video_device *vfd = video_devdata(file);
1934b530a447SHans Verkuil 	const struct v4l2_frequency *p = arg;
19355bc3cb74SMauro Carvalho Chehab 	enum v4l2_tuner_type type;
193677fa4e07SShuah Khan 	int ret;
19375bc3cb74SMauro Carvalho Chehab 
193877fa4e07SShuah Khan 	ret = v4l_enable_media_source(vfd);
193977fa4e07SShuah Khan 	if (ret)
194077fa4e07SShuah Khan 		return ret;
194184099a28SAntti Palosaari 	if (vfd->vfl_type == VFL_TYPE_SDR) {
1942f3c3ececSAntti Palosaari 		if (p->type != V4L2_TUNER_SDR && p->type != V4L2_TUNER_RF)
194384099a28SAntti Palosaari 			return -EINVAL;
194484099a28SAntti Palosaari 	} else {
19455bc3cb74SMauro Carvalho Chehab 		type = (vfd->vfl_type == VFL_TYPE_RADIO) ?
19465bc3cb74SMauro Carvalho Chehab 				V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV;
194784099a28SAntti Palosaari 		if (type != p->type)
19485bc3cb74SMauro Carvalho Chehab 			return -EINVAL;
194984099a28SAntti Palosaari 	}
19505bc3cb74SMauro Carvalho Chehab 	return ops->vidioc_s_frequency(file, fh, p);
19515bc3cb74SMauro Carvalho Chehab }
19525bc3cb74SMauro Carvalho Chehab 
19535bc3cb74SMauro Carvalho Chehab static int v4l_enumstd(const struct v4l2_ioctl_ops *ops,
19545bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
19555bc3cb74SMauro Carvalho Chehab {
19565bc3cb74SMauro Carvalho Chehab 	struct video_device *vfd = video_devdata(file);
19575bc3cb74SMauro Carvalho Chehab 	struct v4l2_standard *p = arg;
19585bc3cb74SMauro Carvalho Chehab 
1959aa2f8871SNiklas Söderlund 	return v4l_video_std_enumstd(p, vfd->tvnorms);
19605bc3cb74SMauro Carvalho Chehab }
19615bc3cb74SMauro Carvalho Chehab 
19625bc3cb74SMauro Carvalho Chehab static int v4l_s_std(const struct v4l2_ioctl_ops *ops,
19635bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
19645bc3cb74SMauro Carvalho Chehab {
19655bc3cb74SMauro Carvalho Chehab 	struct video_device *vfd = video_devdata(file);
1966314527acSHans Verkuil 	v4l2_std_id id = *(v4l2_std_id *)arg, norm;
196777fa4e07SShuah Khan 	int ret;
19685bc3cb74SMauro Carvalho Chehab 
196977fa4e07SShuah Khan 	ret = v4l_enable_media_source(vfd);
197077fa4e07SShuah Khan 	if (ret)
197177fa4e07SShuah Khan 		return ret;
1972314527acSHans Verkuil 	norm = id & vfd->tvnorms;
19735bc3cb74SMauro Carvalho Chehab 	if (vfd->tvnorms && !norm)	/* Check if std is supported */
19745bc3cb74SMauro Carvalho Chehab 		return -EINVAL;
19755bc3cb74SMauro Carvalho Chehab 
19765bc3cb74SMauro Carvalho Chehab 	/* Calls the specific handler */
1977ca371575SHans Verkuil 	return ops->vidioc_s_std(file, fh, norm);
19785bc3cb74SMauro Carvalho Chehab }
19795bc3cb74SMauro Carvalho Chehab 
19805bc3cb74SMauro Carvalho Chehab static int v4l_querystd(const struct v4l2_ioctl_ops *ops,
19815bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
19825bc3cb74SMauro Carvalho Chehab {
19835bc3cb74SMauro Carvalho Chehab 	struct video_device *vfd = video_devdata(file);
19845bc3cb74SMauro Carvalho Chehab 	v4l2_std_id *p = arg;
198577fa4e07SShuah Khan 	int ret;
19865bc3cb74SMauro Carvalho Chehab 
198777fa4e07SShuah Khan 	ret = v4l_enable_media_source(vfd);
198877fa4e07SShuah Khan 	if (ret)
198977fa4e07SShuah Khan 		return ret;
19905bc3cb74SMauro Carvalho Chehab 	/*
19911a2c6866SHans Verkuil 	 * If no signal is detected, then the driver should return
19921a2c6866SHans Verkuil 	 * V4L2_STD_UNKNOWN. Otherwise it should return tvnorms with
19931a2c6866SHans Verkuil 	 * any standards that do not apply removed.
19941a2c6866SHans Verkuil 	 *
19955bc3cb74SMauro Carvalho Chehab 	 * This means that tuners, audio and video decoders can join
19965bc3cb74SMauro Carvalho Chehab 	 * their efforts to improve the standards detection.
19975bc3cb74SMauro Carvalho Chehab 	 */
19985bc3cb74SMauro Carvalho Chehab 	*p = vfd->tvnorms;
19995bc3cb74SMauro Carvalho Chehab 	return ops->vidioc_querystd(file, fh, arg);
20005bc3cb74SMauro Carvalho Chehab }
20015bc3cb74SMauro Carvalho Chehab 
20025bc3cb74SMauro Carvalho Chehab static int v4l_s_hw_freq_seek(const struct v4l2_ioctl_ops *ops,
20035bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
20045bc3cb74SMauro Carvalho Chehab {
20055bc3cb74SMauro Carvalho Chehab 	struct video_device *vfd = video_devdata(file);
20065bc3cb74SMauro Carvalho Chehab 	struct v4l2_hw_freq_seek *p = arg;
20075bc3cb74SMauro Carvalho Chehab 	enum v4l2_tuner_type type;
200877fa4e07SShuah Khan 	int ret;
20095bc3cb74SMauro Carvalho Chehab 
201077fa4e07SShuah Khan 	ret = v4l_enable_media_source(vfd);
201177fa4e07SShuah Khan 	if (ret)
201277fa4e07SShuah Khan 		return ret;
201384099a28SAntti Palosaari 	/* s_hw_freq_seek is not supported for SDR for now */
201484099a28SAntti Palosaari 	if (vfd->vfl_type == VFL_TYPE_SDR)
201584099a28SAntti Palosaari 		return -EINVAL;
201684099a28SAntti Palosaari 
20175bc3cb74SMauro Carvalho Chehab 	type = (vfd->vfl_type == VFL_TYPE_RADIO) ?
20185bc3cb74SMauro Carvalho Chehab 		V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV;
20195bc3cb74SMauro Carvalho Chehab 	if (p->type != type)
20205bc3cb74SMauro Carvalho Chehab 		return -EINVAL;
20215bc3cb74SMauro Carvalho Chehab 	return ops->vidioc_s_hw_freq_seek(file, fh, p);
20225bc3cb74SMauro Carvalho Chehab }
20235bc3cb74SMauro Carvalho Chehab 
2024737c097bSHans Verkuil static int v4l_overlay(const struct v4l2_ioctl_ops *ops,
2025737c097bSHans Verkuil 				struct file *file, void *fh, void *arg)
2026737c097bSHans Verkuil {
2027737c097bSHans Verkuil 	return ops->vidioc_overlay(file, fh, *(unsigned int *)arg);
2028737c097bSHans Verkuil }
2029737c097bSHans Verkuil 
20305bc3cb74SMauro Carvalho Chehab static int v4l_reqbufs(const struct v4l2_ioctl_ops *ops,
20315bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
20325bc3cb74SMauro Carvalho Chehab {
20335bc3cb74SMauro Carvalho Chehab 	struct v4l2_requestbuffers *p = arg;
20344b20259fSHans Verkuil 	int ret = check_fmt(file, p->type);
20355bc3cb74SMauro Carvalho Chehab 
20365bc3cb74SMauro Carvalho Chehab 	if (ret)
20375bc3cb74SMauro Carvalho Chehab 		return ret;
2038129134e5SSergey Senozhatsky 
2039c0acf9cfSSergey Senozhatsky 	CLEAR_AFTER_FIELD(p, flags);
2040129134e5SSergey Senozhatsky 
20415bc3cb74SMauro Carvalho Chehab 	return ops->vidioc_reqbufs(file, fh, p);
20425bc3cb74SMauro Carvalho Chehab }
20435bc3cb74SMauro Carvalho Chehab 
20445bc3cb74SMauro Carvalho Chehab static int v4l_querybuf(const struct v4l2_ioctl_ops *ops,
20455bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
20465bc3cb74SMauro Carvalho Chehab {
20475bc3cb74SMauro Carvalho Chehab 	struct v4l2_buffer *p = arg;
20484b20259fSHans Verkuil 	int ret = check_fmt(file, p->type);
20495bc3cb74SMauro Carvalho Chehab 
20505bc3cb74SMauro Carvalho Chehab 	return ret ? ret : ops->vidioc_querybuf(file, fh, p);
20515bc3cb74SMauro Carvalho Chehab }
20525bc3cb74SMauro Carvalho Chehab 
20535bc3cb74SMauro Carvalho Chehab static int v4l_qbuf(const struct v4l2_ioctl_ops *ops,
20545bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
20555bc3cb74SMauro Carvalho Chehab {
20565bc3cb74SMauro Carvalho Chehab 	struct v4l2_buffer *p = arg;
20574b20259fSHans Verkuil 	int ret = check_fmt(file, p->type);
20585bc3cb74SMauro Carvalho Chehab 
20595bc3cb74SMauro Carvalho Chehab 	return ret ? ret : ops->vidioc_qbuf(file, fh, p);
20605bc3cb74SMauro Carvalho Chehab }
20615bc3cb74SMauro Carvalho Chehab 
20625bc3cb74SMauro Carvalho Chehab static int v4l_dqbuf(const struct v4l2_ioctl_ops *ops,
20635bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
20645bc3cb74SMauro Carvalho Chehab {
20655bc3cb74SMauro Carvalho Chehab 	struct v4l2_buffer *p = arg;
20664b20259fSHans Verkuil 	int ret = check_fmt(file, p->type);
20675bc3cb74SMauro Carvalho Chehab 
20685bc3cb74SMauro Carvalho Chehab 	return ret ? ret : ops->vidioc_dqbuf(file, fh, p);
20695bc3cb74SMauro Carvalho Chehab }
20705bc3cb74SMauro Carvalho Chehab 
20715bc3cb74SMauro Carvalho Chehab static int v4l_create_bufs(const struct v4l2_ioctl_ops *ops,
20725bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
20735bc3cb74SMauro Carvalho Chehab {
20745bc3cb74SMauro Carvalho Chehab 	struct v4l2_create_buffers *create = arg;
20754b20259fSHans Verkuil 	int ret = check_fmt(file, create->format.type);
20765bc3cb74SMauro Carvalho Chehab 
2077d52e2381SLaurent Pinchart 	if (ret)
2078d52e2381SLaurent Pinchart 		return ret;
2079d52e2381SLaurent Pinchart 
2080c0acf9cfSSergey Senozhatsky 	CLEAR_AFTER_FIELD(create, flags);
20815d351251SHans Verkuil 
2082d52e2381SLaurent Pinchart 	v4l_sanitize_format(&create->format);
2083d52e2381SLaurent Pinchart 
2084d52e2381SLaurent Pinchart 	ret = ops->vidioc_create_bufs(file, fh, create);
2085d52e2381SLaurent Pinchart 
2086d52e2381SLaurent Pinchart 	if (create->format.type == V4L2_BUF_TYPE_VIDEO_CAPTURE ||
2087d52e2381SLaurent Pinchart 	    create->format.type == V4L2_BUF_TYPE_VIDEO_OUTPUT)
2088d52e2381SLaurent Pinchart 		create->format.fmt.pix.priv = V4L2_PIX_FMT_PRIV_MAGIC;
2089d52e2381SLaurent Pinchart 
2090d52e2381SLaurent Pinchart 	return ret;
20915bc3cb74SMauro Carvalho Chehab }
20925bc3cb74SMauro Carvalho Chehab 
20935bc3cb74SMauro Carvalho Chehab static int v4l_prepare_buf(const struct v4l2_ioctl_ops *ops,
20945bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
20955bc3cb74SMauro Carvalho Chehab {
20965bc3cb74SMauro Carvalho Chehab 	struct v4l2_buffer *b = arg;
20974b20259fSHans Verkuil 	int ret = check_fmt(file, b->type);
20985bc3cb74SMauro Carvalho Chehab 
20995bc3cb74SMauro Carvalho Chehab 	return ret ? ret : ops->vidioc_prepare_buf(file, fh, b);
21005bc3cb74SMauro Carvalho Chehab }
21015bc3cb74SMauro Carvalho Chehab 
21025bc3cb74SMauro Carvalho Chehab static int v4l_g_parm(const struct v4l2_ioctl_ops *ops,
21035bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
21045bc3cb74SMauro Carvalho Chehab {
2105cd9d9377SHans Verkuil 	struct video_device *vfd = video_devdata(file);
21065bc3cb74SMauro Carvalho Chehab 	struct v4l2_streamparm *p = arg;
21075bc3cb74SMauro Carvalho Chehab 	v4l2_std_id std;
21084b20259fSHans Verkuil 	int ret = check_fmt(file, p->type);
21095bc3cb74SMauro Carvalho Chehab 
21105bc3cb74SMauro Carvalho Chehab 	if (ret)
21115bc3cb74SMauro Carvalho Chehab 		return ret;
21125bc3cb74SMauro Carvalho Chehab 	if (ops->vidioc_g_parm)
21135bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_g_parm(file, fh, p);
21145bc3cb74SMauro Carvalho Chehab 	if (p->type != V4L2_BUF_TYPE_VIDEO_CAPTURE &&
21155bc3cb74SMauro Carvalho Chehab 	    p->type != V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
21165bc3cb74SMauro Carvalho Chehab 		return -EINVAL;
2117cd9d9377SHans Verkuil 	if (vfd->device_caps & V4L2_CAP_READWRITE)
21185bc3cb74SMauro Carvalho Chehab 		p->parm.capture.readbuffers = 2;
21195bc3cb74SMauro Carvalho Chehab 	ret = ops->vidioc_g_std(file, fh, &std);
21205bc3cb74SMauro Carvalho Chehab 	if (ret == 0)
2121ca371575SHans Verkuil 		v4l2_video_std_frame_period(std, &p->parm.capture.timeperframe);
21225bc3cb74SMauro Carvalho Chehab 	return ret;
21235bc3cb74SMauro Carvalho Chehab }
21245bc3cb74SMauro Carvalho Chehab 
21255bc3cb74SMauro Carvalho Chehab static int v4l_s_parm(const struct v4l2_ioctl_ops *ops,
21265bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
21275bc3cb74SMauro Carvalho Chehab {
21285bc3cb74SMauro Carvalho Chehab 	struct v4l2_streamparm *p = arg;
21294b20259fSHans Verkuil 	int ret = check_fmt(file, p->type);
21305bc3cb74SMauro Carvalho Chehab 
21318a7c5594SHans Verkuil 	if (ret)
21328a7c5594SHans Verkuil 		return ret;
21338a7c5594SHans Verkuil 
21344f62e840SHans Verkuil 	/* Note: extendedmode is never used in drivers */
21358a7c5594SHans Verkuil 	if (V4L2_TYPE_IS_OUTPUT(p->type)) {
21368a7c5594SHans Verkuil 		memset(p->parm.output.reserved, 0,
21378a7c5594SHans Verkuil 		       sizeof(p->parm.output.reserved));
21388a7c5594SHans Verkuil 		p->parm.output.extendedmode = 0;
21398a7c5594SHans Verkuil 		p->parm.output.outputmode &= V4L2_MODE_HIGHQUALITY;
21408a7c5594SHans Verkuil 	} else {
21418a7c5594SHans Verkuil 		memset(p->parm.capture.reserved, 0,
21428a7c5594SHans Verkuil 		       sizeof(p->parm.capture.reserved));
21434f62e840SHans Verkuil 		p->parm.capture.extendedmode = 0;
21448a7c5594SHans Verkuil 		p->parm.capture.capturemode &= V4L2_MODE_HIGHQUALITY;
21458a7c5594SHans Verkuil 	}
21468a7c5594SHans Verkuil 	return ops->vidioc_s_parm(file, fh, p);
21475bc3cb74SMauro Carvalho Chehab }
21485bc3cb74SMauro Carvalho Chehab 
21495bc3cb74SMauro Carvalho Chehab static int v4l_queryctrl(const struct v4l2_ioctl_ops *ops,
21505bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
21515bc3cb74SMauro Carvalho Chehab {
21525bc3cb74SMauro Carvalho Chehab 	struct video_device *vfd = video_devdata(file);
21535bc3cb74SMauro Carvalho Chehab 	struct v4l2_queryctrl *p = arg;
21545bc3cb74SMauro Carvalho Chehab 	struct v4l2_fh *vfh =
21555bc3cb74SMauro Carvalho Chehab 		test_bit(V4L2_FL_USES_V4L2_FH, &vfd->flags) ? fh : NULL;
21565bc3cb74SMauro Carvalho Chehab 
21575bc3cb74SMauro Carvalho Chehab 	if (vfh && vfh->ctrl_handler)
21585bc3cb74SMauro Carvalho Chehab 		return v4l2_queryctrl(vfh->ctrl_handler, p);
21595bc3cb74SMauro Carvalho Chehab 	if (vfd->ctrl_handler)
21605bc3cb74SMauro Carvalho Chehab 		return v4l2_queryctrl(vfd->ctrl_handler, p);
21615bc3cb74SMauro Carvalho Chehab 	if (ops->vidioc_queryctrl)
21625bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_queryctrl(file, fh, p);
21635bc3cb74SMauro Carvalho Chehab 	return -ENOTTY;
21645bc3cb74SMauro Carvalho Chehab }
21655bc3cb74SMauro Carvalho Chehab 
2166e6bee368SHans Verkuil static int v4l_query_ext_ctrl(const struct v4l2_ioctl_ops *ops,
2167e6bee368SHans Verkuil 				struct file *file, void *fh, void *arg)
2168e6bee368SHans Verkuil {
2169e6bee368SHans Verkuil 	struct video_device *vfd = video_devdata(file);
2170e6bee368SHans Verkuil 	struct v4l2_query_ext_ctrl *p = arg;
2171e6bee368SHans Verkuil 	struct v4l2_fh *vfh =
2172e6bee368SHans Verkuil 		test_bit(V4L2_FL_USES_V4L2_FH, &vfd->flags) ? fh : NULL;
2173e6bee368SHans Verkuil 
2174e6bee368SHans Verkuil 	if (vfh && vfh->ctrl_handler)
2175e6bee368SHans Verkuil 		return v4l2_query_ext_ctrl(vfh->ctrl_handler, p);
2176e6bee368SHans Verkuil 	if (vfd->ctrl_handler)
2177e6bee368SHans Verkuil 		return v4l2_query_ext_ctrl(vfd->ctrl_handler, p);
2178e6bee368SHans Verkuil 	if (ops->vidioc_query_ext_ctrl)
2179e6bee368SHans Verkuil 		return ops->vidioc_query_ext_ctrl(file, fh, p);
2180e6bee368SHans Verkuil 	return -ENOTTY;
2181e6bee368SHans Verkuil }
2182e6bee368SHans Verkuil 
21835bc3cb74SMauro Carvalho Chehab static int v4l_querymenu(const struct v4l2_ioctl_ops *ops,
21845bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
21855bc3cb74SMauro Carvalho Chehab {
21865bc3cb74SMauro Carvalho Chehab 	struct video_device *vfd = video_devdata(file);
21875bc3cb74SMauro Carvalho Chehab 	struct v4l2_querymenu *p = arg;
21885bc3cb74SMauro Carvalho Chehab 	struct v4l2_fh *vfh =
21895bc3cb74SMauro Carvalho Chehab 		test_bit(V4L2_FL_USES_V4L2_FH, &vfd->flags) ? fh : NULL;
21905bc3cb74SMauro Carvalho Chehab 
21915bc3cb74SMauro Carvalho Chehab 	if (vfh && vfh->ctrl_handler)
21925bc3cb74SMauro Carvalho Chehab 		return v4l2_querymenu(vfh->ctrl_handler, p);
21935bc3cb74SMauro Carvalho Chehab 	if (vfd->ctrl_handler)
21945bc3cb74SMauro Carvalho Chehab 		return v4l2_querymenu(vfd->ctrl_handler, p);
21955bc3cb74SMauro Carvalho Chehab 	if (ops->vidioc_querymenu)
21965bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_querymenu(file, fh, p);
21975bc3cb74SMauro Carvalho Chehab 	return -ENOTTY;
21985bc3cb74SMauro Carvalho Chehab }
21995bc3cb74SMauro Carvalho Chehab 
22005bc3cb74SMauro Carvalho Chehab static int v4l_g_ctrl(const struct v4l2_ioctl_ops *ops,
22015bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
22025bc3cb74SMauro Carvalho Chehab {
22035bc3cb74SMauro Carvalho Chehab 	struct video_device *vfd = video_devdata(file);
22045bc3cb74SMauro Carvalho Chehab 	struct v4l2_control *p = arg;
22055bc3cb74SMauro Carvalho Chehab 	struct v4l2_fh *vfh =
22065bc3cb74SMauro Carvalho Chehab 		test_bit(V4L2_FL_USES_V4L2_FH, &vfd->flags) ? fh : NULL;
22075bc3cb74SMauro Carvalho Chehab 	struct v4l2_ext_controls ctrls;
22085bc3cb74SMauro Carvalho Chehab 	struct v4l2_ext_control ctrl;
22095bc3cb74SMauro Carvalho Chehab 
22105bc3cb74SMauro Carvalho Chehab 	if (vfh && vfh->ctrl_handler)
22115bc3cb74SMauro Carvalho Chehab 		return v4l2_g_ctrl(vfh->ctrl_handler, p);
22125bc3cb74SMauro Carvalho Chehab 	if (vfd->ctrl_handler)
22135bc3cb74SMauro Carvalho Chehab 		return v4l2_g_ctrl(vfd->ctrl_handler, p);
22145bc3cb74SMauro Carvalho Chehab 	if (ops->vidioc_g_ctrl)
22155bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_g_ctrl(file, fh, p);
22165bc3cb74SMauro Carvalho Chehab 	if (ops->vidioc_g_ext_ctrls == NULL)
22175bc3cb74SMauro Carvalho Chehab 		return -ENOTTY;
22185bc3cb74SMauro Carvalho Chehab 
22190f8017beSRicardo Ribalda 	ctrls.which = V4L2_CTRL_ID2WHICH(p->id);
22205bc3cb74SMauro Carvalho Chehab 	ctrls.count = 1;
22215bc3cb74SMauro Carvalho Chehab 	ctrls.controls = &ctrl;
22225bc3cb74SMauro Carvalho Chehab 	ctrl.id = p->id;
22235bc3cb74SMauro Carvalho Chehab 	ctrl.value = p->value;
2224861f92cbSRicardo Ribalda 	if (check_ext_ctrls(&ctrls, VIDIOC_G_CTRL)) {
22255bc3cb74SMauro Carvalho Chehab 		int ret = ops->vidioc_g_ext_ctrls(file, fh, &ctrls);
22265bc3cb74SMauro Carvalho Chehab 
22275bc3cb74SMauro Carvalho Chehab 		if (ret == 0)
22285bc3cb74SMauro Carvalho Chehab 			p->value = ctrl.value;
22295bc3cb74SMauro Carvalho Chehab 		return ret;
22305bc3cb74SMauro Carvalho Chehab 	}
22315bc3cb74SMauro Carvalho Chehab 	return -EINVAL;
22325bc3cb74SMauro Carvalho Chehab }
22335bc3cb74SMauro Carvalho Chehab 
22345bc3cb74SMauro Carvalho Chehab static int v4l_s_ctrl(const struct v4l2_ioctl_ops *ops,
22355bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
22365bc3cb74SMauro Carvalho Chehab {
22375bc3cb74SMauro Carvalho Chehab 	struct video_device *vfd = video_devdata(file);
22385bc3cb74SMauro Carvalho Chehab 	struct v4l2_control *p = arg;
22395bc3cb74SMauro Carvalho Chehab 	struct v4l2_fh *vfh =
22405bc3cb74SMauro Carvalho Chehab 		test_bit(V4L2_FL_USES_V4L2_FH, &vfd->flags) ? fh : NULL;
22415bc3cb74SMauro Carvalho Chehab 	struct v4l2_ext_controls ctrls;
22425bc3cb74SMauro Carvalho Chehab 	struct v4l2_ext_control ctrl;
2243c87ed935SRicardo Ribalda 	int ret;
22445bc3cb74SMauro Carvalho Chehab 
22455bc3cb74SMauro Carvalho Chehab 	if (vfh && vfh->ctrl_handler)
22465bc3cb74SMauro Carvalho Chehab 		return v4l2_s_ctrl(vfh, vfh->ctrl_handler, p);
22475bc3cb74SMauro Carvalho Chehab 	if (vfd->ctrl_handler)
22485bc3cb74SMauro Carvalho Chehab 		return v4l2_s_ctrl(NULL, vfd->ctrl_handler, p);
22495bc3cb74SMauro Carvalho Chehab 	if (ops->vidioc_s_ctrl)
22505bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_s_ctrl(file, fh, p);
22515bc3cb74SMauro Carvalho Chehab 	if (ops->vidioc_s_ext_ctrls == NULL)
22525bc3cb74SMauro Carvalho Chehab 		return -ENOTTY;
22535bc3cb74SMauro Carvalho Chehab 
22540f8017beSRicardo Ribalda 	ctrls.which = V4L2_CTRL_ID2WHICH(p->id);
22555bc3cb74SMauro Carvalho Chehab 	ctrls.count = 1;
22565bc3cb74SMauro Carvalho Chehab 	ctrls.controls = &ctrl;
22575bc3cb74SMauro Carvalho Chehab 	ctrl.id = p->id;
22585bc3cb74SMauro Carvalho Chehab 	ctrl.value = p->value;
2259c87ed935SRicardo Ribalda 	if (!check_ext_ctrls(&ctrls, VIDIOC_S_CTRL))
22605bc3cb74SMauro Carvalho Chehab 		return -EINVAL;
2261c87ed935SRicardo Ribalda 	ret = ops->vidioc_s_ext_ctrls(file, fh, &ctrls);
2262c87ed935SRicardo Ribalda 	p->value = ctrl.value;
2263c87ed935SRicardo Ribalda 	return ret;
22645bc3cb74SMauro Carvalho Chehab }
22655bc3cb74SMauro Carvalho Chehab 
22665bc3cb74SMauro Carvalho Chehab static int v4l_g_ext_ctrls(const struct v4l2_ioctl_ops *ops,
22675bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
22685bc3cb74SMauro Carvalho Chehab {
22695bc3cb74SMauro Carvalho Chehab 	struct video_device *vfd = video_devdata(file);
22705bc3cb74SMauro Carvalho Chehab 	struct v4l2_ext_controls *p = arg;
22715bc3cb74SMauro Carvalho Chehab 	struct v4l2_fh *vfh =
22725bc3cb74SMauro Carvalho Chehab 		test_bit(V4L2_FL_USES_V4L2_FH, &vfd->flags) ? fh : NULL;
22735bc3cb74SMauro Carvalho Chehab 
22745bc3cb74SMauro Carvalho Chehab 	p->error_idx = p->count;
22755bc3cb74SMauro Carvalho Chehab 	if (vfh && vfh->ctrl_handler)
2276173f6eacSEzequiel Garcia 		return v4l2_g_ext_ctrls(vfh->ctrl_handler,
2277173f6eacSEzequiel Garcia 					vfd, vfd->v4l2_dev->mdev, p);
22785bc3cb74SMauro Carvalho Chehab 	if (vfd->ctrl_handler)
2279173f6eacSEzequiel Garcia 		return v4l2_g_ext_ctrls(vfd->ctrl_handler,
2280173f6eacSEzequiel Garcia 					vfd, vfd->v4l2_dev->mdev, p);
22815bc3cb74SMauro Carvalho Chehab 	if (ops->vidioc_g_ext_ctrls == NULL)
22825bc3cb74SMauro Carvalho Chehab 		return -ENOTTY;
2283861f92cbSRicardo Ribalda 	return check_ext_ctrls(p, VIDIOC_G_EXT_CTRLS) ?
2284861f92cbSRicardo Ribalda 				ops->vidioc_g_ext_ctrls(file, fh, p) : -EINVAL;
22855bc3cb74SMauro Carvalho Chehab }
22865bc3cb74SMauro Carvalho Chehab 
22875bc3cb74SMauro Carvalho Chehab static int v4l_s_ext_ctrls(const struct v4l2_ioctl_ops *ops,
22885bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
22895bc3cb74SMauro Carvalho Chehab {
22905bc3cb74SMauro Carvalho Chehab 	struct video_device *vfd = video_devdata(file);
22915bc3cb74SMauro Carvalho Chehab 	struct v4l2_ext_controls *p = arg;
22925bc3cb74SMauro Carvalho Chehab 	struct v4l2_fh *vfh =
22935bc3cb74SMauro Carvalho Chehab 		test_bit(V4L2_FL_USES_V4L2_FH, &vfd->flags) ? fh : NULL;
22945bc3cb74SMauro Carvalho Chehab 
22955bc3cb74SMauro Carvalho Chehab 	p->error_idx = p->count;
22965bc3cb74SMauro Carvalho Chehab 	if (vfh && vfh->ctrl_handler)
2297173f6eacSEzequiel Garcia 		return v4l2_s_ext_ctrls(vfh, vfh->ctrl_handler,
2298173f6eacSEzequiel Garcia 					vfd, vfd->v4l2_dev->mdev, p);
22995bc3cb74SMauro Carvalho Chehab 	if (vfd->ctrl_handler)
2300173f6eacSEzequiel Garcia 		return v4l2_s_ext_ctrls(NULL, vfd->ctrl_handler,
2301173f6eacSEzequiel Garcia 					vfd, vfd->v4l2_dev->mdev, p);
23025bc3cb74SMauro Carvalho Chehab 	if (ops->vidioc_s_ext_ctrls == NULL)
23035bc3cb74SMauro Carvalho Chehab 		return -ENOTTY;
2304861f92cbSRicardo Ribalda 	return check_ext_ctrls(p, VIDIOC_S_EXT_CTRLS) ?
2305861f92cbSRicardo Ribalda 				ops->vidioc_s_ext_ctrls(file, fh, p) : -EINVAL;
23065bc3cb74SMauro Carvalho Chehab }
23075bc3cb74SMauro Carvalho Chehab 
23085bc3cb74SMauro Carvalho Chehab static int v4l_try_ext_ctrls(const struct v4l2_ioctl_ops *ops,
23095bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
23105bc3cb74SMauro Carvalho Chehab {
23115bc3cb74SMauro Carvalho Chehab 	struct video_device *vfd = video_devdata(file);
23125bc3cb74SMauro Carvalho Chehab 	struct v4l2_ext_controls *p = arg;
23135bc3cb74SMauro Carvalho Chehab 	struct v4l2_fh *vfh =
23145bc3cb74SMauro Carvalho Chehab 		test_bit(V4L2_FL_USES_V4L2_FH, &vfd->flags) ? fh : NULL;
23155bc3cb74SMauro Carvalho Chehab 
23165bc3cb74SMauro Carvalho Chehab 	p->error_idx = p->count;
23175bc3cb74SMauro Carvalho Chehab 	if (vfh && vfh->ctrl_handler)
2318173f6eacSEzequiel Garcia 		return v4l2_try_ext_ctrls(vfh->ctrl_handler,
2319173f6eacSEzequiel Garcia 					  vfd, vfd->v4l2_dev->mdev, p);
23205bc3cb74SMauro Carvalho Chehab 	if (vfd->ctrl_handler)
2321173f6eacSEzequiel Garcia 		return v4l2_try_ext_ctrls(vfd->ctrl_handler,
2322173f6eacSEzequiel Garcia 					  vfd, vfd->v4l2_dev->mdev, p);
23235bc3cb74SMauro Carvalho Chehab 	if (ops->vidioc_try_ext_ctrls == NULL)
23245bc3cb74SMauro Carvalho Chehab 		return -ENOTTY;
2325861f92cbSRicardo Ribalda 	return check_ext_ctrls(p, VIDIOC_TRY_EXT_CTRLS) ?
2326861f92cbSRicardo Ribalda 			ops->vidioc_try_ext_ctrls(file, fh, p) : -EINVAL;
23275bc3cb74SMauro Carvalho Chehab }
23285bc3cb74SMauro Carvalho Chehab 
2329eaec420fSHans Verkuil /*
2330eaec420fSHans Verkuil  * The selection API specified originally that the _MPLANE buffer types
2331eaec420fSHans Verkuil  * shouldn't be used. The reasons for this are lost in the mists of time
2332eaec420fSHans Verkuil  * (or just really crappy memories). Regardless, this is really annoying
2333eaec420fSHans Verkuil  * for userspace. So to keep things simple we map _MPLANE buffer types
2334eaec420fSHans Verkuil  * to their 'regular' counterparts before calling the driver. And we
2335eaec420fSHans Verkuil  * restore it afterwards. This way applications can use either buffer
2336eaec420fSHans Verkuil  * type and drivers don't need to check for both.
2337eaec420fSHans Verkuil  */
2338eaec420fSHans Verkuil static int v4l_g_selection(const struct v4l2_ioctl_ops *ops,
2339eaec420fSHans Verkuil 			   struct file *file, void *fh, void *arg)
2340eaec420fSHans Verkuil {
2341eaec420fSHans Verkuil 	struct v4l2_selection *p = arg;
2342eaec420fSHans Verkuil 	u32 old_type = p->type;
2343eaec420fSHans Verkuil 	int ret;
2344eaec420fSHans Verkuil 
2345eaec420fSHans Verkuil 	if (p->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
2346eaec420fSHans Verkuil 		p->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
2347eaec420fSHans Verkuil 	else if (p->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)
2348eaec420fSHans Verkuil 		p->type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
2349eaec420fSHans Verkuil 	ret = ops->vidioc_g_selection(file, fh, p);
2350eaec420fSHans Verkuil 	p->type = old_type;
2351eaec420fSHans Verkuil 	return ret;
2352eaec420fSHans Verkuil }
2353eaec420fSHans Verkuil 
2354eaec420fSHans Verkuil static int v4l_s_selection(const struct v4l2_ioctl_ops *ops,
2355eaec420fSHans Verkuil 			   struct file *file, void *fh, void *arg)
2356eaec420fSHans Verkuil {
2357eaec420fSHans Verkuil 	struct v4l2_selection *p = arg;
2358eaec420fSHans Verkuil 	u32 old_type = p->type;
2359eaec420fSHans Verkuil 	int ret;
2360eaec420fSHans Verkuil 
2361eaec420fSHans Verkuil 	if (p->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
2362eaec420fSHans Verkuil 		p->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
2363eaec420fSHans Verkuil 	else if (p->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)
2364eaec420fSHans Verkuil 		p->type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
2365eaec420fSHans Verkuil 	ret = ops->vidioc_s_selection(file, fh, p);
2366eaec420fSHans Verkuil 	p->type = old_type;
2367eaec420fSHans Verkuil 	return ret;
2368eaec420fSHans Verkuil }
2369eaec420fSHans Verkuil 
23705bc3cb74SMauro Carvalho Chehab static int v4l_g_crop(const struct v4l2_ioctl_ops *ops,
23715bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
23725bc3cb74SMauro Carvalho Chehab {
23738cbd94bdSHans Verkuil 	struct video_device *vfd = video_devdata(file);
23745bc3cb74SMauro Carvalho Chehab 	struct v4l2_crop *p = arg;
23755bc3cb74SMauro Carvalho Chehab 	struct v4l2_selection s = {
23765bc3cb74SMauro Carvalho Chehab 		.type = p->type,
23775bc3cb74SMauro Carvalho Chehab 	};
23785bc3cb74SMauro Carvalho Chehab 	int ret;
23795bc3cb74SMauro Carvalho Chehab 
23805bc3cb74SMauro Carvalho Chehab 	/* simulate capture crop using selection api */
23815bc3cb74SMauro Carvalho Chehab 
23825bc3cb74SMauro Carvalho Chehab 	/* crop means compose for output devices */
23835bc3cb74SMauro Carvalho Chehab 	if (V4L2_TYPE_IS_OUTPUT(p->type))
23845b79da06SHans Verkuil 		s.target = V4L2_SEL_TGT_COMPOSE;
23855bc3cb74SMauro Carvalho Chehab 	else
23865b79da06SHans Verkuil 		s.target = V4L2_SEL_TGT_CROP;
23875bc3cb74SMauro Carvalho Chehab 
23888cbd94bdSHans Verkuil 	if (test_bit(V4L2_FL_QUIRK_INVERTED_CROP, &vfd->flags))
23898cbd94bdSHans Verkuil 		s.target = s.target == V4L2_SEL_TGT_COMPOSE ?
23908cbd94bdSHans Verkuil 			V4L2_SEL_TGT_CROP : V4L2_SEL_TGT_COMPOSE;
23918cbd94bdSHans Verkuil 
2392eaec420fSHans Verkuil 	ret = v4l_g_selection(ops, file, fh, &s);
23935bc3cb74SMauro Carvalho Chehab 
23945bc3cb74SMauro Carvalho Chehab 	/* copying results to old structure on success */
23955bc3cb74SMauro Carvalho Chehab 	if (!ret)
23965bc3cb74SMauro Carvalho Chehab 		p->c = s.r;
23975bc3cb74SMauro Carvalho Chehab 	return ret;
23985bc3cb74SMauro Carvalho Chehab }
23995bc3cb74SMauro Carvalho Chehab 
24005bc3cb74SMauro Carvalho Chehab static int v4l_s_crop(const struct v4l2_ioctl_ops *ops,
24015bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
24025bc3cb74SMauro Carvalho Chehab {
24038cbd94bdSHans Verkuil 	struct video_device *vfd = video_devdata(file);
24045bc3cb74SMauro Carvalho Chehab 	struct v4l2_crop *p = arg;
24055bc3cb74SMauro Carvalho Chehab 	struct v4l2_selection s = {
24065bc3cb74SMauro Carvalho Chehab 		.type = p->type,
24075bc3cb74SMauro Carvalho Chehab 		.r = p->c,
24085bc3cb74SMauro Carvalho Chehab 	};
24095bc3cb74SMauro Carvalho Chehab 
24105bc3cb74SMauro Carvalho Chehab 	/* simulate capture crop using selection api */
24115bc3cb74SMauro Carvalho Chehab 
24125bc3cb74SMauro Carvalho Chehab 	/* crop means compose for output devices */
24135bc3cb74SMauro Carvalho Chehab 	if (V4L2_TYPE_IS_OUTPUT(p->type))
24145b79da06SHans Verkuil 		s.target = V4L2_SEL_TGT_COMPOSE;
24155bc3cb74SMauro Carvalho Chehab 	else
24165b79da06SHans Verkuil 		s.target = V4L2_SEL_TGT_CROP;
24175bc3cb74SMauro Carvalho Chehab 
24188cbd94bdSHans Verkuil 	if (test_bit(V4L2_FL_QUIRK_INVERTED_CROP, &vfd->flags))
24198cbd94bdSHans Verkuil 		s.target = s.target == V4L2_SEL_TGT_COMPOSE ?
24208cbd94bdSHans Verkuil 			V4L2_SEL_TGT_CROP : V4L2_SEL_TGT_COMPOSE;
24218cbd94bdSHans Verkuil 
2422eaec420fSHans Verkuil 	return v4l_s_selection(ops, file, fh, &s);
24235bc3cb74SMauro Carvalho Chehab }
24245bc3cb74SMauro Carvalho Chehab 
24255bc3cb74SMauro Carvalho Chehab static int v4l_cropcap(const struct v4l2_ioctl_ops *ops,
24265bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
24275bc3cb74SMauro Carvalho Chehab {
24288cbd94bdSHans Verkuil 	struct video_device *vfd = video_devdata(file);
24295bc3cb74SMauro Carvalho Chehab 	struct v4l2_cropcap *p = arg;
24305bc3cb74SMauro Carvalho Chehab 	struct v4l2_selection s = { .type = p->type };
243195dd7b7eSHans Verkuil 	int ret = 0;
243295dd7b7eSHans Verkuil 
243395dd7b7eSHans Verkuil 	/* setting trivial pixelaspect */
243495dd7b7eSHans Verkuil 	p->pixelaspect.numerator = 1;
243595dd7b7eSHans Verkuil 	p->pixelaspect.denominator = 1;
243695dd7b7eSHans Verkuil 
24375200ab6aSHans Verkuil 	if (s.type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
24385200ab6aSHans Verkuil 		s.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
24395200ab6aSHans Verkuil 	else if (s.type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)
24405200ab6aSHans Verkuil 		s.type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
24415200ab6aSHans Verkuil 
244295dd7b7eSHans Verkuil 	/*
244395dd7b7eSHans Verkuil 	 * The determine_valid_ioctls() call already should ensure
244495dd7b7eSHans Verkuil 	 * that this can never happen, but just in case...
244595dd7b7eSHans Verkuil 	 */
24465200ab6aSHans Verkuil 	if (WARN_ON(!ops->vidioc_g_selection))
244795dd7b7eSHans Verkuil 		return -ENOTTY;
244895dd7b7eSHans Verkuil 
24495200ab6aSHans Verkuil 	if (ops->vidioc_g_pixelaspect)
24505200ab6aSHans Verkuil 		ret = ops->vidioc_g_pixelaspect(file, fh, s.type,
24515200ab6aSHans Verkuil 						&p->pixelaspect);
245295dd7b7eSHans Verkuil 
245395dd7b7eSHans Verkuil 	/*
245495dd7b7eSHans Verkuil 	 * Ignore ENOTTY or ENOIOCTLCMD error returns, just use the
245595dd7b7eSHans Verkuil 	 * square pixel aspect ratio in that case.
245695dd7b7eSHans Verkuil 	 */
245795dd7b7eSHans Verkuil 	if (ret && ret != -ENOTTY && ret != -ENOIOCTLCMD)
245895dd7b7eSHans Verkuil 		return ret;
245995dd7b7eSHans Verkuil 
246095dd7b7eSHans Verkuil 	/* Use g_selection() to fill in the bounds and defrect rectangles */
24615bc3cb74SMauro Carvalho Chehab 
24625bc3cb74SMauro Carvalho Chehab 	/* obtaining bounds */
24635bc3cb74SMauro Carvalho Chehab 	if (V4L2_TYPE_IS_OUTPUT(p->type))
24645bc3cb74SMauro Carvalho Chehab 		s.target = V4L2_SEL_TGT_COMPOSE_BOUNDS;
24655bc3cb74SMauro Carvalho Chehab 	else
24665bc3cb74SMauro Carvalho Chehab 		s.target = V4L2_SEL_TGT_CROP_BOUNDS;
24675bc3cb74SMauro Carvalho Chehab 
24688cbd94bdSHans Verkuil 	if (test_bit(V4L2_FL_QUIRK_INVERTED_CROP, &vfd->flags))
24698cbd94bdSHans Verkuil 		s.target = s.target == V4L2_SEL_TGT_COMPOSE_BOUNDS ?
24708cbd94bdSHans Verkuil 			V4L2_SEL_TGT_CROP_BOUNDS : V4L2_SEL_TGT_COMPOSE_BOUNDS;
24718cbd94bdSHans Verkuil 
2472eaec420fSHans Verkuil 	ret = v4l_g_selection(ops, file, fh, &s);
24735bc3cb74SMauro Carvalho Chehab 	if (ret)
24745bc3cb74SMauro Carvalho Chehab 		return ret;
24755bc3cb74SMauro Carvalho Chehab 	p->bounds = s.r;
24765bc3cb74SMauro Carvalho Chehab 
24775bc3cb74SMauro Carvalho Chehab 	/* obtaining defrect */
24788cbd94bdSHans Verkuil 	if (s.target == V4L2_SEL_TGT_COMPOSE_BOUNDS)
24795bc3cb74SMauro Carvalho Chehab 		s.target = V4L2_SEL_TGT_COMPOSE_DEFAULT;
24805bc3cb74SMauro Carvalho Chehab 	else
24815bc3cb74SMauro Carvalho Chehab 		s.target = V4L2_SEL_TGT_CROP_DEFAULT;
24825bc3cb74SMauro Carvalho Chehab 
2483eaec420fSHans Verkuil 	ret = v4l_g_selection(ops, file, fh, &s);
24845bc3cb74SMauro Carvalho Chehab 	if (ret)
24855bc3cb74SMauro Carvalho Chehab 		return ret;
24865bc3cb74SMauro Carvalho Chehab 	p->defrect = s.r;
24879409945cSHans Verkuil 
24885bc3cb74SMauro Carvalho Chehab 	return 0;
24895bc3cb74SMauro Carvalho Chehab }
24905bc3cb74SMauro Carvalho Chehab 
24915bc3cb74SMauro Carvalho Chehab static int v4l_log_status(const struct v4l2_ioctl_ops *ops,
24925bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
24935bc3cb74SMauro Carvalho Chehab {
24945bc3cb74SMauro Carvalho Chehab 	struct video_device *vfd = video_devdata(file);
24955bc3cb74SMauro Carvalho Chehab 	int ret;
24965bc3cb74SMauro Carvalho Chehab 
24975bc3cb74SMauro Carvalho Chehab 	if (vfd->v4l2_dev)
24985bc3cb74SMauro Carvalho Chehab 		pr_info("%s: =================  START STATUS  =================\n",
24995bc3cb74SMauro Carvalho Chehab 			vfd->v4l2_dev->name);
25005bc3cb74SMauro Carvalho Chehab 	ret = ops->vidioc_log_status(file, fh);
25015bc3cb74SMauro Carvalho Chehab 	if (vfd->v4l2_dev)
25025bc3cb74SMauro Carvalho Chehab 		pr_info("%s: ==================  END STATUS  ==================\n",
25035bc3cb74SMauro Carvalho Chehab 			vfd->v4l2_dev->name);
25045bc3cb74SMauro Carvalho Chehab 	return ret;
25055bc3cb74SMauro Carvalho Chehab }
25065bc3cb74SMauro Carvalho Chehab 
25075bc3cb74SMauro Carvalho Chehab static int v4l_dbg_g_register(const struct v4l2_ioctl_ops *ops,
25085bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
25095bc3cb74SMauro Carvalho Chehab {
25105bc3cb74SMauro Carvalho Chehab #ifdef CONFIG_VIDEO_ADV_DEBUG
25115bc3cb74SMauro Carvalho Chehab 	struct v4l2_dbg_register *p = arg;
251279b0c640SHans Verkuil 	struct video_device *vfd = video_devdata(file);
251379b0c640SHans Verkuil 	struct v4l2_subdev *sd;
251479b0c640SHans Verkuil 	int idx = 0;
25155bc3cb74SMauro Carvalho Chehab 
25165bc3cb74SMauro Carvalho Chehab 	if (!capable(CAP_SYS_ADMIN))
25175bc3cb74SMauro Carvalho Chehab 		return -EPERM;
25183eef2510SHans Verkuil 	if (p->match.type == V4L2_CHIP_MATCH_SUBDEV) {
251979b0c640SHans Verkuil 		if (vfd->v4l2_dev == NULL)
252079b0c640SHans Verkuil 			return -EINVAL;
25213eef2510SHans Verkuil 		v4l2_device_for_each_subdev(sd, vfd->v4l2_dev)
25223eef2510SHans Verkuil 			if (p->match.addr == idx++)
252379b0c640SHans Verkuil 				return v4l2_subdev_call(sd, core, g_register, p);
252479b0c640SHans Verkuil 		return -EINVAL;
252579b0c640SHans Verkuil 	}
2526191b79b0SHans Verkuil 	if (ops->vidioc_g_register && p->match.type == V4L2_CHIP_MATCH_BRIDGE &&
2527191b79b0SHans Verkuil 	    (ops->vidioc_g_chip_info || p->match.addr == 0))
25285bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_g_register(file, fh, p);
252979b0c640SHans Verkuil 	return -EINVAL;
25305bc3cb74SMauro Carvalho Chehab #else
25315bc3cb74SMauro Carvalho Chehab 	return -ENOTTY;
25325bc3cb74SMauro Carvalho Chehab #endif
25335bc3cb74SMauro Carvalho Chehab }
25345bc3cb74SMauro Carvalho Chehab 
25355bc3cb74SMauro Carvalho Chehab static int v4l_dbg_s_register(const struct v4l2_ioctl_ops *ops,
25365bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
25375bc3cb74SMauro Carvalho Chehab {
25385bc3cb74SMauro Carvalho Chehab #ifdef CONFIG_VIDEO_ADV_DEBUG
2539977ba3b1SHans Verkuil 	const struct v4l2_dbg_register *p = arg;
254079b0c640SHans Verkuil 	struct video_device *vfd = video_devdata(file);
254179b0c640SHans Verkuil 	struct v4l2_subdev *sd;
254279b0c640SHans Verkuil 	int idx = 0;
25435bc3cb74SMauro Carvalho Chehab 
25445bc3cb74SMauro Carvalho Chehab 	if (!capable(CAP_SYS_ADMIN))
25455bc3cb74SMauro Carvalho Chehab 		return -EPERM;
25463eef2510SHans Verkuil 	if (p->match.type == V4L2_CHIP_MATCH_SUBDEV) {
254779b0c640SHans Verkuil 		if (vfd->v4l2_dev == NULL)
254879b0c640SHans Verkuil 			return -EINVAL;
25493eef2510SHans Verkuil 		v4l2_device_for_each_subdev(sd, vfd->v4l2_dev)
25503eef2510SHans Verkuil 			if (p->match.addr == idx++)
255179b0c640SHans Verkuil 				return v4l2_subdev_call(sd, core, s_register, p);
255279b0c640SHans Verkuil 		return -EINVAL;
255379b0c640SHans Verkuil 	}
2554191b79b0SHans Verkuil 	if (ops->vidioc_s_register && p->match.type == V4L2_CHIP_MATCH_BRIDGE &&
2555191b79b0SHans Verkuil 	    (ops->vidioc_g_chip_info || p->match.addr == 0))
25565bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_s_register(file, fh, p);
255779b0c640SHans Verkuil 	return -EINVAL;
25585bc3cb74SMauro Carvalho Chehab #else
25595bc3cb74SMauro Carvalho Chehab 	return -ENOTTY;
25605bc3cb74SMauro Carvalho Chehab #endif
25615bc3cb74SMauro Carvalho Chehab }
25625bc3cb74SMauro Carvalho Chehab 
256396b03d2aSHans Verkuil static int v4l_dbg_g_chip_info(const struct v4l2_ioctl_ops *ops,
256479b0c640SHans Verkuil 				struct file *file, void *fh, void *arg)
256579b0c640SHans Verkuil {
2566cd634f1bSHans Verkuil #ifdef CONFIG_VIDEO_ADV_DEBUG
256779b0c640SHans Verkuil 	struct video_device *vfd = video_devdata(file);
256896b03d2aSHans Verkuil 	struct v4l2_dbg_chip_info *p = arg;
256979b0c640SHans Verkuil 	struct v4l2_subdev *sd;
257079b0c640SHans Verkuil 	int idx = 0;
257179b0c640SHans Verkuil 
257279b0c640SHans Verkuil 	switch (p->match.type) {
257379b0c640SHans Verkuil 	case V4L2_CHIP_MATCH_BRIDGE:
257479b0c640SHans Verkuil 		if (ops->vidioc_s_register)
257579b0c640SHans Verkuil 			p->flags |= V4L2_CHIP_FL_WRITABLE;
257679b0c640SHans Verkuil 		if (ops->vidioc_g_register)
257779b0c640SHans Verkuil 			p->flags |= V4L2_CHIP_FL_READABLE;
2578c0decac1SMauro Carvalho Chehab 		strscpy(p->name, vfd->v4l2_dev->name, sizeof(p->name));
257996b03d2aSHans Verkuil 		if (ops->vidioc_g_chip_info)
258096b03d2aSHans Verkuil 			return ops->vidioc_g_chip_info(file, fh, arg);
25810f0fe4b9SHans Verkuil 		if (p->match.addr)
25820f0fe4b9SHans Verkuil 			return -EINVAL;
258379b0c640SHans Verkuil 		return 0;
258479b0c640SHans Verkuil 
25853eef2510SHans Verkuil 	case V4L2_CHIP_MATCH_SUBDEV:
258679b0c640SHans Verkuil 		if (vfd->v4l2_dev == NULL)
258779b0c640SHans Verkuil 			break;
258879b0c640SHans Verkuil 		v4l2_device_for_each_subdev(sd, vfd->v4l2_dev) {
25893eef2510SHans Verkuil 			if (p->match.addr != idx++)
25903eef2510SHans Verkuil 				continue;
259179b0c640SHans Verkuil 			if (sd->ops->core && sd->ops->core->s_register)
259279b0c640SHans Verkuil 				p->flags |= V4L2_CHIP_FL_WRITABLE;
259379b0c640SHans Verkuil 			if (sd->ops->core && sd->ops->core->g_register)
259479b0c640SHans Verkuil 				p->flags |= V4L2_CHIP_FL_READABLE;
2595c0decac1SMauro Carvalho Chehab 			strscpy(p->name, sd->name, sizeof(p->name));
259679b0c640SHans Verkuil 			return 0;
259779b0c640SHans Verkuil 		}
259879b0c640SHans Verkuil 		break;
259979b0c640SHans Verkuil 	}
260079b0c640SHans Verkuil 	return -EINVAL;
2601cd634f1bSHans Verkuil #else
2602cd634f1bSHans Verkuil 	return -ENOTTY;
2603cd634f1bSHans Verkuil #endif
260479b0c640SHans Verkuil }
260579b0c640SHans Verkuil 
26065bc3cb74SMauro Carvalho Chehab static int v4l_dqevent(const struct v4l2_ioctl_ops *ops,
26075bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
26085bc3cb74SMauro Carvalho Chehab {
26095bc3cb74SMauro Carvalho Chehab 	return v4l2_event_dequeue(fh, arg, file->f_flags & O_NONBLOCK);
26105bc3cb74SMauro Carvalho Chehab }
26115bc3cb74SMauro Carvalho Chehab 
26125bc3cb74SMauro Carvalho Chehab static int v4l_subscribe_event(const struct v4l2_ioctl_ops *ops,
26135bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
26145bc3cb74SMauro Carvalho Chehab {
26155bc3cb74SMauro Carvalho Chehab 	return ops->vidioc_subscribe_event(fh, arg);
26165bc3cb74SMauro Carvalho Chehab }
26175bc3cb74SMauro Carvalho Chehab 
26185bc3cb74SMauro Carvalho Chehab static int v4l_unsubscribe_event(const struct v4l2_ioctl_ops *ops,
26195bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
26205bc3cb74SMauro Carvalho Chehab {
26215bc3cb74SMauro Carvalho Chehab 	return ops->vidioc_unsubscribe_event(fh, arg);
26225bc3cb74SMauro Carvalho Chehab }
26235bc3cb74SMauro Carvalho Chehab 
26245bc3cb74SMauro Carvalho Chehab static int v4l_g_sliced_vbi_cap(const struct v4l2_ioctl_ops *ops,
26255bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
26265bc3cb74SMauro Carvalho Chehab {
26275bc3cb74SMauro Carvalho Chehab 	struct v4l2_sliced_vbi_cap *p = arg;
26284b20259fSHans Verkuil 	int ret = check_fmt(file, p->type);
26294b20259fSHans Verkuil 
26304b20259fSHans Verkuil 	if (ret)
26314b20259fSHans Verkuil 		return ret;
26325bc3cb74SMauro Carvalho Chehab 
26335bc3cb74SMauro Carvalho Chehab 	/* Clear up to type, everything after type is zeroed already */
26345bc3cb74SMauro Carvalho Chehab 	memset(p, 0, offsetof(struct v4l2_sliced_vbi_cap, type));
26355bc3cb74SMauro Carvalho Chehab 
26365bc3cb74SMauro Carvalho Chehab 	return ops->vidioc_g_sliced_vbi_cap(file, fh, p);
26375bc3cb74SMauro Carvalho Chehab }
26385bc3cb74SMauro Carvalho Chehab 
26395bc3cb74SMauro Carvalho Chehab static int v4l_enum_freq_bands(const struct v4l2_ioctl_ops *ops,
26405bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
26415bc3cb74SMauro Carvalho Chehab {
26425bc3cb74SMauro Carvalho Chehab 	struct video_device *vfd = video_devdata(file);
26435bc3cb74SMauro Carvalho Chehab 	struct v4l2_frequency_band *p = arg;
26445bc3cb74SMauro Carvalho Chehab 	enum v4l2_tuner_type type;
26455bc3cb74SMauro Carvalho Chehab 	int err;
26465bc3cb74SMauro Carvalho Chehab 
264784099a28SAntti Palosaari 	if (vfd->vfl_type == VFL_TYPE_SDR) {
2648f3c3ececSAntti Palosaari 		if (p->type != V4L2_TUNER_SDR && p->type != V4L2_TUNER_RF)
264984099a28SAntti Palosaari 			return -EINVAL;
265084099a28SAntti Palosaari 		type = p->type;
265184099a28SAntti Palosaari 	} else {
26525bc3cb74SMauro Carvalho Chehab 		type = (vfd->vfl_type == VFL_TYPE_RADIO) ?
26535bc3cb74SMauro Carvalho Chehab 				V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV;
26545bc3cb74SMauro Carvalho Chehab 		if (type != p->type)
26555bc3cb74SMauro Carvalho Chehab 			return -EINVAL;
265684099a28SAntti Palosaari 	}
2657a7f404afSHans Verkuil 	if (ops->vidioc_enum_freq_bands) {
2658a7f404afSHans Verkuil 		err = ops->vidioc_enum_freq_bands(file, fh, p);
2659a7f404afSHans Verkuil 		if (err != -ENOTTY)
2660a7f404afSHans Verkuil 			return err;
2661a7f404afSHans Verkuil 	}
266273f35418SHans Verkuil 	if (is_valid_ioctl(vfd, VIDIOC_G_TUNER)) {
26635bc3cb74SMauro Carvalho Chehab 		struct v4l2_tuner t = {
26645bc3cb74SMauro Carvalho Chehab 			.index = p->tuner,
26655bc3cb74SMauro Carvalho Chehab 			.type = type,
26665bc3cb74SMauro Carvalho Chehab 		};
26675bc3cb74SMauro Carvalho Chehab 
266879e8c7beSMauro Carvalho Chehab 		if (p->index)
266979e8c7beSMauro Carvalho Chehab 			return -EINVAL;
26705bc3cb74SMauro Carvalho Chehab 		err = ops->vidioc_g_tuner(file, fh, &t);
26715bc3cb74SMauro Carvalho Chehab 		if (err)
26725bc3cb74SMauro Carvalho Chehab 			return err;
26735bc3cb74SMauro Carvalho Chehab 		p->capability = t.capability | V4L2_TUNER_CAP_FREQ_BANDS;
26745bc3cb74SMauro Carvalho Chehab 		p->rangelow = t.rangelow;
26755bc3cb74SMauro Carvalho Chehab 		p->rangehigh = t.rangehigh;
26765bc3cb74SMauro Carvalho Chehab 		p->modulation = (type == V4L2_TUNER_RADIO) ?
26775bc3cb74SMauro Carvalho Chehab 			V4L2_BAND_MODULATION_FM : V4L2_BAND_MODULATION_VSB;
26785bc3cb74SMauro Carvalho Chehab 		return 0;
26795bc3cb74SMauro Carvalho Chehab 	}
268073f35418SHans Verkuil 	if (is_valid_ioctl(vfd, VIDIOC_G_MODULATOR)) {
26815bc3cb74SMauro Carvalho Chehab 		struct v4l2_modulator m = {
26825bc3cb74SMauro Carvalho Chehab 			.index = p->tuner,
26835bc3cb74SMauro Carvalho Chehab 		};
26845bc3cb74SMauro Carvalho Chehab 
26855bc3cb74SMauro Carvalho Chehab 		if (type != V4L2_TUNER_RADIO)
26865bc3cb74SMauro Carvalho Chehab 			return -EINVAL;
268779e8c7beSMauro Carvalho Chehab 		if (p->index)
268879e8c7beSMauro Carvalho Chehab 			return -EINVAL;
26895bc3cb74SMauro Carvalho Chehab 		err = ops->vidioc_g_modulator(file, fh, &m);
26905bc3cb74SMauro Carvalho Chehab 		if (err)
26915bc3cb74SMauro Carvalho Chehab 			return err;
26925bc3cb74SMauro Carvalho Chehab 		p->capability = m.capability | V4L2_TUNER_CAP_FREQ_BANDS;
26935bc3cb74SMauro Carvalho Chehab 		p->rangelow = m.rangelow;
26945bc3cb74SMauro Carvalho Chehab 		p->rangehigh = m.rangehigh;
26955bc3cb74SMauro Carvalho Chehab 		p->modulation = (type == V4L2_TUNER_RADIO) ?
26965bc3cb74SMauro Carvalho Chehab 			V4L2_BAND_MODULATION_FM : V4L2_BAND_MODULATION_VSB;
26975bc3cb74SMauro Carvalho Chehab 		return 0;
26985bc3cb74SMauro Carvalho Chehab 	}
26995bc3cb74SMauro Carvalho Chehab 	return -ENOTTY;
27005bc3cb74SMauro Carvalho Chehab }
27015bc3cb74SMauro Carvalho Chehab 
27025bc3cb74SMauro Carvalho Chehab struct v4l2_ioctl_info {
27035bc3cb74SMauro Carvalho Chehab 	unsigned int ioctl;
27045bc3cb74SMauro Carvalho Chehab 	u32 flags;
27055bc3cb74SMauro Carvalho Chehab 	const char * const name;
27063ad3b7a2SSami Tolvanen 	int (*func)(const struct v4l2_ioctl_ops *ops, struct file *file,
27073ad3b7a2SSami Tolvanen 		    void *fh, void *p);
27085bc3cb74SMauro Carvalho Chehab 	void (*debug)(const void *arg, bool write_only);
27095bc3cb74SMauro Carvalho Chehab };
27105bc3cb74SMauro Carvalho Chehab 
27115bc3cb74SMauro Carvalho Chehab /* This control needs a priority check */
27125bc3cb74SMauro Carvalho Chehab #define INFO_FL_PRIO		(1 << 0)
27135bc3cb74SMauro Carvalho Chehab /* This control can be valid if the filehandle passes a control handler. */
27145bc3cb74SMauro Carvalho Chehab #define INFO_FL_CTRL		(1 << 1)
27155bc3cb74SMauro Carvalho Chehab /* Queuing ioctl */
27163ad3b7a2SSami Tolvanen #define INFO_FL_QUEUE		(1 << 2)
2717043f77edSHans Verkuil /* Always copy back result, even on error */
27183ad3b7a2SSami Tolvanen #define INFO_FL_ALWAYS_COPY	(1 << 3)
27195bc3cb74SMauro Carvalho Chehab /* Zero struct from after the field to the end */
27205bc3cb74SMauro Carvalho Chehab #define INFO_FL_CLEAR(v4l2_struct, field)			\
27215bc3cb74SMauro Carvalho Chehab 	((offsetof(struct v4l2_struct, field) +			\
2722c593642cSPankaj Bharadiya 	  sizeof_field(struct v4l2_struct, field)) << 16)
27235bc3cb74SMauro Carvalho Chehab #define INFO_FL_CLEAR_MASK	(_IOC_SIZEMASK << 16)
27245bc3cb74SMauro Carvalho Chehab 
27253ad3b7a2SSami Tolvanen #define DEFINE_V4L_STUB_FUNC(_vidioc)				\
27263ad3b7a2SSami Tolvanen 	static int v4l_stub_ ## _vidioc(			\
27273ad3b7a2SSami Tolvanen 			const struct v4l2_ioctl_ops *ops,	\
27283ad3b7a2SSami Tolvanen 			struct file *file, void *fh, void *p)	\
27293ad3b7a2SSami Tolvanen 	{							\
27303ad3b7a2SSami Tolvanen 		return ops->vidioc_ ## _vidioc(file, fh, p);	\
27313ad3b7a2SSami Tolvanen 	}
27323ad3b7a2SSami Tolvanen 
27333ad3b7a2SSami Tolvanen #define IOCTL_INFO(_ioctl, _func, _debug, _flags)		\
27345bc3cb74SMauro Carvalho Chehab 	[_IOC_NR(_ioctl)] = {					\
27355bc3cb74SMauro Carvalho Chehab 		.ioctl = _ioctl,				\
27363ad3b7a2SSami Tolvanen 		.flags = _flags,				\
27375bc3cb74SMauro Carvalho Chehab 		.name = #_ioctl,				\
27383ad3b7a2SSami Tolvanen 		.func = _func,					\
27395bc3cb74SMauro Carvalho Chehab 		.debug = _debug,				\
27405bc3cb74SMauro Carvalho Chehab 	}
27415bc3cb74SMauro Carvalho Chehab 
27423ad3b7a2SSami Tolvanen DEFINE_V4L_STUB_FUNC(g_fbuf)
27433ad3b7a2SSami Tolvanen DEFINE_V4L_STUB_FUNC(s_fbuf)
27443ad3b7a2SSami Tolvanen DEFINE_V4L_STUB_FUNC(expbuf)
27453ad3b7a2SSami Tolvanen DEFINE_V4L_STUB_FUNC(g_std)
27463ad3b7a2SSami Tolvanen DEFINE_V4L_STUB_FUNC(g_audio)
27473ad3b7a2SSami Tolvanen DEFINE_V4L_STUB_FUNC(s_audio)
27483ad3b7a2SSami Tolvanen DEFINE_V4L_STUB_FUNC(g_edid)
27493ad3b7a2SSami Tolvanen DEFINE_V4L_STUB_FUNC(s_edid)
27503ad3b7a2SSami Tolvanen DEFINE_V4L_STUB_FUNC(g_audout)
27513ad3b7a2SSami Tolvanen DEFINE_V4L_STUB_FUNC(s_audout)
27523ad3b7a2SSami Tolvanen DEFINE_V4L_STUB_FUNC(g_jpegcomp)
27533ad3b7a2SSami Tolvanen DEFINE_V4L_STUB_FUNC(s_jpegcomp)
27543ad3b7a2SSami Tolvanen DEFINE_V4L_STUB_FUNC(enumaudio)
27553ad3b7a2SSami Tolvanen DEFINE_V4L_STUB_FUNC(enumaudout)
27563ad3b7a2SSami Tolvanen DEFINE_V4L_STUB_FUNC(enum_framesizes)
27573ad3b7a2SSami Tolvanen DEFINE_V4L_STUB_FUNC(enum_frameintervals)
27583ad3b7a2SSami Tolvanen DEFINE_V4L_STUB_FUNC(g_enc_index)
27593ad3b7a2SSami Tolvanen DEFINE_V4L_STUB_FUNC(encoder_cmd)
27603ad3b7a2SSami Tolvanen DEFINE_V4L_STUB_FUNC(try_encoder_cmd)
27613ad3b7a2SSami Tolvanen DEFINE_V4L_STUB_FUNC(decoder_cmd)
27623ad3b7a2SSami Tolvanen DEFINE_V4L_STUB_FUNC(try_decoder_cmd)
27633ad3b7a2SSami Tolvanen DEFINE_V4L_STUB_FUNC(s_dv_timings)
27643ad3b7a2SSami Tolvanen DEFINE_V4L_STUB_FUNC(g_dv_timings)
27653ad3b7a2SSami Tolvanen DEFINE_V4L_STUB_FUNC(enum_dv_timings)
27663ad3b7a2SSami Tolvanen DEFINE_V4L_STUB_FUNC(query_dv_timings)
27673ad3b7a2SSami Tolvanen DEFINE_V4L_STUB_FUNC(dv_timings_cap)
27685bc3cb74SMauro Carvalho Chehab 
27697c91d0a4SEric Biggers static const struct v4l2_ioctl_info v4l2_ioctls[] = {
27703ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_QUERYCAP, v4l_querycap, v4l_print_querycap, 0),
2771e5b6b07aSLaurent Pinchart 	IOCTL_INFO(VIDIOC_ENUM_FMT, v4l_enum_fmt, v4l_print_fmtdesc, 0),
27723ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_G_FMT, v4l_g_fmt, v4l_print_format, 0),
27733ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_S_FMT, v4l_s_fmt, v4l_print_format, INFO_FL_PRIO),
27743ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_REQBUFS, v4l_reqbufs, v4l_print_requestbuffers, INFO_FL_PRIO | INFO_FL_QUEUE),
27753ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_QUERYBUF, v4l_querybuf, v4l_print_buffer, INFO_FL_QUEUE | INFO_FL_CLEAR(v4l2_buffer, length)),
27763ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_G_FBUF, v4l_stub_g_fbuf, v4l_print_framebuffer, 0),
27773ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_S_FBUF, v4l_stub_s_fbuf, v4l_print_framebuffer, INFO_FL_PRIO),
27783ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_OVERLAY, v4l_overlay, v4l_print_u32, INFO_FL_PRIO),
27793ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_QBUF, v4l_qbuf, v4l_print_buffer, INFO_FL_QUEUE),
27803ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_EXPBUF, v4l_stub_expbuf, v4l_print_exportbuffer, INFO_FL_QUEUE | INFO_FL_CLEAR(v4l2_exportbuffer, flags)),
27813ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_DQBUF, v4l_dqbuf, v4l_print_buffer, INFO_FL_QUEUE),
27823ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_STREAMON, v4l_streamon, v4l_print_buftype, INFO_FL_PRIO | INFO_FL_QUEUE),
27833ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_STREAMOFF, v4l_streamoff, v4l_print_buftype, INFO_FL_PRIO | INFO_FL_QUEUE),
27843ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_G_PARM, v4l_g_parm, v4l_print_streamparm, INFO_FL_CLEAR(v4l2_streamparm, type)),
27853ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_S_PARM, v4l_s_parm, v4l_print_streamparm, INFO_FL_PRIO),
27863ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_G_STD, v4l_stub_g_std, v4l_print_std, 0),
27873ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_S_STD, v4l_s_std, v4l_print_std, INFO_FL_PRIO),
27883ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_ENUMSTD, v4l_enumstd, v4l_print_standard, INFO_FL_CLEAR(v4l2_standard, index)),
27893ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_ENUMINPUT, v4l_enuminput, v4l_print_enuminput, INFO_FL_CLEAR(v4l2_input, index)),
27903ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_G_CTRL, v4l_g_ctrl, v4l_print_control, INFO_FL_CTRL | INFO_FL_CLEAR(v4l2_control, id)),
27913ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_S_CTRL, v4l_s_ctrl, v4l_print_control, INFO_FL_PRIO | INFO_FL_CTRL),
27923ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_G_TUNER, v4l_g_tuner, v4l_print_tuner, INFO_FL_CLEAR(v4l2_tuner, index)),
27933ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_S_TUNER, v4l_s_tuner, v4l_print_tuner, INFO_FL_PRIO),
27943ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_G_AUDIO, v4l_stub_g_audio, v4l_print_audio, 0),
27953ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_S_AUDIO, v4l_stub_s_audio, v4l_print_audio, INFO_FL_PRIO),
27963ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_QUERYCTRL, v4l_queryctrl, v4l_print_queryctrl, INFO_FL_CTRL | INFO_FL_CLEAR(v4l2_queryctrl, id)),
27973ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_QUERYMENU, v4l_querymenu, v4l_print_querymenu, INFO_FL_CTRL | INFO_FL_CLEAR(v4l2_querymenu, index)),
2798f645e625SNiklas Söderlund 	IOCTL_INFO(VIDIOC_G_INPUT, v4l_g_input, v4l_print_u32, 0),
27993ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_S_INPUT, v4l_s_input, v4l_print_u32, INFO_FL_PRIO),
28003ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_G_EDID, v4l_stub_g_edid, v4l_print_edid, INFO_FL_ALWAYS_COPY),
28013ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_S_EDID, v4l_stub_s_edid, v4l_print_edid, INFO_FL_PRIO | INFO_FL_ALWAYS_COPY),
2802f645e625SNiklas Söderlund 	IOCTL_INFO(VIDIOC_G_OUTPUT, v4l_g_output, v4l_print_u32, 0),
28033ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_S_OUTPUT, v4l_s_output, v4l_print_u32, INFO_FL_PRIO),
28043ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_ENUMOUTPUT, v4l_enumoutput, v4l_print_enumoutput, INFO_FL_CLEAR(v4l2_output, index)),
28053ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_G_AUDOUT, v4l_stub_g_audout, v4l_print_audioout, 0),
28063ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_S_AUDOUT, v4l_stub_s_audout, v4l_print_audioout, INFO_FL_PRIO),
28073ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_G_MODULATOR, v4l_g_modulator, v4l_print_modulator, INFO_FL_CLEAR(v4l2_modulator, index)),
28083ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_S_MODULATOR, v4l_s_modulator, v4l_print_modulator, INFO_FL_PRIO),
28093ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_G_FREQUENCY, v4l_g_frequency, v4l_print_frequency, INFO_FL_CLEAR(v4l2_frequency, tuner)),
28103ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_S_FREQUENCY, v4l_s_frequency, v4l_print_frequency, INFO_FL_PRIO),
28113ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_CROPCAP, v4l_cropcap, v4l_print_cropcap, INFO_FL_CLEAR(v4l2_cropcap, type)),
28123ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_G_CROP, v4l_g_crop, v4l_print_crop, INFO_FL_CLEAR(v4l2_crop, type)),
28133ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_S_CROP, v4l_s_crop, v4l_print_crop, INFO_FL_PRIO),
28143ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_G_SELECTION, v4l_g_selection, v4l_print_selection, INFO_FL_CLEAR(v4l2_selection, r)),
28153ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_S_SELECTION, v4l_s_selection, v4l_print_selection, INFO_FL_PRIO | INFO_FL_CLEAR(v4l2_selection, r)),
28163ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_G_JPEGCOMP, v4l_stub_g_jpegcomp, v4l_print_jpegcompression, 0),
28173ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_S_JPEGCOMP, v4l_stub_s_jpegcomp, v4l_print_jpegcompression, INFO_FL_PRIO),
28183ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_QUERYSTD, v4l_querystd, v4l_print_std, 0),
28193ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_TRY_FMT, v4l_try_fmt, v4l_print_format, 0),
28203ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_ENUMAUDIO, v4l_stub_enumaudio, v4l_print_audio, INFO_FL_CLEAR(v4l2_audio, index)),
28213ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_ENUMAUDOUT, v4l_stub_enumaudout, v4l_print_audioout, INFO_FL_CLEAR(v4l2_audioout, index)),
28223ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_G_PRIORITY, v4l_g_priority, v4l_print_u32, 0),
28233ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_S_PRIORITY, v4l_s_priority, v4l_print_u32, INFO_FL_PRIO),
28243ad3b7a2SSami 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)),
28253ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_LOG_STATUS, v4l_log_status, v4l_print_newline, 0),
28263ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_G_EXT_CTRLS, v4l_g_ext_ctrls, v4l_print_ext_controls, INFO_FL_CTRL),
28273ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_S_EXT_CTRLS, v4l_s_ext_ctrls, v4l_print_ext_controls, INFO_FL_PRIO | INFO_FL_CTRL),
28283ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_TRY_EXT_CTRLS, v4l_try_ext_ctrls, v4l_print_ext_controls, INFO_FL_CTRL),
28293ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_ENUM_FRAMESIZES, v4l_stub_enum_framesizes, v4l_print_frmsizeenum, INFO_FL_CLEAR(v4l2_frmsizeenum, pixel_format)),
28303ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_ENUM_FRAMEINTERVALS, v4l_stub_enum_frameintervals, v4l_print_frmivalenum, INFO_FL_CLEAR(v4l2_frmivalenum, height)),
28313ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_G_ENC_INDEX, v4l_stub_g_enc_index, v4l_print_enc_idx, 0),
28323ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_ENCODER_CMD, v4l_stub_encoder_cmd, v4l_print_encoder_cmd, INFO_FL_PRIO | INFO_FL_CLEAR(v4l2_encoder_cmd, flags)),
28333ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_TRY_ENCODER_CMD, v4l_stub_try_encoder_cmd, v4l_print_encoder_cmd, INFO_FL_CLEAR(v4l2_encoder_cmd, flags)),
28343ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_DECODER_CMD, v4l_stub_decoder_cmd, v4l_print_decoder_cmd, INFO_FL_PRIO),
28353ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_TRY_DECODER_CMD, v4l_stub_try_decoder_cmd, v4l_print_decoder_cmd, 0),
28363ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_DBG_S_REGISTER, v4l_dbg_s_register, v4l_print_dbg_register, 0),
28373ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_DBG_G_REGISTER, v4l_dbg_g_register, v4l_print_dbg_register, 0),
28383ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_S_HW_FREQ_SEEK, v4l_s_hw_freq_seek, v4l_print_hw_freq_seek, INFO_FL_PRIO),
28393ad3b7a2SSami 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)),
28403ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_G_DV_TIMINGS, v4l_stub_g_dv_timings, v4l_print_dv_timings, 0),
28413ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_DQEVENT, v4l_dqevent, v4l_print_event, 0),
28423ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_SUBSCRIBE_EVENT, v4l_subscribe_event, v4l_print_event_subscription, 0),
28433ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_UNSUBSCRIBE_EVENT, v4l_unsubscribe_event, v4l_print_event_subscription, 0),
28443ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_CREATE_BUFS, v4l_create_bufs, v4l_print_create_buffers, INFO_FL_PRIO | INFO_FL_QUEUE),
28453ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_PREPARE_BUF, v4l_prepare_buf, v4l_print_buffer, INFO_FL_QUEUE),
28463ad3b7a2SSami 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)),
28473ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_QUERY_DV_TIMINGS, v4l_stub_query_dv_timings, v4l_print_dv_timings, INFO_FL_ALWAYS_COPY),
28483ad3b7a2SSami 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)),
28493ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_ENUM_FREQ_BANDS, v4l_enum_freq_bands, v4l_print_freq_band, 0),
28503ad3b7a2SSami 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)),
28513ad3b7a2SSami 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)),
28525bc3cb74SMauro Carvalho Chehab };
28535bc3cb74SMauro Carvalho Chehab #define V4L2_IOCTLS ARRAY_SIZE(v4l2_ioctls)
28545bc3cb74SMauro Carvalho Chehab 
285573a11062SHans Verkuil static bool v4l2_is_known_ioctl(unsigned int cmd)
28565bc3cb74SMauro Carvalho Chehab {
28575bc3cb74SMauro Carvalho Chehab 	if (_IOC_NR(cmd) >= V4L2_IOCTLS)
28585bc3cb74SMauro Carvalho Chehab 		return false;
28595bc3cb74SMauro Carvalho Chehab 	return v4l2_ioctls[_IOC_NR(cmd)].ioctl == cmd;
28605bc3cb74SMauro Carvalho Chehab }
28615bc3cb74SMauro Carvalho Chehab 
286273a11062SHans Verkuil static struct mutex *v4l2_ioctl_get_lock(struct video_device *vdev,
2863d862bc08SHans Verkuil 					 struct v4l2_fh *vfh, unsigned int cmd,
2864d862bc08SHans Verkuil 					 void *arg)
28655bc3cb74SMauro Carvalho Chehab {
28665bc3cb74SMauro Carvalho Chehab 	if (_IOC_NR(cmd) >= V4L2_IOCTLS)
28675bc3cb74SMauro Carvalho Chehab 		return vdev->lock;
2868d862bc08SHans Verkuil 	if (vfh && vfh->m2m_ctx &&
2869d862bc08SHans Verkuil 	    (v4l2_ioctls[_IOC_NR(cmd)].flags & INFO_FL_QUEUE)) {
2870542a522dSEzequiel Garcia 		if (vfh->m2m_ctx->q_lock)
2871542a522dSEzequiel Garcia 			return vfh->m2m_ctx->q_lock;
2872d862bc08SHans Verkuil 	}
28735bc3cb74SMauro Carvalho Chehab 	if (vdev->queue && vdev->queue->lock &&
28745bc3cb74SMauro Carvalho Chehab 			(v4l2_ioctls[_IOC_NR(cmd)].flags & INFO_FL_QUEUE))
28755bc3cb74SMauro Carvalho Chehab 		return vdev->queue->lock;
28765bc3cb74SMauro Carvalho Chehab 	return vdev->lock;
28775bc3cb74SMauro Carvalho Chehab }
28785bc3cb74SMauro Carvalho Chehab 
28795bc3cb74SMauro Carvalho Chehab /* Common ioctl debug function. This function can be used by
28805bc3cb74SMauro Carvalho Chehab    external ioctl messages as well as internal V4L ioctl */
28815bc3cb74SMauro Carvalho Chehab void v4l_printk_ioctl(const char *prefix, unsigned int cmd)
28825bc3cb74SMauro Carvalho Chehab {
28835bc3cb74SMauro Carvalho Chehab 	const char *dir, *type;
28845bc3cb74SMauro Carvalho Chehab 
28855bc3cb74SMauro Carvalho Chehab 	if (prefix)
28865bc3cb74SMauro Carvalho Chehab 		printk(KERN_DEBUG "%s: ", prefix);
28875bc3cb74SMauro Carvalho Chehab 
28885bc3cb74SMauro Carvalho Chehab 	switch (_IOC_TYPE(cmd)) {
28895bc3cb74SMauro Carvalho Chehab 	case 'd':
28905bc3cb74SMauro Carvalho Chehab 		type = "v4l2_int";
28915bc3cb74SMauro Carvalho Chehab 		break;
28925bc3cb74SMauro Carvalho Chehab 	case 'V':
28935bc3cb74SMauro Carvalho Chehab 		if (_IOC_NR(cmd) >= V4L2_IOCTLS) {
28945bc3cb74SMauro Carvalho Chehab 			type = "v4l2";
28955bc3cb74SMauro Carvalho Chehab 			break;
28965bc3cb74SMauro Carvalho Chehab 		}
28975bc3cb74SMauro Carvalho Chehab 		pr_cont("%s", v4l2_ioctls[_IOC_NR(cmd)].name);
28985bc3cb74SMauro Carvalho Chehab 		return;
28995bc3cb74SMauro Carvalho Chehab 	default:
29005bc3cb74SMauro Carvalho Chehab 		type = "unknown";
29015bc3cb74SMauro Carvalho Chehab 		break;
29025bc3cb74SMauro Carvalho Chehab 	}
29035bc3cb74SMauro Carvalho Chehab 
29045bc3cb74SMauro Carvalho Chehab 	switch (_IOC_DIR(cmd)) {
29055bc3cb74SMauro Carvalho Chehab 	case _IOC_NONE:              dir = "--"; break;
29065bc3cb74SMauro Carvalho Chehab 	case _IOC_READ:              dir = "r-"; break;
29075bc3cb74SMauro Carvalho Chehab 	case _IOC_WRITE:             dir = "-w"; break;
29085bc3cb74SMauro Carvalho Chehab 	case _IOC_READ | _IOC_WRITE: dir = "rw"; break;
29095bc3cb74SMauro Carvalho Chehab 	default:                     dir = "*ERR*"; break;
29105bc3cb74SMauro Carvalho Chehab 	}
29115bc3cb74SMauro Carvalho Chehab 	pr_cont("%s ioctl '%c', dir=%s, #%d (0x%08x)",
29125bc3cb74SMauro Carvalho Chehab 		type, _IOC_TYPE(cmd), dir, _IOC_NR(cmd), cmd);
29135bc3cb74SMauro Carvalho Chehab }
29145bc3cb74SMauro Carvalho Chehab EXPORT_SYMBOL(v4l_printk_ioctl);
29155bc3cb74SMauro Carvalho Chehab 
29165bc3cb74SMauro Carvalho Chehab static long __video_do_ioctl(struct file *file,
29175bc3cb74SMauro Carvalho Chehab 		unsigned int cmd, void *arg)
29185bc3cb74SMauro Carvalho Chehab {
29195bc3cb74SMauro Carvalho Chehab 	struct video_device *vfd = video_devdata(file);
2920cc6eddcdSHans Verkuil 	struct mutex *req_queue_lock = NULL;
292173a11062SHans Verkuil 	struct mutex *lock; /* ioctl serialization mutex */
29225bc3cb74SMauro Carvalho Chehab 	const struct v4l2_ioctl_ops *ops = vfd->ioctl_ops;
29235bc3cb74SMauro Carvalho Chehab 	bool write_only = false;
29245bc3cb74SMauro Carvalho Chehab 	struct v4l2_ioctl_info default_info;
29255bc3cb74SMauro Carvalho Chehab 	const struct v4l2_ioctl_info *info;
29265bc3cb74SMauro Carvalho Chehab 	void *fh = file->private_data;
29275bc3cb74SMauro Carvalho Chehab 	struct v4l2_fh *vfh = NULL;
292817028cdbSHans Verkuil 	int dev_debug = vfd->dev_debug;
29295bc3cb74SMauro Carvalho Chehab 	long ret = -ENOTTY;
29305bc3cb74SMauro Carvalho Chehab 
29315bc3cb74SMauro Carvalho Chehab 	if (ops == NULL) {
29325bc3cb74SMauro Carvalho Chehab 		pr_warn("%s: has no ioctl_ops.\n",
29335bc3cb74SMauro Carvalho Chehab 				video_device_node_name(vfd));
29345bc3cb74SMauro Carvalho Chehab 		return ret;
29355bc3cb74SMauro Carvalho Chehab 	}
29365bc3cb74SMauro Carvalho Chehab 
2937b7284bb0SRamakrishnan Muthukrishnan 	if (test_bit(V4L2_FL_USES_V4L2_FH, &vfd->flags))
29385bc3cb74SMauro Carvalho Chehab 		vfh = file->private_data;
29395bc3cb74SMauro Carvalho Chehab 
2940cc6eddcdSHans Verkuil 	/*
2941cc6eddcdSHans Verkuil 	 * We need to serialize streamon/off with queueing new requests.
2942cc6eddcdSHans Verkuil 	 * These ioctls may trigger the cancellation of a streaming
2943cc6eddcdSHans Verkuil 	 * operation, and that should not be mixed with queueing a new
2944cc6eddcdSHans Verkuil 	 * request at the same time.
2945cc6eddcdSHans Verkuil 	 */
2946cc6eddcdSHans Verkuil 	if (v4l2_device_supports_requests(vfd->v4l2_dev) &&
2947cc6eddcdSHans Verkuil 	    (cmd == VIDIOC_STREAMON || cmd == VIDIOC_STREAMOFF)) {
2948cc6eddcdSHans Verkuil 		req_queue_lock = &vfd->v4l2_dev->mdev->req_queue_mutex;
2949cc6eddcdSHans Verkuil 
2950cc6eddcdSHans Verkuil 		if (mutex_lock_interruptible(req_queue_lock))
2951cc6eddcdSHans Verkuil 			return -ERESTARTSYS;
2952cc6eddcdSHans Verkuil 	}
2953cc6eddcdSHans Verkuil 
2954d862bc08SHans Verkuil 	lock = v4l2_ioctl_get_lock(vfd, vfh, cmd, arg);
295573a11062SHans Verkuil 
2956cc6eddcdSHans Verkuil 	if (lock && mutex_lock_interruptible(lock)) {
2957cc6eddcdSHans Verkuil 		if (req_queue_lock)
2958cc6eddcdSHans Verkuil 			mutex_unlock(req_queue_lock);
295973a11062SHans Verkuil 		return -ERESTARTSYS;
2960cc6eddcdSHans Verkuil 	}
296173a11062SHans Verkuil 
296273a11062SHans Verkuil 	if (!video_is_registered(vfd)) {
296373a11062SHans Verkuil 		ret = -ENODEV;
296473a11062SHans Verkuil 		goto unlock;
296573a11062SHans Verkuil 	}
296673a11062SHans Verkuil 
29675bc3cb74SMauro Carvalho Chehab 	if (v4l2_is_known_ioctl(cmd)) {
29685bc3cb74SMauro Carvalho Chehab 		info = &v4l2_ioctls[_IOC_NR(cmd)];
29695bc3cb74SMauro Carvalho Chehab 
29705bc3cb74SMauro Carvalho Chehab 		if (!test_bit(_IOC_NR(cmd), vfd->valid_ioctls) &&
29715bc3cb74SMauro Carvalho Chehab 		    !((info->flags & INFO_FL_CTRL) && vfh && vfh->ctrl_handler))
29725bc3cb74SMauro Carvalho Chehab 			goto done;
29735bc3cb74SMauro Carvalho Chehab 
2974b7284bb0SRamakrishnan Muthukrishnan 		if (vfh && (info->flags & INFO_FL_PRIO)) {
29755bc3cb74SMauro Carvalho Chehab 			ret = v4l2_prio_check(vfd->prio, vfh->prio);
29765bc3cb74SMauro Carvalho Chehab 			if (ret)
29775bc3cb74SMauro Carvalho Chehab 				goto done;
29785bc3cb74SMauro Carvalho Chehab 		}
29795bc3cb74SMauro Carvalho Chehab 	} else {
29805bc3cb74SMauro Carvalho Chehab 		default_info.ioctl = cmd;
29815bc3cb74SMauro Carvalho Chehab 		default_info.flags = 0;
29825bc3cb74SMauro Carvalho Chehab 		default_info.debug = v4l_print_default;
29835bc3cb74SMauro Carvalho Chehab 		info = &default_info;
29845bc3cb74SMauro Carvalho Chehab 	}
29855bc3cb74SMauro Carvalho Chehab 
29865bc3cb74SMauro Carvalho Chehab 	write_only = _IOC_DIR(cmd) == _IOC_WRITE;
29873ad3b7a2SSami Tolvanen 	if (info != &default_info) {
29883ad3b7a2SSami Tolvanen 		ret = info->func(ops, file, fh, arg);
29895bc3cb74SMauro Carvalho Chehab 	} else if (!ops->vidioc_default) {
29905bc3cb74SMauro Carvalho Chehab 		ret = -ENOTTY;
29915bc3cb74SMauro Carvalho Chehab 	} else {
29925bc3cb74SMauro Carvalho Chehab 		ret = ops->vidioc_default(file, fh,
2993b7284bb0SRamakrishnan Muthukrishnan 			vfh ? v4l2_prio_check(vfd->prio, vfh->prio) >= 0 : 0,
29945bc3cb74SMauro Carvalho Chehab 			cmd, arg);
29955bc3cb74SMauro Carvalho Chehab 	}
29965bc3cb74SMauro Carvalho Chehab 
29975bc3cb74SMauro Carvalho Chehab done:
299817028cdbSHans Verkuil 	if (dev_debug & (V4L2_DEV_DEBUG_IOCTL | V4L2_DEV_DEBUG_IOCTL_ARG)) {
299917028cdbSHans Verkuil 		if (!(dev_debug & V4L2_DEV_DEBUG_STREAMING) &&
300017028cdbSHans Verkuil 		    (cmd == VIDIOC_QBUF || cmd == VIDIOC_DQBUF))
30015983d3bcSHans Verkuil 			goto unlock;
300217028cdbSHans Verkuil 
30035bc3cb74SMauro Carvalho Chehab 		v4l_printk_ioctl(video_device_node_name(vfd), cmd);
30045bc3cb74SMauro Carvalho Chehab 		if (ret < 0)
3005505d04bdSHans Verkuil 			pr_cont(": error %ld", ret);
300617028cdbSHans Verkuil 		if (!(dev_debug & V4L2_DEV_DEBUG_IOCTL_ARG))
30075bc3cb74SMauro Carvalho Chehab 			pr_cont("\n");
30085bc3cb74SMauro Carvalho Chehab 		else if (_IOC_DIR(cmd) == _IOC_NONE)
30095bc3cb74SMauro Carvalho Chehab 			info->debug(arg, write_only);
30105bc3cb74SMauro Carvalho Chehab 		else {
30115bc3cb74SMauro Carvalho Chehab 			pr_cont(": ");
30125bc3cb74SMauro Carvalho Chehab 			info->debug(arg, write_only);
30135bc3cb74SMauro Carvalho Chehab 		}
30145bc3cb74SMauro Carvalho Chehab 	}
30155bc3cb74SMauro Carvalho Chehab 
301673a11062SHans Verkuil unlock:
301773a11062SHans Verkuil 	if (lock)
301873a11062SHans Verkuil 		mutex_unlock(lock);
3019cc6eddcdSHans Verkuil 	if (req_queue_lock)
3020cc6eddcdSHans Verkuil 		mutex_unlock(req_queue_lock);
30215bc3cb74SMauro Carvalho Chehab 	return ret;
30225bc3cb74SMauro Carvalho Chehab }
30235bc3cb74SMauro Carvalho Chehab 
30245bc3cb74SMauro Carvalho Chehab static int check_array_args(unsigned int cmd, void *parg, size_t *array_size,
3025ba2d35c1SHans Verkuil 			    void __user **user_ptr, void ***kernel_ptr)
30265bc3cb74SMauro Carvalho Chehab {
30275bc3cb74SMauro Carvalho Chehab 	int ret = 0;
30285bc3cb74SMauro Carvalho Chehab 
30295bc3cb74SMauro Carvalho Chehab 	switch (cmd) {
303096b1a702SHans Verkuil 	case VIDIOC_PREPARE_BUF:
30315bc3cb74SMauro Carvalho Chehab 	case VIDIOC_QUERYBUF:
30325bc3cb74SMauro Carvalho Chehab 	case VIDIOC_QBUF:
30335bc3cb74SMauro Carvalho Chehab 	case VIDIOC_DQBUF: {
30345bc3cb74SMauro Carvalho Chehab 		struct v4l2_buffer *buf = parg;
30355bc3cb74SMauro Carvalho Chehab 
30365bc3cb74SMauro Carvalho Chehab 		if (V4L2_TYPE_IS_MULTIPLANAR(buf->type) && buf->length > 0) {
30375bc3cb74SMauro Carvalho Chehab 			if (buf->length > VIDEO_MAX_PLANES) {
30385bc3cb74SMauro Carvalho Chehab 				ret = -EINVAL;
30395bc3cb74SMauro Carvalho Chehab 				break;
30405bc3cb74SMauro Carvalho Chehab 			}
30415bc3cb74SMauro Carvalho Chehab 			*user_ptr = (void __user *)buf->m.planes;
3042ba2d35c1SHans Verkuil 			*kernel_ptr = (void **)&buf->m.planes;
30435bc3cb74SMauro Carvalho Chehab 			*array_size = sizeof(struct v4l2_plane) * buf->length;
30445bc3cb74SMauro Carvalho Chehab 			ret = 1;
30455bc3cb74SMauro Carvalho Chehab 		}
30465bc3cb74SMauro Carvalho Chehab 		break;
30475bc3cb74SMauro Carvalho Chehab 	}
30485bc3cb74SMauro Carvalho Chehab 
3049dd519bb3SHans Verkuil 	case VIDIOC_G_EDID:
3050dd519bb3SHans Verkuil 	case VIDIOC_S_EDID: {
3051dd519bb3SHans Verkuil 		struct v4l2_edid *edid = parg;
3052ed45ce2cSHans Verkuil 
3053ed45ce2cSHans Verkuil 		if (edid->blocks) {
30541b8b10ccSHans Verkuil 			if (edid->blocks > 256) {
30551b8b10ccSHans Verkuil 				ret = -EINVAL;
30561b8b10ccSHans Verkuil 				break;
30571b8b10ccSHans Verkuil 			}
3058ed45ce2cSHans Verkuil 			*user_ptr = (void __user *)edid->edid;
3059ba2d35c1SHans Verkuil 			*kernel_ptr = (void **)&edid->edid;
3060ed45ce2cSHans Verkuil 			*array_size = edid->blocks * 128;
3061ed45ce2cSHans Verkuil 			ret = 1;
3062ed45ce2cSHans Verkuil 		}
3063ed45ce2cSHans Verkuil 		break;
3064ed45ce2cSHans Verkuil 	}
3065ed45ce2cSHans Verkuil 
30665bc3cb74SMauro Carvalho Chehab 	case VIDIOC_S_EXT_CTRLS:
30675bc3cb74SMauro Carvalho Chehab 	case VIDIOC_G_EXT_CTRLS:
30685bc3cb74SMauro Carvalho Chehab 	case VIDIOC_TRY_EXT_CTRLS: {
30695bc3cb74SMauro Carvalho Chehab 		struct v4l2_ext_controls *ctrls = parg;
30705bc3cb74SMauro Carvalho Chehab 
30715bc3cb74SMauro Carvalho Chehab 		if (ctrls->count != 0) {
30725bc3cb74SMauro Carvalho Chehab 			if (ctrls->count > V4L2_CID_MAX_CTRLS) {
30735bc3cb74SMauro Carvalho Chehab 				ret = -EINVAL;
30745bc3cb74SMauro Carvalho Chehab 				break;
30755bc3cb74SMauro Carvalho Chehab 			}
30765bc3cb74SMauro Carvalho Chehab 			*user_ptr = (void __user *)ctrls->controls;
3077ba2d35c1SHans Verkuil 			*kernel_ptr = (void **)&ctrls->controls;
30785bc3cb74SMauro Carvalho Chehab 			*array_size = sizeof(struct v4l2_ext_control)
30795bc3cb74SMauro Carvalho Chehab 				    * ctrls->count;
30805bc3cb74SMauro Carvalho Chehab 			ret = 1;
30815bc3cb74SMauro Carvalho Chehab 		}
30825bc3cb74SMauro Carvalho Chehab 		break;
30835bc3cb74SMauro Carvalho Chehab 	}
30843f65c6f6SArnd Bergmann 	case VIDIOC_G_FMT:
30853f65c6f6SArnd Bergmann 	case VIDIOC_S_FMT:
30863f65c6f6SArnd Bergmann 	case VIDIOC_TRY_FMT: {
30873f65c6f6SArnd Bergmann 		struct v4l2_format *fmt = parg;
30883f65c6f6SArnd Bergmann 
30893f65c6f6SArnd Bergmann 		if (fmt->type != V4L2_BUF_TYPE_VIDEO_OVERLAY &&
30903f65c6f6SArnd Bergmann 		    fmt->type != V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY)
30913f65c6f6SArnd Bergmann 			break;
30923f65c6f6SArnd Bergmann 		if (fmt->fmt.win.clipcount > 2048)
30933f65c6f6SArnd Bergmann 			return -EINVAL;
30943f65c6f6SArnd Bergmann 		if (!fmt->fmt.win.clipcount)
30953f65c6f6SArnd Bergmann 			break;
30963f65c6f6SArnd Bergmann 
30973f65c6f6SArnd Bergmann 		*user_ptr = (void __user *)fmt->fmt.win.clips;
30983f65c6f6SArnd Bergmann 		*kernel_ptr = (void **)&fmt->fmt.win.clips;
30993f65c6f6SArnd Bergmann 		*array_size = sizeof(struct v4l2_clip)
31003f65c6f6SArnd Bergmann 				* fmt->fmt.win.clipcount;
31013f65c6f6SArnd Bergmann 
31023f65c6f6SArnd Bergmann 		ret = 1;
31033f65c6f6SArnd Bergmann 		break;
31043f65c6f6SArnd Bergmann 	}
31055bc3cb74SMauro Carvalho Chehab 	}
31065bc3cb74SMauro Carvalho Chehab 
31075bc3cb74SMauro Carvalho Chehab 	return ret;
31085bc3cb74SMauro Carvalho Chehab }
31095bc3cb74SMauro Carvalho Chehab 
3110c8ef1a60SArnd Bergmann static unsigned int video_translate_cmd(unsigned int cmd)
3111c8ef1a60SArnd Bergmann {
3112c344f07aSArnd Bergmann #if !defined(CONFIG_64BIT) && defined(CONFIG_COMPAT_32BIT_TIME)
31131a6c0b36SArnd Bergmann 	switch (cmd) {
31141a6c0b36SArnd Bergmann 	case VIDIOC_DQEVENT_TIME32:
31151a6c0b36SArnd Bergmann 		return VIDIOC_DQEVENT;
3116577c89b0SArnd Bergmann 	case VIDIOC_QUERYBUF_TIME32:
3117577c89b0SArnd Bergmann 		return VIDIOC_QUERYBUF;
3118577c89b0SArnd Bergmann 	case VIDIOC_QBUF_TIME32:
3119577c89b0SArnd Bergmann 		return VIDIOC_QBUF;
3120577c89b0SArnd Bergmann 	case VIDIOC_DQBUF_TIME32:
3121577c89b0SArnd Bergmann 		return VIDIOC_DQBUF;
3122577c89b0SArnd Bergmann 	case VIDIOC_PREPARE_BUF_TIME32:
3123577c89b0SArnd Bergmann 		return VIDIOC_PREPARE_BUF;
31241a6c0b36SArnd Bergmann 	}
3125c344f07aSArnd Bergmann #endif
31268dbcc3faSArnd Bergmann 	if (in_compat_syscall())
31278dbcc3faSArnd Bergmann 		return v4l2_compat_translate_cmd(cmd);
31281a6c0b36SArnd Bergmann 
3129c8ef1a60SArnd Bergmann 	return cmd;
3130c8ef1a60SArnd Bergmann }
3131c8ef1a60SArnd Bergmann 
31328dbcc3faSArnd Bergmann static int video_get_user(void __user *arg, void *parg,
31338dbcc3faSArnd Bergmann 			  unsigned int real_cmd, unsigned int cmd,
3134c8ef1a60SArnd Bergmann 			  bool *always_copy)
3135c8ef1a60SArnd Bergmann {
31368dbcc3faSArnd Bergmann 	unsigned int n = _IOC_SIZE(real_cmd);
31378dbcc3faSArnd Bergmann 	int err = 0;
3138c8ef1a60SArnd Bergmann 
3139c8ef1a60SArnd Bergmann 	if (!(_IOC_DIR(cmd) & _IOC_WRITE)) {
3140c8ef1a60SArnd Bergmann 		/* read-only ioctl */
3141c8ef1a60SArnd Bergmann 		memset(parg, 0, n);
3142c8ef1a60SArnd Bergmann 		return 0;
3143c8ef1a60SArnd Bergmann 	}
3144c8ef1a60SArnd Bergmann 
31458dbcc3faSArnd Bergmann 	/*
31468dbcc3faSArnd Bergmann 	 * In some cases, only a few fields are used as input,
31478dbcc3faSArnd Bergmann 	 * i.e. when the app sets "index" and then the driver
31488dbcc3faSArnd Bergmann 	 * fills in the rest of the structure for the thing
31498dbcc3faSArnd Bergmann 	 * with that index.  We only need to copy up the first
31508dbcc3faSArnd Bergmann 	 * non-input field.
31518dbcc3faSArnd Bergmann 	 */
31528dbcc3faSArnd Bergmann 	if (v4l2_is_known_ioctl(real_cmd)) {
31538dbcc3faSArnd Bergmann 		u32 flags = v4l2_ioctls[_IOC_NR(real_cmd)].flags;
31548dbcc3faSArnd Bergmann 
31558dbcc3faSArnd Bergmann 		if (flags & INFO_FL_CLEAR_MASK)
31568dbcc3faSArnd Bergmann 			n = (flags & INFO_FL_CLEAR_MASK) >> 16;
31578dbcc3faSArnd Bergmann 		*always_copy = flags & INFO_FL_ALWAYS_COPY;
31588dbcc3faSArnd Bergmann 	}
31598dbcc3faSArnd Bergmann 
31608dbcc3faSArnd Bergmann 	if (cmd == real_cmd) {
31618dbcc3faSArnd Bergmann 		if (copy_from_user(parg, (void __user *)arg, n))
31628dbcc3faSArnd Bergmann 			err = -EFAULT;
31638dbcc3faSArnd Bergmann 	} else if (in_compat_syscall()) {
31647b53cca7SArnd Bergmann 		memset(parg, 0, n);
31658dbcc3faSArnd Bergmann 		err = v4l2_compat_get_user(arg, parg, cmd);
31668dbcc3faSArnd Bergmann 	} else {
31677b53cca7SArnd Bergmann 		memset(parg, 0, n);
3168c344f07aSArnd Bergmann #if !defined(CONFIG_64BIT) && defined(CONFIG_COMPAT_32BIT_TIME)
3169c8ef1a60SArnd Bergmann 		switch (cmd) {
3170577c89b0SArnd Bergmann 		case VIDIOC_QUERYBUF_TIME32:
3171577c89b0SArnd Bergmann 		case VIDIOC_QBUF_TIME32:
3172577c89b0SArnd Bergmann 		case VIDIOC_DQBUF_TIME32:
3173577c89b0SArnd Bergmann 		case VIDIOC_PREPARE_BUF_TIME32: {
3174577c89b0SArnd Bergmann 			struct v4l2_buffer_time32 vb32;
3175577c89b0SArnd Bergmann 			struct v4l2_buffer *vb = parg;
3176577c89b0SArnd Bergmann 
3177577c89b0SArnd Bergmann 			if (copy_from_user(&vb32, arg, sizeof(vb32)))
3178577c89b0SArnd Bergmann 				return -EFAULT;
3179577c89b0SArnd Bergmann 
3180577c89b0SArnd Bergmann 			*vb = (struct v4l2_buffer) {
3181577c89b0SArnd Bergmann 				.index		= vb32.index,
3182577c89b0SArnd Bergmann 				.type		= vb32.type,
3183577c89b0SArnd Bergmann 				.bytesused	= vb32.bytesused,
3184577c89b0SArnd Bergmann 				.flags		= vb32.flags,
3185577c89b0SArnd Bergmann 				.field		= vb32.field,
3186577c89b0SArnd Bergmann 				.timestamp.tv_sec	= vb32.timestamp.tv_sec,
3187577c89b0SArnd Bergmann 				.timestamp.tv_usec	= vb32.timestamp.tv_usec,
3188577c89b0SArnd Bergmann 				.timecode	= vb32.timecode,
3189577c89b0SArnd Bergmann 				.sequence	= vb32.sequence,
3190577c89b0SArnd Bergmann 				.memory		= vb32.memory,
3191577c89b0SArnd Bergmann 				.m.userptr	= vb32.m.userptr,
3192577c89b0SArnd Bergmann 				.length		= vb32.length,
3193577c89b0SArnd Bergmann 				.request_fd	= vb32.request_fd,
3194577c89b0SArnd Bergmann 			};
3195577c89b0SArnd Bergmann 			break;
3196577c89b0SArnd Bergmann 		}
3197c8ef1a60SArnd Bergmann 		}
3198c344f07aSArnd Bergmann #endif
31998dbcc3faSArnd Bergmann 	}
3200c8ef1a60SArnd Bergmann 
3201c8ef1a60SArnd Bergmann 	/* zero out anything we don't copy from userspace */
32028dbcc3faSArnd Bergmann 	if (!err && n < _IOC_SIZE(real_cmd))
32038dbcc3faSArnd Bergmann 		memset((u8 *)parg + n, 0, _IOC_SIZE(real_cmd) - n);
32048dbcc3faSArnd Bergmann 	return err;
3205c8ef1a60SArnd Bergmann }
3206c8ef1a60SArnd Bergmann 
32078dbcc3faSArnd Bergmann static int video_put_user(void __user *arg, void *parg,
32088dbcc3faSArnd Bergmann 			  unsigned int real_cmd, unsigned int cmd)
3209c8ef1a60SArnd Bergmann {
3210c8ef1a60SArnd Bergmann 	if (!(_IOC_DIR(cmd) & _IOC_READ))
3211c8ef1a60SArnd Bergmann 		return 0;
3212c8ef1a60SArnd Bergmann 
32138dbcc3faSArnd Bergmann 	if (cmd == real_cmd) {
32148dbcc3faSArnd Bergmann 		/*  Copy results into user buffer  */
32158dbcc3faSArnd Bergmann 		if (copy_to_user(arg, parg, _IOC_SIZE(cmd)))
32168dbcc3faSArnd Bergmann 			return -EFAULT;
32178dbcc3faSArnd Bergmann 		return 0;
32188dbcc3faSArnd Bergmann 	}
32198dbcc3faSArnd Bergmann 
32208dbcc3faSArnd Bergmann 	if (in_compat_syscall())
32218dbcc3faSArnd Bergmann 		return v4l2_compat_put_user(arg, parg, cmd);
32228dbcc3faSArnd Bergmann 
3223c344f07aSArnd Bergmann #if !defined(CONFIG_64BIT) && defined(CONFIG_COMPAT_32BIT_TIME)
3224c8ef1a60SArnd Bergmann 	switch (cmd) {
32251a6c0b36SArnd Bergmann 	case VIDIOC_DQEVENT_TIME32: {
32261a6c0b36SArnd Bergmann 		struct v4l2_event *ev = parg;
32274ffb879eSPeilin Ye 		struct v4l2_event_time32 ev32;
32284ffb879eSPeilin Ye 
32294ffb879eSPeilin Ye 		memset(&ev32, 0, sizeof(ev32));
32304ffb879eSPeilin Ye 
32314ffb879eSPeilin Ye 		ev32.type	= ev->type;
32324ffb879eSPeilin Ye 		ev32.pending	= ev->pending;
32334ffb879eSPeilin Ye 		ev32.sequence	= ev->sequence;
32344ffb879eSPeilin Ye 		ev32.timestamp.tv_sec	= ev->timestamp.tv_sec;
32354ffb879eSPeilin Ye 		ev32.timestamp.tv_nsec	= ev->timestamp.tv_nsec;
32364ffb879eSPeilin Ye 		ev32.id		= ev->id;
32371a6c0b36SArnd Bergmann 
32381a6c0b36SArnd Bergmann 		memcpy(&ev32.u, &ev->u, sizeof(ev->u));
32391a6c0b36SArnd Bergmann 		memcpy(&ev32.reserved, &ev->reserved, sizeof(ev->reserved));
32401a6c0b36SArnd Bergmann 
32411a6c0b36SArnd Bergmann 		if (copy_to_user(arg, &ev32, sizeof(ev32)))
32421a6c0b36SArnd Bergmann 			return -EFAULT;
32431a6c0b36SArnd Bergmann 		break;
32441a6c0b36SArnd Bergmann 	}
3245577c89b0SArnd Bergmann 	case VIDIOC_QUERYBUF_TIME32:
3246577c89b0SArnd Bergmann 	case VIDIOC_QBUF_TIME32:
3247577c89b0SArnd Bergmann 	case VIDIOC_DQBUF_TIME32:
3248577c89b0SArnd Bergmann 	case VIDIOC_PREPARE_BUF_TIME32: {
3249577c89b0SArnd Bergmann 		struct v4l2_buffer *vb = parg;
32504ffb879eSPeilin Ye 		struct v4l2_buffer_time32 vb32;
32514ffb879eSPeilin Ye 
32524ffb879eSPeilin Ye 		memset(&vb32, 0, sizeof(vb32));
32534ffb879eSPeilin Ye 
32544ffb879eSPeilin Ye 		vb32.index	= vb->index;
32554ffb879eSPeilin Ye 		vb32.type	= vb->type;
32564ffb879eSPeilin Ye 		vb32.bytesused	= vb->bytesused;
32574ffb879eSPeilin Ye 		vb32.flags	= vb->flags;
32584ffb879eSPeilin Ye 		vb32.field	= vb->field;
32594ffb879eSPeilin Ye 		vb32.timestamp.tv_sec	= vb->timestamp.tv_sec;
32604ffb879eSPeilin Ye 		vb32.timestamp.tv_usec	= vb->timestamp.tv_usec;
32614ffb879eSPeilin Ye 		vb32.timecode	= vb->timecode;
32624ffb879eSPeilin Ye 		vb32.sequence	= vb->sequence;
32634ffb879eSPeilin Ye 		vb32.memory	= vb->memory;
32644ffb879eSPeilin Ye 		vb32.m.userptr	= vb->m.userptr;
32654ffb879eSPeilin Ye 		vb32.length	= vb->length;
32664ffb879eSPeilin Ye 		vb32.request_fd	= vb->request_fd;
3267577c89b0SArnd Bergmann 
3268577c89b0SArnd Bergmann 		if (copy_to_user(arg, &vb32, sizeof(vb32)))
3269577c89b0SArnd Bergmann 			return -EFAULT;
3270577c89b0SArnd Bergmann 		break;
3271577c89b0SArnd Bergmann 	}
3272c8ef1a60SArnd Bergmann 	}
3273c344f07aSArnd Bergmann #endif
3274c8ef1a60SArnd Bergmann 
3275c8ef1a60SArnd Bergmann 	return 0;
3276c8ef1a60SArnd Bergmann }
3277c8ef1a60SArnd Bergmann 
32785bc3cb74SMauro Carvalho Chehab long
3279c8ef1a60SArnd Bergmann video_usercopy(struct file *file, unsigned int orig_cmd, unsigned long arg,
32805bc3cb74SMauro Carvalho Chehab 	       v4l2_kioctl func)
32815bc3cb74SMauro Carvalho Chehab {
32825bc3cb74SMauro Carvalho Chehab 	char	sbuf[128];
3283fb18802aSSakari Ailus 	void    *mbuf = NULL, *array_buf = NULL;
32845bc3cb74SMauro Carvalho Chehab 	void	*parg = (void *)arg;
32855bc3cb74SMauro Carvalho Chehab 	long	err  = -EINVAL;
32865bc3cb74SMauro Carvalho Chehab 	bool	has_array_args;
3287043f77edSHans Verkuil 	bool	always_copy = false;
32885bc3cb74SMauro Carvalho Chehab 	size_t  array_size = 0;
32895bc3cb74SMauro Carvalho Chehab 	void __user *user_ptr = NULL;
32905bc3cb74SMauro Carvalho Chehab 	void	**kernel_ptr = NULL;
3291c8ef1a60SArnd Bergmann 	unsigned int cmd = video_translate_cmd(orig_cmd);
3292f8a695c4SMauro Carvalho Chehab 	const size_t ioc_size = _IOC_SIZE(cmd);
32935bc3cb74SMauro Carvalho Chehab 
32945bc3cb74SMauro Carvalho Chehab 	/*  Copy arguments into temp kernel buffer  */
32955bc3cb74SMauro Carvalho Chehab 	if (_IOC_DIR(cmd) != _IOC_NONE) {
3296f8a695c4SMauro Carvalho Chehab 		if (ioc_size <= sizeof(sbuf)) {
32975bc3cb74SMauro Carvalho Chehab 			parg = sbuf;
32985bc3cb74SMauro Carvalho Chehab 		} else {
32995bc3cb74SMauro Carvalho Chehab 			/* too big to allocate from stack */
330062a12551SSakari Ailus 			mbuf = kmalloc(ioc_size, GFP_KERNEL);
33015bc3cb74SMauro Carvalho Chehab 			if (NULL == mbuf)
33025bc3cb74SMauro Carvalho Chehab 				return -ENOMEM;
33035bc3cb74SMauro Carvalho Chehab 			parg = mbuf;
33045bc3cb74SMauro Carvalho Chehab 		}
33055bc3cb74SMauro Carvalho Chehab 
33068dbcc3faSArnd Bergmann 		err = video_get_user((void __user *)arg, parg, cmd,
33078dbcc3faSArnd Bergmann 				     orig_cmd, &always_copy);
3308c8ef1a60SArnd Bergmann 		if (err)
33095bc3cb74SMauro Carvalho Chehab 			goto out;
33101dc8b65cSArnd Bergmann 	}
33115bc3cb74SMauro Carvalho Chehab 
33125bc3cb74SMauro Carvalho Chehab 	err = check_array_args(cmd, parg, &array_size, &user_ptr, &kernel_ptr);
33135bc3cb74SMauro Carvalho Chehab 	if (err < 0)
33145bc3cb74SMauro Carvalho Chehab 		goto out;
33155bc3cb74SMauro Carvalho Chehab 	has_array_args = err;
33165bc3cb74SMauro Carvalho Chehab 
33175bc3cb74SMauro Carvalho Chehab 	if (has_array_args) {
3318fb18802aSSakari Ailus 		array_buf = kvmalloc(array_size, GFP_KERNEL);
33195bc3cb74SMauro Carvalho Chehab 		err = -ENOMEM;
3320fb18802aSSakari Ailus 		if (array_buf == NULL)
33215bc3cb74SMauro Carvalho Chehab 			goto out_array_args;
33225bc3cb74SMauro Carvalho Chehab 		err = -EFAULT;
33238dbcc3faSArnd Bergmann 		if (in_compat_syscall())
3324fb18802aSSakari Ailus 			err = v4l2_compat_get_array_args(file, array_buf,
3325fb18802aSSakari Ailus 							 user_ptr, array_size,
3326fb18802aSSakari Ailus 							 orig_cmd, parg);
33278dbcc3faSArnd Bergmann 		else
3328fb18802aSSakari Ailus 			err = copy_from_user(array_buf, user_ptr, array_size) ?
33298dbcc3faSArnd Bergmann 								-EFAULT : 0;
33308dbcc3faSArnd Bergmann 		if (err)
33315bc3cb74SMauro Carvalho Chehab 			goto out_array_args;
3332fb18802aSSakari Ailus 		*kernel_ptr = array_buf;
33335bc3cb74SMauro Carvalho Chehab 	}
33345bc3cb74SMauro Carvalho Chehab 
33355bc3cb74SMauro Carvalho Chehab 	/* Handles IOCTL */
33365bc3cb74SMauro Carvalho Chehab 	err = func(file, cmd, parg);
3337181a4a2dSHans Verkuil 	if (err == -ENOTTY || err == -ENOIOCTLCMD) {
33385bc3cb74SMauro Carvalho Chehab 		err = -ENOTTY;
3339181a4a2dSHans Verkuil 		goto out;
3340181a4a2dSHans Verkuil 	}
3341181a4a2dSHans Verkuil 
3342aa32f4c0SHans Verkuil 	if (err == 0) {
3343aa32f4c0SHans Verkuil 		if (cmd == VIDIOC_DQBUF)
3344aa32f4c0SHans Verkuil 			trace_v4l2_dqbuf(video_devdata(file)->minor, parg);
3345aa32f4c0SHans Verkuil 		else if (cmd == VIDIOC_QBUF)
3346aa32f4c0SHans Verkuil 			trace_v4l2_qbuf(video_devdata(file)->minor, parg);
3347aa32f4c0SHans Verkuil 	}
33485bc3cb74SMauro Carvalho Chehab 
33495bc3cb74SMauro Carvalho Chehab 	if (has_array_args) {
3350ba2d35c1SHans Verkuil 		*kernel_ptr = (void __force *)user_ptr;
33518dbcc3faSArnd Bergmann 		if (in_compat_syscall()) {
33528dbcc3faSArnd Bergmann 			int put_err;
33538dbcc3faSArnd Bergmann 
3354fb18802aSSakari Ailus 			put_err = v4l2_compat_put_array_args(file, user_ptr,
3355fb18802aSSakari Ailus 							     array_buf,
3356fb18802aSSakari Ailus 							     array_size,
3357fb18802aSSakari Ailus 							     orig_cmd, parg);
33588dbcc3faSArnd Bergmann 			if (put_err)
33598dbcc3faSArnd Bergmann 				err = put_err;
3360fb18802aSSakari Ailus 		} else if (copy_to_user(user_ptr, array_buf, array_size)) {
33615bc3cb74SMauro Carvalho Chehab 			err = -EFAULT;
33628dbcc3faSArnd Bergmann 		}
33635bc3cb74SMauro Carvalho Chehab 		goto out_array_args;
33645bc3cb74SMauro Carvalho Chehab 	}
3365043f77edSHans Verkuil 	/*
3366043f77edSHans Verkuil 	 * Some ioctls can return an error, but still have valid
3367043f77edSHans Verkuil 	 * results that must be returned.
3368043f77edSHans Verkuil 	 */
3369043f77edSHans Verkuil 	if (err < 0 && !always_copy)
33705bc3cb74SMauro Carvalho Chehab 		goto out;
33715bc3cb74SMauro Carvalho Chehab 
33725bc3cb74SMauro Carvalho Chehab out_array_args:
33738dbcc3faSArnd Bergmann 	if (video_put_user((void __user *)arg, parg, cmd, orig_cmd))
33745bc3cb74SMauro Carvalho Chehab 		err = -EFAULT;
33755bc3cb74SMauro Carvalho Chehab out:
3376fb18802aSSakari Ailus 	kvfree(array_buf);
337762a12551SSakari Ailus 	kfree(mbuf);
33785bc3cb74SMauro Carvalho Chehab 	return err;
33795bc3cb74SMauro Carvalho Chehab }
33805bc3cb74SMauro Carvalho Chehab 
33815bc3cb74SMauro Carvalho Chehab long video_ioctl2(struct file *file,
33825bc3cb74SMauro Carvalho Chehab 	       unsigned int cmd, unsigned long arg)
33835bc3cb74SMauro Carvalho Chehab {
33845bc3cb74SMauro Carvalho Chehab 	return video_usercopy(file, cmd, arg, __video_do_ioctl);
33855bc3cb74SMauro Carvalho Chehab }
33865bc3cb74SMauro Carvalho Chehab EXPORT_SYMBOL(video_ioctl2);
3387