12874c5fdSThomas Gleixner // SPDX-License-Identifier: GPL-2.0-or-later
25bc3cb74SMauro Carvalho Chehab /*
35bc3cb74SMauro Carvalho Chehab  * Video capture interface for Linux version 2
45bc3cb74SMauro Carvalho Chehab  *
55bc3cb74SMauro Carvalho Chehab  * A generic framework to process V4L2 ioctl commands.
65bc3cb74SMauro Carvalho Chehab  *
75bc3cb74SMauro Carvalho Chehab  * Authors:	Alan Cox, <alan@lxorguk.ukuu.org.uk> (version 1)
832590819SMauro Carvalho Chehab  *              Mauro Carvalho Chehab <mchehab@kernel.org> (version 2)
95bc3cb74SMauro Carvalho Chehab  */
105bc3cb74SMauro Carvalho Chehab 
118dbcc3faSArnd Bergmann #include <linux/compat.h>
12758d90e1STomasz Figa #include <linux/mm.h>
135bc3cb74SMauro Carvalho Chehab #include <linux/module.h>
145bc3cb74SMauro Carvalho Chehab #include <linux/slab.h>
155bc3cb74SMauro Carvalho Chehab #include <linux/types.h>
165bc3cb74SMauro Carvalho Chehab #include <linux/kernel.h>
175bc3cb74SMauro Carvalho Chehab #include <linux/version.h>
185bc3cb74SMauro Carvalho Chehab 
195bc3cb74SMauro Carvalho Chehab #include <linux/videodev2.h>
205bc3cb74SMauro Carvalho Chehab 
215bc3cb74SMauro Carvalho Chehab #include <media/v4l2-common.h>
225bc3cb74SMauro Carvalho Chehab #include <media/v4l2-ioctl.h>
235bc3cb74SMauro Carvalho Chehab #include <media/v4l2-ctrls.h>
245bc3cb74SMauro Carvalho Chehab #include <media/v4l2-fh.h>
255bc3cb74SMauro Carvalho Chehab #include <media/v4l2-event.h>
265bc3cb74SMauro Carvalho Chehab #include <media/v4l2-device.h>
27c139990eSJunghak Sung #include <media/videobuf2-v4l2.h>
2877fa4e07SShuah Khan #include <media/v4l2-mc.h>
29d862bc08SHans Verkuil #include <media/v4l2-mem2mem.h>
305bc3cb74SMauro Carvalho Chehab 
31aa32f4c0SHans Verkuil #include <trace/events/v4l2.h>
32aa32f4c0SHans Verkuil 
335bc3cb74SMauro Carvalho Chehab /* Zero out the end of the struct pointed to by p.  Everything after, but
345bc3cb74SMauro Carvalho Chehab  * not including, the specified field is cleared. */
355bc3cb74SMauro Carvalho Chehab #define CLEAR_AFTER_FIELD(p, field) \
365bc3cb74SMauro Carvalho Chehab 	memset((u8 *)(p) + offsetof(typeof(*(p)), field) + sizeof((p)->field), \
375bc3cb74SMauro Carvalho Chehab 	0, sizeof(*(p)) - offsetof(typeof(*(p)), field) - sizeof((p)->field))
385bc3cb74SMauro Carvalho Chehab 
3973f35418SHans Verkuil #define is_valid_ioctl(vfd, cmd) test_bit(_IOC_NR(cmd), (vfd)->valid_ioctls)
4073f35418SHans Verkuil 
415bc3cb74SMauro Carvalho Chehab struct std_descr {
425bc3cb74SMauro Carvalho Chehab 	v4l2_std_id std;
435bc3cb74SMauro Carvalho Chehab 	const char *descr;
445bc3cb74SMauro Carvalho Chehab };
455bc3cb74SMauro Carvalho Chehab 
465bc3cb74SMauro Carvalho Chehab static const struct std_descr standards[] = {
475bc3cb74SMauro Carvalho Chehab 	{ V4L2_STD_NTSC,	"NTSC"      },
485bc3cb74SMauro Carvalho Chehab 	{ V4L2_STD_NTSC_M,	"NTSC-M"    },
495bc3cb74SMauro Carvalho Chehab 	{ V4L2_STD_NTSC_M_JP,	"NTSC-M-JP" },
505bc3cb74SMauro Carvalho Chehab 	{ V4L2_STD_NTSC_M_KR,	"NTSC-M-KR" },
515bc3cb74SMauro Carvalho Chehab 	{ V4L2_STD_NTSC_443,	"NTSC-443"  },
525bc3cb74SMauro Carvalho Chehab 	{ V4L2_STD_PAL,		"PAL"       },
535bc3cb74SMauro Carvalho Chehab 	{ V4L2_STD_PAL_BG,	"PAL-BG"    },
545bc3cb74SMauro Carvalho Chehab 	{ V4L2_STD_PAL_B,	"PAL-B"     },
555bc3cb74SMauro Carvalho Chehab 	{ V4L2_STD_PAL_B1,	"PAL-B1"    },
565bc3cb74SMauro Carvalho Chehab 	{ V4L2_STD_PAL_G,	"PAL-G"     },
575bc3cb74SMauro Carvalho Chehab 	{ V4L2_STD_PAL_H,	"PAL-H"     },
585bc3cb74SMauro Carvalho Chehab 	{ V4L2_STD_PAL_I,	"PAL-I"     },
595bc3cb74SMauro Carvalho Chehab 	{ V4L2_STD_PAL_DK,	"PAL-DK"    },
605bc3cb74SMauro Carvalho Chehab 	{ V4L2_STD_PAL_D,	"PAL-D"     },
615bc3cb74SMauro Carvalho Chehab 	{ V4L2_STD_PAL_D1,	"PAL-D1"    },
625bc3cb74SMauro Carvalho Chehab 	{ V4L2_STD_PAL_K,	"PAL-K"     },
635bc3cb74SMauro Carvalho Chehab 	{ V4L2_STD_PAL_M,	"PAL-M"     },
645bc3cb74SMauro Carvalho Chehab 	{ V4L2_STD_PAL_N,	"PAL-N"     },
655bc3cb74SMauro Carvalho Chehab 	{ V4L2_STD_PAL_Nc,	"PAL-Nc"    },
665bc3cb74SMauro Carvalho Chehab 	{ V4L2_STD_PAL_60,	"PAL-60"    },
675bc3cb74SMauro Carvalho Chehab 	{ V4L2_STD_SECAM,	"SECAM"     },
685bc3cb74SMauro Carvalho Chehab 	{ V4L2_STD_SECAM_B,	"SECAM-B"   },
695bc3cb74SMauro Carvalho Chehab 	{ V4L2_STD_SECAM_G,	"SECAM-G"   },
705bc3cb74SMauro Carvalho Chehab 	{ V4L2_STD_SECAM_H,	"SECAM-H"   },
715bc3cb74SMauro Carvalho Chehab 	{ V4L2_STD_SECAM_DK,	"SECAM-DK"  },
725bc3cb74SMauro Carvalho Chehab 	{ V4L2_STD_SECAM_D,	"SECAM-D"   },
735bc3cb74SMauro Carvalho Chehab 	{ V4L2_STD_SECAM_K,	"SECAM-K"   },
745bc3cb74SMauro Carvalho Chehab 	{ V4L2_STD_SECAM_K1,	"SECAM-K1"  },
755bc3cb74SMauro Carvalho Chehab 	{ V4L2_STD_SECAM_L,	"SECAM-L"   },
765bc3cb74SMauro Carvalho Chehab 	{ V4L2_STD_SECAM_LC,	"SECAM-Lc"  },
775bc3cb74SMauro Carvalho Chehab 	{ 0,			"Unknown"   }
785bc3cb74SMauro Carvalho Chehab };
795bc3cb74SMauro Carvalho Chehab 
805bc3cb74SMauro Carvalho Chehab /* video4linux standard ID conversion to standard name
815bc3cb74SMauro Carvalho Chehab  */
825bc3cb74SMauro Carvalho Chehab const char *v4l2_norm_to_name(v4l2_std_id id)
835bc3cb74SMauro Carvalho Chehab {
845bc3cb74SMauro Carvalho Chehab 	u32 myid = id;
855bc3cb74SMauro Carvalho Chehab 	int i;
865bc3cb74SMauro Carvalho Chehab 
875bc3cb74SMauro Carvalho Chehab 	/* HACK: ppc32 architecture doesn't have __ucmpdi2 function to handle
884faf7066SMauro Carvalho Chehab 	   64 bit comparisons. So, on that architecture, with some gcc
895bc3cb74SMauro Carvalho Chehab 	   variants, compilation fails. Currently, the max value is 30bit wide.
905bc3cb74SMauro Carvalho Chehab 	 */
915bc3cb74SMauro Carvalho Chehab 	BUG_ON(myid != id);
925bc3cb74SMauro Carvalho Chehab 
935bc3cb74SMauro Carvalho Chehab 	for (i = 0; standards[i].std; i++)
945bc3cb74SMauro Carvalho Chehab 		if (myid == standards[i].std)
955bc3cb74SMauro Carvalho Chehab 			break;
965bc3cb74SMauro Carvalho Chehab 	return standards[i].descr;
975bc3cb74SMauro Carvalho Chehab }
985bc3cb74SMauro Carvalho Chehab EXPORT_SYMBOL(v4l2_norm_to_name);
995bc3cb74SMauro Carvalho Chehab 
1005bc3cb74SMauro Carvalho Chehab /* Returns frame period for the given standard */
1015bc3cb74SMauro Carvalho Chehab void v4l2_video_std_frame_period(int id, struct v4l2_fract *frameperiod)
1025bc3cb74SMauro Carvalho Chehab {
1035bc3cb74SMauro Carvalho Chehab 	if (id & V4L2_STD_525_60) {
1045bc3cb74SMauro Carvalho Chehab 		frameperiod->numerator = 1001;
1055bc3cb74SMauro Carvalho Chehab 		frameperiod->denominator = 30000;
1065bc3cb74SMauro Carvalho Chehab 	} else {
1075bc3cb74SMauro Carvalho Chehab 		frameperiod->numerator = 1;
1085bc3cb74SMauro Carvalho Chehab 		frameperiod->denominator = 25;
1095bc3cb74SMauro Carvalho Chehab 	}
1105bc3cb74SMauro Carvalho Chehab }
1115bc3cb74SMauro Carvalho Chehab EXPORT_SYMBOL(v4l2_video_std_frame_period);
1125bc3cb74SMauro Carvalho Chehab 
1135bc3cb74SMauro Carvalho Chehab /* Fill in the fields of a v4l2_standard structure according to the
1145bc3cb74SMauro Carvalho Chehab    'id' and 'transmission' parameters.  Returns negative on error.  */
1155bc3cb74SMauro Carvalho Chehab int v4l2_video_std_construct(struct v4l2_standard *vs,
1165bc3cb74SMauro Carvalho Chehab 			     int id, const char *name)
1175bc3cb74SMauro Carvalho Chehab {
1185bc3cb74SMauro Carvalho Chehab 	vs->id = id;
1195bc3cb74SMauro Carvalho Chehab 	v4l2_video_std_frame_period(id, &vs->frameperiod);
1205bc3cb74SMauro Carvalho Chehab 	vs->framelines = (id & V4L2_STD_525_60) ? 525 : 625;
121c0decac1SMauro Carvalho Chehab 	strscpy(vs->name, name, sizeof(vs->name));
1225bc3cb74SMauro Carvalho Chehab 	return 0;
1235bc3cb74SMauro Carvalho Chehab }
1245bc3cb74SMauro Carvalho Chehab EXPORT_SYMBOL(v4l2_video_std_construct);
1255bc3cb74SMauro Carvalho Chehab 
126aa2f8871SNiklas Söderlund /* Fill in the fields of a v4l2_standard structure according to the
127aa2f8871SNiklas Söderlund  * 'id' and 'vs->index' parameters. Returns negative on error. */
128aa2f8871SNiklas Söderlund int v4l_video_std_enumstd(struct v4l2_standard *vs, v4l2_std_id id)
129aa2f8871SNiklas Söderlund {
130aa2f8871SNiklas Söderlund 	v4l2_std_id curr_id = 0;
131aa2f8871SNiklas Söderlund 	unsigned int index = vs->index, i, j = 0;
132aa2f8871SNiklas Söderlund 	const char *descr = "";
133aa2f8871SNiklas Söderlund 
134aa2f8871SNiklas Söderlund 	/* Return -ENODATA if the id for the current input
135aa2f8871SNiklas Söderlund 	   or output is 0, meaning that it doesn't support this API. */
136aa2f8871SNiklas Söderlund 	if (id == 0)
137aa2f8871SNiklas Söderlund 		return -ENODATA;
138aa2f8871SNiklas Söderlund 
139aa2f8871SNiklas Söderlund 	/* Return norm array in a canonical way */
140aa2f8871SNiklas Söderlund 	for (i = 0; i <= index && id; i++) {
141aa2f8871SNiklas Söderlund 		/* last std value in the standards array is 0, so this
142aa2f8871SNiklas Söderlund 		   while always ends there since (id & 0) == 0. */
143aa2f8871SNiklas Söderlund 		while ((id & standards[j].std) != standards[j].std)
144aa2f8871SNiklas Söderlund 			j++;
145aa2f8871SNiklas Söderlund 		curr_id = standards[j].std;
146aa2f8871SNiklas Söderlund 		descr = standards[j].descr;
147aa2f8871SNiklas Söderlund 		j++;
148aa2f8871SNiklas Söderlund 		if (curr_id == 0)
149aa2f8871SNiklas Söderlund 			break;
150aa2f8871SNiklas Söderlund 		if (curr_id != V4L2_STD_PAL &&
151aa2f8871SNiklas Söderlund 				curr_id != V4L2_STD_SECAM &&
152aa2f8871SNiklas Söderlund 				curr_id != V4L2_STD_NTSC)
153aa2f8871SNiklas Söderlund 			id &= ~curr_id;
154aa2f8871SNiklas Söderlund 	}
155aa2f8871SNiklas Söderlund 	if (i <= index)
156aa2f8871SNiklas Söderlund 		return -EINVAL;
157aa2f8871SNiklas Söderlund 
158aa2f8871SNiklas Söderlund 	v4l2_video_std_construct(vs, curr_id, descr);
159aa2f8871SNiklas Söderlund 	return 0;
160aa2f8871SNiklas Söderlund }
161aa2f8871SNiklas Söderlund 
1625bc3cb74SMauro Carvalho Chehab /* ----------------------------------------------------------------- */
1635bc3cb74SMauro Carvalho Chehab /* some arrays for pretty-printing debug messages of enum types      */
1645bc3cb74SMauro Carvalho Chehab 
1655bc3cb74SMauro Carvalho Chehab const char *v4l2_field_names[] = {
1665bc3cb74SMauro Carvalho Chehab 	[V4L2_FIELD_ANY]        = "any",
1675bc3cb74SMauro Carvalho Chehab 	[V4L2_FIELD_NONE]       = "none",
1685bc3cb74SMauro Carvalho Chehab 	[V4L2_FIELD_TOP]        = "top",
1695bc3cb74SMauro Carvalho Chehab 	[V4L2_FIELD_BOTTOM]     = "bottom",
1705bc3cb74SMauro Carvalho Chehab 	[V4L2_FIELD_INTERLACED] = "interlaced",
1715bc3cb74SMauro Carvalho Chehab 	[V4L2_FIELD_SEQ_TB]     = "seq-tb",
1725bc3cb74SMauro Carvalho Chehab 	[V4L2_FIELD_SEQ_BT]     = "seq-bt",
1735bc3cb74SMauro Carvalho Chehab 	[V4L2_FIELD_ALTERNATE]  = "alternate",
1745bc3cb74SMauro Carvalho Chehab 	[V4L2_FIELD_INTERLACED_TB] = "interlaced-tb",
1755bc3cb74SMauro Carvalho Chehab 	[V4L2_FIELD_INTERLACED_BT] = "interlaced-bt",
1765bc3cb74SMauro Carvalho Chehab };
1775bc3cb74SMauro Carvalho Chehab EXPORT_SYMBOL(v4l2_field_names);
1785bc3cb74SMauro Carvalho Chehab 
1795bc3cb74SMauro Carvalho Chehab const char *v4l2_type_names[] = {
180839aa56dSHans Verkuil 	[0]				   = "0",
1815bc3cb74SMauro Carvalho Chehab 	[V4L2_BUF_TYPE_VIDEO_CAPTURE]      = "vid-cap",
1825bc3cb74SMauro Carvalho Chehab 	[V4L2_BUF_TYPE_VIDEO_OVERLAY]      = "vid-overlay",
1835bc3cb74SMauro Carvalho Chehab 	[V4L2_BUF_TYPE_VIDEO_OUTPUT]       = "vid-out",
1845bc3cb74SMauro Carvalho Chehab 	[V4L2_BUF_TYPE_VBI_CAPTURE]        = "vbi-cap",
1855bc3cb74SMauro Carvalho Chehab 	[V4L2_BUF_TYPE_VBI_OUTPUT]         = "vbi-out",
1865bc3cb74SMauro Carvalho Chehab 	[V4L2_BUF_TYPE_SLICED_VBI_CAPTURE] = "sliced-vbi-cap",
1875bc3cb74SMauro Carvalho Chehab 	[V4L2_BUF_TYPE_SLICED_VBI_OUTPUT]  = "sliced-vbi-out",
1885bc3cb74SMauro Carvalho Chehab 	[V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY] = "vid-out-overlay",
1895bc3cb74SMauro Carvalho Chehab 	[V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE] = "vid-cap-mplane",
1905bc3cb74SMauro Carvalho Chehab 	[V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE] = "vid-out-mplane",
1916f3073b8SAntti Palosaari 	[V4L2_BUF_TYPE_SDR_CAPTURE]        = "sdr-cap",
1929effc72fSAntti Palosaari 	[V4L2_BUF_TYPE_SDR_OUTPUT]         = "sdr-out",
193fb9ffa6aSLaurent Pinchart 	[V4L2_BUF_TYPE_META_CAPTURE]       = "meta-cap",
19472148d1aSSakari Ailus 	[V4L2_BUF_TYPE_META_OUTPUT]	   = "meta-out",
1955bc3cb74SMauro Carvalho Chehab };
1965bc3cb74SMauro Carvalho Chehab EXPORT_SYMBOL(v4l2_type_names);
1975bc3cb74SMauro Carvalho Chehab 
1985bc3cb74SMauro Carvalho Chehab static const char *v4l2_memory_names[] = {
1995bc3cb74SMauro Carvalho Chehab 	[V4L2_MEMORY_MMAP]    = "mmap",
2005bc3cb74SMauro Carvalho Chehab 	[V4L2_MEMORY_USERPTR] = "userptr",
2015bc3cb74SMauro Carvalho Chehab 	[V4L2_MEMORY_OVERLAY] = "overlay",
202051c7788SSumit Semwal 	[V4L2_MEMORY_DMABUF] = "dmabuf",
2035bc3cb74SMauro Carvalho Chehab };
2045bc3cb74SMauro Carvalho Chehab 
205d9246240SHans Verkuil #define prt_names(a, arr) (((unsigned)(a)) < ARRAY_SIZE(arr) ? arr[a] : "unknown")
2065bc3cb74SMauro Carvalho Chehab 
2075bc3cb74SMauro Carvalho Chehab /* ------------------------------------------------------------------ */
2085bc3cb74SMauro Carvalho Chehab /* debug help functions                                               */
2095bc3cb74SMauro Carvalho Chehab 
2105bc3cb74SMauro Carvalho Chehab static void v4l_print_querycap(const void *arg, bool write_only)
2115bc3cb74SMauro Carvalho Chehab {
2125bc3cb74SMauro Carvalho Chehab 	const struct v4l2_capability *p = arg;
2135bc3cb74SMauro Carvalho Chehab 
2148720427cSMauro Carvalho Chehab 	pr_cont("driver=%.*s, card=%.*s, bus=%.*s, version=0x%08x, capabilities=0x%08x, device_caps=0x%08x\n",
21527d5a87cSHans Verkuil 		(int)sizeof(p->driver), p->driver,
21627d5a87cSHans Verkuil 		(int)sizeof(p->card), p->card,
21727d5a87cSHans Verkuil 		(int)sizeof(p->bus_info), p->bus_info,
2185bc3cb74SMauro Carvalho Chehab 		p->version, p->capabilities, p->device_caps);
2195bc3cb74SMauro Carvalho Chehab }
2205bc3cb74SMauro Carvalho Chehab 
2215bc3cb74SMauro Carvalho Chehab static void v4l_print_enuminput(const void *arg, bool write_only)
2225bc3cb74SMauro Carvalho Chehab {
2235bc3cb74SMauro Carvalho Chehab 	const struct v4l2_input *p = arg;
2245bc3cb74SMauro Carvalho Chehab 
2258720427cSMauro Carvalho Chehab 	pr_cont("index=%u, name=%.*s, type=%u, audioset=0x%x, tuner=%u, std=0x%08Lx, status=0x%x, capabilities=0x%x\n",
22627d5a87cSHans Verkuil 		p->index, (int)sizeof(p->name), p->name, p->type, p->audioset,
22727d5a87cSHans Verkuil 		p->tuner, (unsigned long long)p->std, p->status,
22827d5a87cSHans Verkuil 		p->capabilities);
2295bc3cb74SMauro Carvalho Chehab }
2305bc3cb74SMauro Carvalho Chehab 
2315bc3cb74SMauro Carvalho Chehab static void v4l_print_enumoutput(const void *arg, bool write_only)
2325bc3cb74SMauro Carvalho Chehab {
2335bc3cb74SMauro Carvalho Chehab 	const struct v4l2_output *p = arg;
2345bc3cb74SMauro Carvalho Chehab 
2358720427cSMauro Carvalho Chehab 	pr_cont("index=%u, name=%.*s, type=%u, audioset=0x%x, modulator=%u, std=0x%08Lx, capabilities=0x%x\n",
23627d5a87cSHans Verkuil 		p->index, (int)sizeof(p->name), p->name, p->type, p->audioset,
23727d5a87cSHans Verkuil 		p->modulator, (unsigned long long)p->std, p->capabilities);
2385bc3cb74SMauro Carvalho Chehab }
2395bc3cb74SMauro Carvalho Chehab 
2405bc3cb74SMauro Carvalho Chehab static void v4l_print_audio(const void *arg, bool write_only)
2415bc3cb74SMauro Carvalho Chehab {
2425bc3cb74SMauro Carvalho Chehab 	const struct v4l2_audio *p = arg;
2435bc3cb74SMauro Carvalho Chehab 
2445bc3cb74SMauro Carvalho Chehab 	if (write_only)
2455bc3cb74SMauro Carvalho Chehab 		pr_cont("index=%u, mode=0x%x\n", p->index, p->mode);
2465bc3cb74SMauro Carvalho Chehab 	else
24727d5a87cSHans Verkuil 		pr_cont("index=%u, name=%.*s, capability=0x%x, mode=0x%x\n",
24827d5a87cSHans Verkuil 			p->index, (int)sizeof(p->name), p->name,
24927d5a87cSHans Verkuil 			p->capability, p->mode);
2505bc3cb74SMauro Carvalho Chehab }
2515bc3cb74SMauro Carvalho Chehab 
2525bc3cb74SMauro Carvalho Chehab static void v4l_print_audioout(const void *arg, bool write_only)
2535bc3cb74SMauro Carvalho Chehab {
2545bc3cb74SMauro Carvalho Chehab 	const struct v4l2_audioout *p = arg;
2555bc3cb74SMauro Carvalho Chehab 
2565bc3cb74SMauro Carvalho Chehab 	if (write_only)
2575bc3cb74SMauro Carvalho Chehab 		pr_cont("index=%u\n", p->index);
2585bc3cb74SMauro Carvalho Chehab 	else
25927d5a87cSHans Verkuil 		pr_cont("index=%u, name=%.*s, capability=0x%x, mode=0x%x\n",
26027d5a87cSHans Verkuil 			p->index, (int)sizeof(p->name), p->name,
26127d5a87cSHans Verkuil 			p->capability, p->mode);
2625bc3cb74SMauro Carvalho Chehab }
2635bc3cb74SMauro Carvalho Chehab 
2645bc3cb74SMauro Carvalho Chehab static void v4l_print_fmtdesc(const void *arg, bool write_only)
2655bc3cb74SMauro Carvalho Chehab {
2665bc3cb74SMauro Carvalho Chehab 	const struct v4l2_fmtdesc *p = arg;
2675bc3cb74SMauro Carvalho Chehab 
268e927e1e0SSakari Ailus 	pr_cont("index=%u, type=%s, flags=0x%x, pixelformat=%p4cc, mbus_code=0x%04x, description='%.*s'\n",
2695bc3cb74SMauro Carvalho Chehab 		p->index, prt_names(p->type, v4l2_type_names),
270e927e1e0SSakari Ailus 		p->flags, &p->pixelformat, p->mbus_code,
27127d5a87cSHans Verkuil 		(int)sizeof(p->description), p->description);
2725bc3cb74SMauro Carvalho Chehab }
2735bc3cb74SMauro Carvalho Chehab 
2745bc3cb74SMauro Carvalho Chehab static void v4l_print_format(const void *arg, bool write_only)
2755bc3cb74SMauro Carvalho Chehab {
2765bc3cb74SMauro Carvalho Chehab 	const struct v4l2_format *p = arg;
2775bc3cb74SMauro Carvalho Chehab 	const struct v4l2_pix_format *pix;
2785bc3cb74SMauro Carvalho Chehab 	const struct v4l2_pix_format_mplane *mp;
2795bc3cb74SMauro Carvalho Chehab 	const struct v4l2_vbi_format *vbi;
2805bc3cb74SMauro Carvalho Chehab 	const struct v4l2_sliced_vbi_format *sliced;
2815bc3cb74SMauro Carvalho Chehab 	const struct v4l2_window *win;
282fb9ffa6aSLaurent Pinchart 	const struct v4l2_meta_format *meta;
28324bb30c8SSakari Ailus 	u32 pixelformat;
2847fe9f01cSSakari Ailus 	u32 planes;
2855bc3cb74SMauro Carvalho Chehab 	unsigned i;
2865bc3cb74SMauro Carvalho Chehab 
2875bc3cb74SMauro Carvalho Chehab 	pr_cont("type=%s", prt_names(p->type, v4l2_type_names));
2885bc3cb74SMauro Carvalho Chehab 	switch (p->type) {
2895bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_CAPTURE:
2905bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_OUTPUT:
2915bc3cb74SMauro Carvalho Chehab 		pix = &p->fmt.pix;
292e927e1e0SSakari Ailus 		pr_cont(", width=%u, height=%u, pixelformat=%p4cc, field=%s, bytesperline=%u, sizeimage=%u, colorspace=%d, flags=0x%x, ycbcr_enc=%u, quantization=%u, xfer_func=%u\n",
293e927e1e0SSakari Ailus 			pix->width, pix->height, &pix->pixelformat,
2945bc3cb74SMauro Carvalho Chehab 			prt_names(pix->field, v4l2_field_names),
2955bc3cb74SMauro Carvalho Chehab 			pix->bytesperline, pix->sizeimage,
296736d96b5SHans Verkuil 			pix->colorspace, pix->flags, pix->ycbcr_enc,
29774fdcb2eSHans Verkuil 			pix->quantization, pix->xfer_func);
2985bc3cb74SMauro Carvalho Chehab 		break;
2995bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
3005bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
3015bc3cb74SMauro Carvalho Chehab 		mp = &p->fmt.pix_mp;
30224bb30c8SSakari Ailus 		pixelformat = mp->pixelformat;
303e927e1e0SSakari 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",
30424bb30c8SSakari Ailus 			mp->width, mp->height, &pixelformat,
3055bc3cb74SMauro Carvalho Chehab 			prt_names(mp->field, v4l2_field_names),
306736d96b5SHans Verkuil 			mp->colorspace, mp->num_planes, mp->flags,
30774fdcb2eSHans Verkuil 			mp->ycbcr_enc, mp->quantization, mp->xfer_func);
3087fe9f01cSSakari Ailus 		planes = min_t(u32, mp->num_planes, VIDEO_MAX_PLANES);
3097fe9f01cSSakari Ailus 		for (i = 0; i < planes; i++)
3105bc3cb74SMauro Carvalho Chehab 			printk(KERN_DEBUG "plane %u: bytesperline=%u sizeimage=%u\n", i,
3115bc3cb74SMauro Carvalho Chehab 					mp->plane_fmt[i].bytesperline,
3125bc3cb74SMauro Carvalho Chehab 					mp->plane_fmt[i].sizeimage);
3135bc3cb74SMauro Carvalho Chehab 		break;
3145bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_OVERLAY:
3155bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
3165bc3cb74SMauro Carvalho Chehab 		win = &p->fmt.win;
317560dde24SHans Verkuil 		/* Note: we can't print the clip list here since the clips
318560dde24SHans Verkuil 		 * pointer is a userspace pointer, not a kernelspace
319560dde24SHans Verkuil 		 * pointer. */
320560dde24SHans 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",
321560dde24SHans Verkuil 			win->w.width, win->w.height, win->w.left, win->w.top,
3225bc3cb74SMauro Carvalho Chehab 			prt_names(win->field, v4l2_field_names),
323560dde24SHans Verkuil 			win->chromakey, win->clipcount, win->clips,
324560dde24SHans Verkuil 			win->bitmap, win->global_alpha);
3255bc3cb74SMauro Carvalho Chehab 		break;
3265bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VBI_CAPTURE:
3275bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VBI_OUTPUT:
3285bc3cb74SMauro Carvalho Chehab 		vbi = &p->fmt.vbi;
329e927e1e0SSakari Ailus 		pr_cont(", sampling_rate=%u, offset=%u, samples_per_line=%u, sample_format=%p4cc, start=%u,%u, count=%u,%u\n",
3305bc3cb74SMauro Carvalho Chehab 			vbi->sampling_rate, vbi->offset,
331e927e1e0SSakari Ailus 			vbi->samples_per_line, &vbi->sample_format,
3325bc3cb74SMauro Carvalho Chehab 			vbi->start[0], vbi->start[1],
3335bc3cb74SMauro Carvalho Chehab 			vbi->count[0], vbi->count[1]);
3345bc3cb74SMauro Carvalho Chehab 		break;
3355bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
3365bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
3375bc3cb74SMauro Carvalho Chehab 		sliced = &p->fmt.sliced;
3385bc3cb74SMauro Carvalho Chehab 		pr_cont(", service_set=0x%08x, io_size=%d\n",
3395bc3cb74SMauro Carvalho Chehab 				sliced->service_set, sliced->io_size);
3405bc3cb74SMauro Carvalho Chehab 		for (i = 0; i < 24; i++)
3415bc3cb74SMauro Carvalho Chehab 			printk(KERN_DEBUG "line[%02u]=0x%04x, 0x%04x\n", i,
3425bc3cb74SMauro Carvalho Chehab 				sliced->service_lines[0][i],
3435bc3cb74SMauro Carvalho Chehab 				sliced->service_lines[1][i]);
3445bc3cb74SMauro Carvalho Chehab 		break;
345582c52cbSAntti Palosaari 	case V4L2_BUF_TYPE_SDR_CAPTURE:
3469effc72fSAntti Palosaari 	case V4L2_BUF_TYPE_SDR_OUTPUT:
34724bb30c8SSakari Ailus 		pixelformat = p->fmt.sdr.pixelformat;
34824bb30c8SSakari Ailus 		pr_cont(", pixelformat=%p4cc\n", &pixelformat);
349582c52cbSAntti Palosaari 		break;
350fb9ffa6aSLaurent Pinchart 	case V4L2_BUF_TYPE_META_CAPTURE:
35172148d1aSSakari Ailus 	case V4L2_BUF_TYPE_META_OUTPUT:
352fb9ffa6aSLaurent Pinchart 		meta = &p->fmt.meta;
35324bb30c8SSakari Ailus 		pixelformat = meta->dataformat;
354e927e1e0SSakari Ailus 		pr_cont(", dataformat=%p4cc, buffersize=%u\n",
35524bb30c8SSakari Ailus 			&pixelformat, meta->buffersize);
356fb9ffa6aSLaurent Pinchart 		break;
3575bc3cb74SMauro Carvalho Chehab 	}
3585bc3cb74SMauro Carvalho Chehab }
3595bc3cb74SMauro Carvalho Chehab 
3605bc3cb74SMauro Carvalho Chehab static void v4l_print_framebuffer(const void *arg, bool write_only)
3615bc3cb74SMauro Carvalho Chehab {
3625bc3cb74SMauro Carvalho Chehab 	const struct v4l2_framebuffer *p = arg;
3635bc3cb74SMauro Carvalho Chehab 
364e927e1e0SSakari 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",
365e927e1e0SSakari Ailus 		p->capability, p->flags, p->base, p->fmt.width, p->fmt.height,
366e927e1e0SSakari Ailus 		&p->fmt.pixelformat, p->fmt.bytesperline, p->fmt.sizeimage,
3675bc3cb74SMauro Carvalho Chehab 		p->fmt.colorspace);
3685bc3cb74SMauro Carvalho Chehab }
3695bc3cb74SMauro Carvalho Chehab 
3705bc3cb74SMauro Carvalho Chehab static void v4l_print_buftype(const void *arg, bool write_only)
3715bc3cb74SMauro Carvalho Chehab {
3725bc3cb74SMauro Carvalho Chehab 	pr_cont("type=%s\n", prt_names(*(u32 *)arg, v4l2_type_names));
3735bc3cb74SMauro Carvalho Chehab }
3745bc3cb74SMauro Carvalho Chehab 
3755bc3cb74SMauro Carvalho Chehab static void v4l_print_modulator(const void *arg, bool write_only)
3765bc3cb74SMauro Carvalho Chehab {
3775bc3cb74SMauro Carvalho Chehab 	const struct v4l2_modulator *p = arg;
3785bc3cb74SMauro Carvalho Chehab 
3795bc3cb74SMauro Carvalho Chehab 	if (write_only)
380560dde24SHans Verkuil 		pr_cont("index=%u, txsubchans=0x%x\n", p->index, p->txsubchans);
3815bc3cb74SMauro Carvalho Chehab 	else
3828720427cSMauro Carvalho Chehab 		pr_cont("index=%u, name=%.*s, capability=0x%x, rangelow=%u, rangehigh=%u, txsubchans=0x%x\n",
38327d5a87cSHans Verkuil 			p->index, (int)sizeof(p->name), p->name, p->capability,
3845bc3cb74SMauro Carvalho Chehab 			p->rangelow, p->rangehigh, p->txsubchans);
3855bc3cb74SMauro Carvalho Chehab }
3865bc3cb74SMauro Carvalho Chehab 
3875bc3cb74SMauro Carvalho Chehab static void v4l_print_tuner(const void *arg, bool write_only)
3885bc3cb74SMauro Carvalho Chehab {
3895bc3cb74SMauro Carvalho Chehab 	const struct v4l2_tuner *p = arg;
3905bc3cb74SMauro Carvalho Chehab 
3915bc3cb74SMauro Carvalho Chehab 	if (write_only)
3925bc3cb74SMauro Carvalho Chehab 		pr_cont("index=%u, audmode=%u\n", p->index, p->audmode);
3935bc3cb74SMauro Carvalho Chehab 	else
3948720427cSMauro 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",
39527d5a87cSHans Verkuil 			p->index, (int)sizeof(p->name), p->name, p->type,
3965bc3cb74SMauro Carvalho Chehab 			p->capability, p->rangelow,
3975bc3cb74SMauro Carvalho Chehab 			p->rangehigh, p->signal, p->afc,
3985bc3cb74SMauro Carvalho Chehab 			p->rxsubchans, p->audmode);
3995bc3cb74SMauro Carvalho Chehab }
4005bc3cb74SMauro Carvalho Chehab 
4015bc3cb74SMauro Carvalho Chehab static void v4l_print_frequency(const void *arg, bool write_only)
4025bc3cb74SMauro Carvalho Chehab {
4035bc3cb74SMauro Carvalho Chehab 	const struct v4l2_frequency *p = arg;
4045bc3cb74SMauro Carvalho Chehab 
4055bc3cb74SMauro Carvalho Chehab 	pr_cont("tuner=%u, type=%u, frequency=%u\n",
4065bc3cb74SMauro Carvalho Chehab 				p->tuner, p->type, p->frequency);
4075bc3cb74SMauro Carvalho Chehab }
4085bc3cb74SMauro Carvalho Chehab 
4095bc3cb74SMauro Carvalho Chehab static void v4l_print_standard(const void *arg, bool write_only)
4105bc3cb74SMauro Carvalho Chehab {
4115bc3cb74SMauro Carvalho Chehab 	const struct v4l2_standard *p = arg;
4125bc3cb74SMauro Carvalho Chehab 
4138720427cSMauro Carvalho Chehab 	pr_cont("index=%u, id=0x%Lx, name=%.*s, fps=%u/%u, framelines=%u\n",
4148720427cSMauro Carvalho Chehab 		p->index,
41527d5a87cSHans Verkuil 		(unsigned long long)p->id, (int)sizeof(p->name), p->name,
4165bc3cb74SMauro Carvalho Chehab 		p->frameperiod.numerator,
4175bc3cb74SMauro Carvalho Chehab 		p->frameperiod.denominator,
4185bc3cb74SMauro Carvalho Chehab 		p->framelines);
4195bc3cb74SMauro Carvalho Chehab }
4205bc3cb74SMauro Carvalho Chehab 
4215bc3cb74SMauro Carvalho Chehab static void v4l_print_std(const void *arg, bool write_only)
4225bc3cb74SMauro Carvalho Chehab {
4235bc3cb74SMauro Carvalho Chehab 	pr_cont("std=0x%08Lx\n", *(const long long unsigned *)arg);
4245bc3cb74SMauro Carvalho Chehab }
4255bc3cb74SMauro Carvalho Chehab 
4265bc3cb74SMauro Carvalho Chehab static void v4l_print_hw_freq_seek(const void *arg, bool write_only)
4275bc3cb74SMauro Carvalho Chehab {
4285bc3cb74SMauro Carvalho Chehab 	const struct v4l2_hw_freq_seek *p = arg;
4295bc3cb74SMauro Carvalho Chehab 
4308720427cSMauro Carvalho Chehab 	pr_cont("tuner=%u, type=%u, seek_upward=%u, wrap_around=%u, spacing=%u, rangelow=%u, rangehigh=%u\n",
43179e8c7beSMauro Carvalho Chehab 		p->tuner, p->type, p->seek_upward, p->wrap_around, p->spacing,
43279e8c7beSMauro Carvalho Chehab 		p->rangelow, p->rangehigh);
4335bc3cb74SMauro Carvalho Chehab }
4345bc3cb74SMauro Carvalho Chehab 
4355bc3cb74SMauro Carvalho Chehab static void v4l_print_requestbuffers(const void *arg, bool write_only)
4365bc3cb74SMauro Carvalho Chehab {
4375bc3cb74SMauro Carvalho Chehab 	const struct v4l2_requestbuffers *p = arg;
4385bc3cb74SMauro Carvalho Chehab 
4395bc3cb74SMauro Carvalho Chehab 	pr_cont("count=%d, type=%s, memory=%s\n",
4405bc3cb74SMauro Carvalho Chehab 		p->count,
4415bc3cb74SMauro Carvalho Chehab 		prt_names(p->type, v4l2_type_names),
4425bc3cb74SMauro Carvalho Chehab 		prt_names(p->memory, v4l2_memory_names));
4435bc3cb74SMauro Carvalho Chehab }
4445bc3cb74SMauro Carvalho Chehab 
4455bc3cb74SMauro Carvalho Chehab static void v4l_print_buffer(const void *arg, bool write_only)
4465bc3cb74SMauro Carvalho Chehab {
4475bc3cb74SMauro Carvalho Chehab 	const struct v4l2_buffer *p = arg;
4485bc3cb74SMauro Carvalho Chehab 	const struct v4l2_timecode *tc = &p->timecode;
4495bc3cb74SMauro Carvalho Chehab 	const struct v4l2_plane *plane;
4505bc3cb74SMauro Carvalho Chehab 	int i;
4515bc3cb74SMauro Carvalho Chehab 
45248e15418SHans Verkuil 	pr_cont("%02d:%02d:%02d.%06ld index=%d, type=%s, request_fd=%d, flags=0x%08x, field=%s, sequence=%d, memory=%s",
453577c89b0SArnd Bergmann 			(int)p->timestamp.tv_sec / 3600,
454577c89b0SArnd Bergmann 			((int)p->timestamp.tv_sec / 60) % 60,
455577c89b0SArnd Bergmann 			((int)p->timestamp.tv_sec % 60),
4565bc3cb74SMauro Carvalho Chehab 			(long)p->timestamp.tv_usec,
4575bc3cb74SMauro Carvalho Chehab 			p->index,
45862fed26fSHans Verkuil 			prt_names(p->type, v4l2_type_names), p->request_fd,
4595bc3cb74SMauro Carvalho Chehab 			p->flags, prt_names(p->field, v4l2_field_names),
4605bc3cb74SMauro Carvalho Chehab 			p->sequence, prt_names(p->memory, v4l2_memory_names));
4615bc3cb74SMauro Carvalho Chehab 
4625bc3cb74SMauro Carvalho Chehab 	if (V4L2_TYPE_IS_MULTIPLANAR(p->type) && p->m.planes) {
4635bc3cb74SMauro Carvalho Chehab 		pr_cont("\n");
4645bc3cb74SMauro Carvalho Chehab 		for (i = 0; i < p->length; ++i) {
4655bc3cb74SMauro Carvalho Chehab 			plane = &p->m.planes[i];
4665bc3cb74SMauro Carvalho Chehab 			printk(KERN_DEBUG
4678720427cSMauro Carvalho Chehab 				"plane %d: bytesused=%d, data_offset=0x%08x, offset/userptr=0x%lx, length=%d\n",
4685bc3cb74SMauro Carvalho Chehab 				i, plane->bytesused, plane->data_offset,
4695bc3cb74SMauro Carvalho Chehab 				plane->m.userptr, plane->length);
4705bc3cb74SMauro Carvalho Chehab 		}
4715bc3cb74SMauro Carvalho Chehab 	} else {
472560dde24SHans Verkuil 		pr_cont(", bytesused=%d, offset/userptr=0x%lx, length=%d\n",
4735bc3cb74SMauro Carvalho Chehab 			p->bytesused, p->m.userptr, p->length);
4745bc3cb74SMauro Carvalho Chehab 	}
4755bc3cb74SMauro Carvalho Chehab 
4768720427cSMauro Carvalho Chehab 	printk(KERN_DEBUG "timecode=%02d:%02d:%02d type=%d, flags=0x%08x, frames=%d, userbits=0x%08x\n",
4775bc3cb74SMauro Carvalho Chehab 			tc->hours, tc->minutes, tc->seconds,
4785bc3cb74SMauro Carvalho Chehab 			tc->type, tc->flags, tc->frames, *(__u32 *)tc->userbits);
4795bc3cb74SMauro Carvalho Chehab }
4805bc3cb74SMauro Carvalho Chehab 
481b799d09aSTomasz Stanislawski static void v4l_print_exportbuffer(const void *arg, bool write_only)
482b799d09aSTomasz Stanislawski {
483b799d09aSTomasz Stanislawski 	const struct v4l2_exportbuffer *p = arg;
484b799d09aSTomasz Stanislawski 
485b799d09aSTomasz Stanislawski 	pr_cont("fd=%d, type=%s, index=%u, plane=%u, flags=0x%08x\n",
486b799d09aSTomasz Stanislawski 		p->fd, prt_names(p->type, v4l2_type_names),
487b799d09aSTomasz Stanislawski 		p->index, p->plane, p->flags);
488b799d09aSTomasz Stanislawski }
489b799d09aSTomasz Stanislawski 
4905bc3cb74SMauro Carvalho Chehab static void v4l_print_create_buffers(const void *arg, bool write_only)
4915bc3cb74SMauro Carvalho Chehab {
4925bc3cb74SMauro Carvalho Chehab 	const struct v4l2_create_buffers *p = arg;
4935bc3cb74SMauro Carvalho Chehab 
494319c4bd4SHelen Koike 	pr_cont("index=%d, count=%d, memory=%s, capabilities=0x%08x, ",
495319c4bd4SHelen Koike 		p->index, p->count, prt_names(p->memory, v4l2_memory_names),
496319c4bd4SHelen Koike 		p->capabilities);
4975bc3cb74SMauro Carvalho Chehab 	v4l_print_format(&p->format, write_only);
4985bc3cb74SMauro Carvalho Chehab }
4995bc3cb74SMauro Carvalho Chehab 
5005bc3cb74SMauro Carvalho Chehab static void v4l_print_streamparm(const void *arg, bool write_only)
5015bc3cb74SMauro Carvalho Chehab {
5025bc3cb74SMauro Carvalho Chehab 	const struct v4l2_streamparm *p = arg;
5035bc3cb74SMauro Carvalho Chehab 
5045bc3cb74SMauro Carvalho Chehab 	pr_cont("type=%s", prt_names(p->type, v4l2_type_names));
5055bc3cb74SMauro Carvalho Chehab 
5065bc3cb74SMauro Carvalho Chehab 	if (p->type == V4L2_BUF_TYPE_VIDEO_CAPTURE ||
5075bc3cb74SMauro Carvalho Chehab 	    p->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
5085bc3cb74SMauro Carvalho Chehab 		const struct v4l2_captureparm *c = &p->parm.capture;
5095bc3cb74SMauro Carvalho Chehab 
5108720427cSMauro Carvalho Chehab 		pr_cont(", capability=0x%x, capturemode=0x%x, timeperframe=%d/%d, extendedmode=%d, readbuffers=%d\n",
5115bc3cb74SMauro Carvalho Chehab 			c->capability, c->capturemode,
5125bc3cb74SMauro Carvalho Chehab 			c->timeperframe.numerator, c->timeperframe.denominator,
5135bc3cb74SMauro Carvalho Chehab 			c->extendedmode, c->readbuffers);
5145bc3cb74SMauro Carvalho Chehab 	} else if (p->type == V4L2_BUF_TYPE_VIDEO_OUTPUT ||
5155bc3cb74SMauro Carvalho Chehab 		   p->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
5165bc3cb74SMauro Carvalho Chehab 		const struct v4l2_outputparm *c = &p->parm.output;
5175bc3cb74SMauro Carvalho Chehab 
5188720427cSMauro Carvalho Chehab 		pr_cont(", capability=0x%x, outputmode=0x%x, timeperframe=%d/%d, extendedmode=%d, writebuffers=%d\n",
5195bc3cb74SMauro Carvalho Chehab 			c->capability, c->outputmode,
5205bc3cb74SMauro Carvalho Chehab 			c->timeperframe.numerator, c->timeperframe.denominator,
5215bc3cb74SMauro Carvalho Chehab 			c->extendedmode, c->writebuffers);
522560dde24SHans Verkuil 	} else {
523560dde24SHans Verkuil 		pr_cont("\n");
5245bc3cb74SMauro Carvalho Chehab 	}
5255bc3cb74SMauro Carvalho Chehab }
5265bc3cb74SMauro Carvalho Chehab 
5275bc3cb74SMauro Carvalho Chehab static void v4l_print_queryctrl(const void *arg, bool write_only)
5285bc3cb74SMauro Carvalho Chehab {
5295bc3cb74SMauro Carvalho Chehab 	const struct v4l2_queryctrl *p = arg;
5305bc3cb74SMauro Carvalho Chehab 
5318720427cSMauro Carvalho Chehab 	pr_cont("id=0x%x, type=%d, name=%.*s, min/max=%d/%d, step=%d, default=%d, flags=0x%08x\n",
53227d5a87cSHans Verkuil 			p->id, p->type, (int)sizeof(p->name), p->name,
5335bc3cb74SMauro Carvalho Chehab 			p->minimum, p->maximum,
5345bc3cb74SMauro Carvalho Chehab 			p->step, p->default_value, p->flags);
5355bc3cb74SMauro Carvalho Chehab }
5365bc3cb74SMauro Carvalho Chehab 
537e6bee368SHans Verkuil static void v4l_print_query_ext_ctrl(const void *arg, bool write_only)
538e6bee368SHans Verkuil {
539e6bee368SHans Verkuil 	const struct v4l2_query_ext_ctrl *p = arg;
540e6bee368SHans Verkuil 
5418720427cSMauro 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",
542e6bee368SHans Verkuil 			p->id, p->type, (int)sizeof(p->name), p->name,
543e6bee368SHans Verkuil 			p->minimum, p->maximum,
544e6bee368SHans Verkuil 			p->step, p->default_value, p->flags,
545e6bee368SHans Verkuil 			p->elem_size, p->elems, p->nr_of_dims,
5460176077aSHans Verkuil 			p->dims[0], p->dims[1], p->dims[2], p->dims[3]);
547e6bee368SHans Verkuil }
548e6bee368SHans Verkuil 
5495bc3cb74SMauro Carvalho Chehab static void v4l_print_querymenu(const void *arg, bool write_only)
5505bc3cb74SMauro Carvalho Chehab {
5515bc3cb74SMauro Carvalho Chehab 	const struct v4l2_querymenu *p = arg;
5525bc3cb74SMauro Carvalho Chehab 
5535bc3cb74SMauro Carvalho Chehab 	pr_cont("id=0x%x, index=%d\n", p->id, p->index);
5545bc3cb74SMauro Carvalho Chehab }
5555bc3cb74SMauro Carvalho Chehab 
5565bc3cb74SMauro Carvalho Chehab static void v4l_print_control(const void *arg, bool write_only)
5575bc3cb74SMauro Carvalho Chehab {
5585bc3cb74SMauro Carvalho Chehab 	const struct v4l2_control *p = arg;
559a69a7a33SEzequiel Garcia 	const char *name = v4l2_ctrl_get_name(p->id);
5605bc3cb74SMauro Carvalho Chehab 
561a69a7a33SEzequiel Garcia 	if (name)
562a69a7a33SEzequiel Garcia 		pr_cont("name=%s, ", name);
5635bc3cb74SMauro Carvalho Chehab 	pr_cont("id=0x%x, value=%d\n", p->id, p->value);
5645bc3cb74SMauro Carvalho Chehab }
5655bc3cb74SMauro Carvalho Chehab 
5665bc3cb74SMauro Carvalho Chehab static void v4l_print_ext_controls(const void *arg, bool write_only)
5675bc3cb74SMauro Carvalho Chehab {
5685bc3cb74SMauro Carvalho Chehab 	const struct v4l2_ext_controls *p = arg;
5695bc3cb74SMauro Carvalho Chehab 	int i;
5705bc3cb74SMauro Carvalho Chehab 
571f23317adSAlexandre Courbot 	pr_cont("which=0x%x, count=%d, error_idx=%d, request_fd=%d",
572f23317adSAlexandre Courbot 			p->which, p->count, p->error_idx, p->request_fd);
5735bc3cb74SMauro Carvalho Chehab 	for (i = 0; i < p->count; i++) {
574a69a7a33SEzequiel Garcia 		unsigned int id = p->controls[i].id;
575a69a7a33SEzequiel Garcia 		const char *name = v4l2_ctrl_get_name(id);
576a69a7a33SEzequiel Garcia 
577a69a7a33SEzequiel Garcia 		if (name)
578a69a7a33SEzequiel Garcia 			pr_cont(", name=%s", name);
579017ab36aSHans Verkuil 		if (!p->controls[i].size)
580a69a7a33SEzequiel Garcia 			pr_cont(", id/val=0x%x/0x%x", id, p->controls[i].value);
5815bc3cb74SMauro Carvalho Chehab 		else
582a69a7a33SEzequiel Garcia 			pr_cont(", id/size=0x%x/%u", id, p->controls[i].size);
5835bc3cb74SMauro Carvalho Chehab 	}
5845bc3cb74SMauro Carvalho Chehab 	pr_cont("\n");
5855bc3cb74SMauro Carvalho Chehab }
5865bc3cb74SMauro Carvalho Chehab 
5875bc3cb74SMauro Carvalho Chehab static void v4l_print_cropcap(const void *arg, bool write_only)
5885bc3cb74SMauro Carvalho Chehab {
5895bc3cb74SMauro Carvalho Chehab 	const struct v4l2_cropcap *p = arg;
5905bc3cb74SMauro Carvalho Chehab 
5918720427cSMauro 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",
5925bc3cb74SMauro Carvalho Chehab 		prt_names(p->type, v4l2_type_names),
5935bc3cb74SMauro Carvalho Chehab 		p->bounds.width, p->bounds.height,
5945bc3cb74SMauro Carvalho Chehab 		p->bounds.left, p->bounds.top,
5955bc3cb74SMauro Carvalho Chehab 		p->defrect.width, p->defrect.height,
5965bc3cb74SMauro Carvalho Chehab 		p->defrect.left, p->defrect.top,
5975bc3cb74SMauro Carvalho Chehab 		p->pixelaspect.numerator, p->pixelaspect.denominator);
5985bc3cb74SMauro Carvalho Chehab }
5995bc3cb74SMauro Carvalho Chehab 
6005bc3cb74SMauro Carvalho Chehab static void v4l_print_crop(const void *arg, bool write_only)
6015bc3cb74SMauro Carvalho Chehab {
6025bc3cb74SMauro Carvalho Chehab 	const struct v4l2_crop *p = arg;
6035bc3cb74SMauro Carvalho Chehab 
6045bc3cb74SMauro Carvalho Chehab 	pr_cont("type=%s, wxh=%dx%d, x,y=%d,%d\n",
6055bc3cb74SMauro Carvalho Chehab 		prt_names(p->type, v4l2_type_names),
6065bc3cb74SMauro Carvalho Chehab 		p->c.width, p->c.height,
6075bc3cb74SMauro Carvalho Chehab 		p->c.left, p->c.top);
6085bc3cb74SMauro Carvalho Chehab }
6095bc3cb74SMauro Carvalho Chehab 
6105bc3cb74SMauro Carvalho Chehab static void v4l_print_selection(const void *arg, bool write_only)
6115bc3cb74SMauro Carvalho Chehab {
6125bc3cb74SMauro Carvalho Chehab 	const struct v4l2_selection *p = arg;
6135bc3cb74SMauro Carvalho Chehab 
6145bc3cb74SMauro Carvalho Chehab 	pr_cont("type=%s, target=%d, flags=0x%x, wxh=%dx%d, x,y=%d,%d\n",
6155bc3cb74SMauro Carvalho Chehab 		prt_names(p->type, v4l2_type_names),
6165bc3cb74SMauro Carvalho Chehab 		p->target, p->flags,
6175bc3cb74SMauro Carvalho Chehab 		p->r.width, p->r.height, p->r.left, p->r.top);
6185bc3cb74SMauro Carvalho Chehab }
6195bc3cb74SMauro Carvalho Chehab 
6205bc3cb74SMauro Carvalho Chehab static void v4l_print_jpegcompression(const void *arg, bool write_only)
6215bc3cb74SMauro Carvalho Chehab {
6225bc3cb74SMauro Carvalho Chehab 	const struct v4l2_jpegcompression *p = arg;
6235bc3cb74SMauro Carvalho Chehab 
6248720427cSMauro Carvalho Chehab 	pr_cont("quality=%d, APPn=%d, APP_len=%d, COM_len=%d, jpeg_markers=0x%x\n",
6255bc3cb74SMauro Carvalho Chehab 		p->quality, p->APPn, p->APP_len,
6265bc3cb74SMauro Carvalho Chehab 		p->COM_len, p->jpeg_markers);
6275bc3cb74SMauro Carvalho Chehab }
6285bc3cb74SMauro Carvalho Chehab 
6295bc3cb74SMauro Carvalho Chehab static void v4l_print_enc_idx(const void *arg, bool write_only)
6305bc3cb74SMauro Carvalho Chehab {
6315bc3cb74SMauro Carvalho Chehab 	const struct v4l2_enc_idx *p = arg;
6325bc3cb74SMauro Carvalho Chehab 
6335bc3cb74SMauro Carvalho Chehab 	pr_cont("entries=%d, entries_cap=%d\n",
6345bc3cb74SMauro Carvalho Chehab 			p->entries, p->entries_cap);
6355bc3cb74SMauro Carvalho Chehab }
6365bc3cb74SMauro Carvalho Chehab 
6375bc3cb74SMauro Carvalho Chehab static void v4l_print_encoder_cmd(const void *arg, bool write_only)
6385bc3cb74SMauro Carvalho Chehab {
6395bc3cb74SMauro Carvalho Chehab 	const struct v4l2_encoder_cmd *p = arg;
6405bc3cb74SMauro Carvalho Chehab 
6415bc3cb74SMauro Carvalho Chehab 	pr_cont("cmd=%d, flags=0x%x\n",
6425bc3cb74SMauro Carvalho Chehab 			p->cmd, p->flags);
6435bc3cb74SMauro Carvalho Chehab }
6445bc3cb74SMauro Carvalho Chehab 
6455bc3cb74SMauro Carvalho Chehab static void v4l_print_decoder_cmd(const void *arg, bool write_only)
6465bc3cb74SMauro Carvalho Chehab {
6475bc3cb74SMauro Carvalho Chehab 	const struct v4l2_decoder_cmd *p = arg;
6485bc3cb74SMauro Carvalho Chehab 
6495bc3cb74SMauro Carvalho Chehab 	pr_cont("cmd=%d, flags=0x%x\n", p->cmd, p->flags);
6505bc3cb74SMauro Carvalho Chehab 
6515bc3cb74SMauro Carvalho Chehab 	if (p->cmd == V4L2_DEC_CMD_START)
6525bc3cb74SMauro Carvalho Chehab 		pr_info("speed=%d, format=%u\n",
6535bc3cb74SMauro Carvalho Chehab 				p->start.speed, p->start.format);
6545bc3cb74SMauro Carvalho Chehab 	else if (p->cmd == V4L2_DEC_CMD_STOP)
6555bc3cb74SMauro Carvalho Chehab 		pr_info("pts=%llu\n", p->stop.pts);
6565bc3cb74SMauro Carvalho Chehab }
6575bc3cb74SMauro Carvalho Chehab 
65896b03d2aSHans Verkuil static void v4l_print_dbg_chip_info(const void *arg, bool write_only)
65979b0c640SHans Verkuil {
66096b03d2aSHans Verkuil 	const struct v4l2_dbg_chip_info *p = arg;
66179b0c640SHans Verkuil 
66279b0c640SHans Verkuil 	pr_cont("type=%u, ", p->match.type);
6633eef2510SHans Verkuil 	if (p->match.type == V4L2_CHIP_MATCH_I2C_DRIVER)
66479b0c640SHans Verkuil 		pr_cont("name=%.*s, ",
66579b0c640SHans Verkuil 				(int)sizeof(p->match.name), p->match.name);
66679b0c640SHans Verkuil 	else
66779b0c640SHans Verkuil 		pr_cont("addr=%u, ", p->match.addr);
66879b0c640SHans Verkuil 	pr_cont("name=%.*s\n", (int)sizeof(p->name), p->name);
66979b0c640SHans Verkuil }
67079b0c640SHans Verkuil 
6715bc3cb74SMauro Carvalho Chehab static void v4l_print_dbg_register(const void *arg, bool write_only)
6725bc3cb74SMauro Carvalho Chehab {
6735bc3cb74SMauro Carvalho Chehab 	const struct v4l2_dbg_register *p = arg;
6745bc3cb74SMauro Carvalho Chehab 
6755bc3cb74SMauro Carvalho Chehab 	pr_cont("type=%u, ", p->match.type);
6763eef2510SHans Verkuil 	if (p->match.type == V4L2_CHIP_MATCH_I2C_DRIVER)
67727d5a87cSHans Verkuil 		pr_cont("name=%.*s, ",
67827d5a87cSHans Verkuil 				(int)sizeof(p->match.name), p->match.name);
6795bc3cb74SMauro Carvalho Chehab 	else
6805bc3cb74SMauro Carvalho Chehab 		pr_cont("addr=%u, ", p->match.addr);
6815bc3cb74SMauro Carvalho Chehab 	pr_cont("reg=0x%llx, val=0x%llx\n",
6825bc3cb74SMauro Carvalho Chehab 			p->reg, p->val);
6835bc3cb74SMauro Carvalho Chehab }
6845bc3cb74SMauro Carvalho Chehab 
6855bc3cb74SMauro Carvalho Chehab static void v4l_print_dv_timings(const void *arg, bool write_only)
6865bc3cb74SMauro Carvalho Chehab {
6875bc3cb74SMauro Carvalho Chehab 	const struct v4l2_dv_timings *p = arg;
6885bc3cb74SMauro Carvalho Chehab 
6895bc3cb74SMauro Carvalho Chehab 	switch (p->type) {
6905bc3cb74SMauro Carvalho Chehab 	case V4L2_DV_BT_656_1120:
6918720427cSMauro 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",
6925bc3cb74SMauro Carvalho Chehab 				p->bt.interlaced, p->bt.pixelclock,
6935bc3cb74SMauro Carvalho Chehab 				p->bt.width, p->bt.height,
6945bc3cb74SMauro Carvalho Chehab 				p->bt.polarities, p->bt.hfrontporch,
6955bc3cb74SMauro Carvalho Chehab 				p->bt.hsync, p->bt.hbackporch,
6965bc3cb74SMauro Carvalho Chehab 				p->bt.vfrontporch, p->bt.vsync,
6975bc3cb74SMauro Carvalho Chehab 				p->bt.vbackporch, p->bt.il_vfrontporch,
6985bc3cb74SMauro Carvalho Chehab 				p->bt.il_vsync, p->bt.il_vbackporch,
6995bc3cb74SMauro Carvalho Chehab 				p->bt.standards, p->bt.flags);
7005bc3cb74SMauro Carvalho Chehab 		break;
7015bc3cb74SMauro Carvalho Chehab 	default:
7025bc3cb74SMauro Carvalho Chehab 		pr_cont("type=%d\n", p->type);
7035bc3cb74SMauro Carvalho Chehab 		break;
7045bc3cb74SMauro Carvalho Chehab 	}
7055bc3cb74SMauro Carvalho Chehab }
7065bc3cb74SMauro Carvalho Chehab 
7075bc3cb74SMauro Carvalho Chehab static void v4l_print_enum_dv_timings(const void *arg, bool write_only)
7085bc3cb74SMauro Carvalho Chehab {
7095bc3cb74SMauro Carvalho Chehab 	const struct v4l2_enum_dv_timings *p = arg;
7105bc3cb74SMauro Carvalho Chehab 
7115bc3cb74SMauro Carvalho Chehab 	pr_cont("index=%u, ", p->index);
7125bc3cb74SMauro Carvalho Chehab 	v4l_print_dv_timings(&p->timings, write_only);
7135bc3cb74SMauro Carvalho Chehab }
7145bc3cb74SMauro Carvalho Chehab 
7155bc3cb74SMauro Carvalho Chehab static void v4l_print_dv_timings_cap(const void *arg, bool write_only)
7165bc3cb74SMauro Carvalho Chehab {
7175bc3cb74SMauro Carvalho Chehab 	const struct v4l2_dv_timings_cap *p = arg;
7185bc3cb74SMauro Carvalho Chehab 
7195bc3cb74SMauro Carvalho Chehab 	switch (p->type) {
7205bc3cb74SMauro Carvalho Chehab 	case V4L2_DV_BT_656_1120:
7218720427cSMauro Carvalho Chehab 		pr_cont("type=bt-656/1120, width=%u-%u, height=%u-%u, pixelclock=%llu-%llu, standards=0x%x, capabilities=0x%x\n",
7225bc3cb74SMauro Carvalho Chehab 			p->bt.min_width, p->bt.max_width,
7235bc3cb74SMauro Carvalho Chehab 			p->bt.min_height, p->bt.max_height,
7245bc3cb74SMauro Carvalho Chehab 			p->bt.min_pixelclock, p->bt.max_pixelclock,
7255bc3cb74SMauro Carvalho Chehab 			p->bt.standards, p->bt.capabilities);
7265bc3cb74SMauro Carvalho Chehab 		break;
7275bc3cb74SMauro Carvalho Chehab 	default:
7285bc3cb74SMauro Carvalho Chehab 		pr_cont("type=%u\n", p->type);
7295bc3cb74SMauro Carvalho Chehab 		break;
7305bc3cb74SMauro Carvalho Chehab 	}
7315bc3cb74SMauro Carvalho Chehab }
7325bc3cb74SMauro Carvalho Chehab 
7335bc3cb74SMauro Carvalho Chehab static void v4l_print_frmsizeenum(const void *arg, bool write_only)
7345bc3cb74SMauro Carvalho Chehab {
7355bc3cb74SMauro Carvalho Chehab 	const struct v4l2_frmsizeenum *p = arg;
7365bc3cb74SMauro Carvalho Chehab 
737e927e1e0SSakari Ailus 	pr_cont("index=%u, pixelformat=%p4cc, type=%u",
738e927e1e0SSakari Ailus 		p->index, &p->pixel_format, p->type);
7395bc3cb74SMauro Carvalho Chehab 	switch (p->type) {
7405bc3cb74SMauro Carvalho Chehab 	case V4L2_FRMSIZE_TYPE_DISCRETE:
741560dde24SHans Verkuil 		pr_cont(", wxh=%ux%u\n",
7425bc3cb74SMauro Carvalho Chehab 			p->discrete.width, p->discrete.height);
7435bc3cb74SMauro Carvalho Chehab 		break;
7445bc3cb74SMauro Carvalho Chehab 	case V4L2_FRMSIZE_TYPE_STEPWISE:
745560dde24SHans Verkuil 		pr_cont(", min=%ux%u, max=%ux%u, step=%ux%u\n",
7462489477eSRicardo Ribalda 				p->stepwise.min_width,
7472489477eSRicardo Ribalda 				p->stepwise.min_height,
7482489477eSRicardo Ribalda 				p->stepwise.max_width,
7492489477eSRicardo Ribalda 				p->stepwise.max_height,
7502489477eSRicardo Ribalda 				p->stepwise.step_width,
7512489477eSRicardo Ribalda 				p->stepwise.step_height);
7525bc3cb74SMauro Carvalho Chehab 		break;
7535bc3cb74SMauro Carvalho Chehab 	case V4L2_FRMSIZE_TYPE_CONTINUOUS:
7545bc3cb74SMauro Carvalho Chehab 	default:
7555bc3cb74SMauro Carvalho Chehab 		pr_cont("\n");
7565bc3cb74SMauro Carvalho Chehab 		break;
7575bc3cb74SMauro Carvalho Chehab 	}
7585bc3cb74SMauro Carvalho Chehab }
7595bc3cb74SMauro Carvalho Chehab 
7605bc3cb74SMauro Carvalho Chehab static void v4l_print_frmivalenum(const void *arg, bool write_only)
7615bc3cb74SMauro Carvalho Chehab {
7625bc3cb74SMauro Carvalho Chehab 	const struct v4l2_frmivalenum *p = arg;
7635bc3cb74SMauro Carvalho Chehab 
764e927e1e0SSakari Ailus 	pr_cont("index=%u, pixelformat=%p4cc, wxh=%ux%u, type=%u",
765e927e1e0SSakari Ailus 		p->index, &p->pixel_format, p->width, p->height, p->type);
7665bc3cb74SMauro Carvalho Chehab 	switch (p->type) {
7675bc3cb74SMauro Carvalho Chehab 	case V4L2_FRMIVAL_TYPE_DISCRETE:
768560dde24SHans Verkuil 		pr_cont(", fps=%d/%d\n",
7695bc3cb74SMauro Carvalho Chehab 				p->discrete.numerator,
7705bc3cb74SMauro Carvalho Chehab 				p->discrete.denominator);
7715bc3cb74SMauro Carvalho Chehab 		break;
7725bc3cb74SMauro Carvalho Chehab 	case V4L2_FRMIVAL_TYPE_STEPWISE:
773560dde24SHans Verkuil 		pr_cont(", min=%d/%d, max=%d/%d, step=%d/%d\n",
7745bc3cb74SMauro Carvalho Chehab 				p->stepwise.min.numerator,
7755bc3cb74SMauro Carvalho Chehab 				p->stepwise.min.denominator,
7765bc3cb74SMauro Carvalho Chehab 				p->stepwise.max.numerator,
7775bc3cb74SMauro Carvalho Chehab 				p->stepwise.max.denominator,
7785bc3cb74SMauro Carvalho Chehab 				p->stepwise.step.numerator,
7795bc3cb74SMauro Carvalho Chehab 				p->stepwise.step.denominator);
7805bc3cb74SMauro Carvalho Chehab 		break;
7815bc3cb74SMauro Carvalho Chehab 	case V4L2_FRMIVAL_TYPE_CONTINUOUS:
7825bc3cb74SMauro Carvalho Chehab 	default:
7835bc3cb74SMauro Carvalho Chehab 		pr_cont("\n");
7845bc3cb74SMauro Carvalho Chehab 		break;
7855bc3cb74SMauro Carvalho Chehab 	}
7865bc3cb74SMauro Carvalho Chehab }
7875bc3cb74SMauro Carvalho Chehab 
7885bc3cb74SMauro Carvalho Chehab static void v4l_print_event(const void *arg, bool write_only)
7895bc3cb74SMauro Carvalho Chehab {
7905bc3cb74SMauro Carvalho Chehab 	const struct v4l2_event *p = arg;
7915bc3cb74SMauro Carvalho Chehab 	const struct v4l2_event_ctrl *c;
7925bc3cb74SMauro Carvalho Chehab 
7931a6c0b36SArnd Bergmann 	pr_cont("type=0x%x, pending=%u, sequence=%u, id=%u, timestamp=%llu.%9.9llu\n",
7945bc3cb74SMauro Carvalho Chehab 			p->type, p->pending, p->sequence, p->id,
7955bc3cb74SMauro Carvalho Chehab 			p->timestamp.tv_sec, p->timestamp.tv_nsec);
7965bc3cb74SMauro Carvalho Chehab 	switch (p->type) {
7975bc3cb74SMauro Carvalho Chehab 	case V4L2_EVENT_VSYNC:
7985bc3cb74SMauro Carvalho Chehab 		printk(KERN_DEBUG "field=%s\n",
7995bc3cb74SMauro Carvalho Chehab 			prt_names(p->u.vsync.field, v4l2_field_names));
8005bc3cb74SMauro Carvalho Chehab 		break;
8015bc3cb74SMauro Carvalho Chehab 	case V4L2_EVENT_CTRL:
8025bc3cb74SMauro Carvalho Chehab 		c = &p->u.ctrl;
8035bc3cb74SMauro Carvalho Chehab 		printk(KERN_DEBUG "changes=0x%x, type=%u, ",
8045bc3cb74SMauro Carvalho Chehab 			c->changes, c->type);
8055bc3cb74SMauro Carvalho Chehab 		if (c->type == V4L2_CTRL_TYPE_INTEGER64)
8065bc3cb74SMauro Carvalho Chehab 			pr_cont("value64=%lld, ", c->value64);
8075bc3cb74SMauro Carvalho Chehab 		else
8085bc3cb74SMauro Carvalho Chehab 			pr_cont("value=%d, ", c->value);
8098720427cSMauro Carvalho Chehab 		pr_cont("flags=0x%x, minimum=%d, maximum=%d, step=%d, default_value=%d\n",
8105bc3cb74SMauro Carvalho Chehab 			c->flags, c->minimum, c->maximum,
8115bc3cb74SMauro Carvalho Chehab 			c->step, c->default_value);
8125bc3cb74SMauro Carvalho Chehab 		break;
8135bc3cb74SMauro Carvalho Chehab 	case V4L2_EVENT_FRAME_SYNC:
8145bc3cb74SMauro Carvalho Chehab 		pr_cont("frame_sequence=%u\n",
8155bc3cb74SMauro Carvalho Chehab 			p->u.frame_sync.frame_sequence);
8165bc3cb74SMauro Carvalho Chehab 		break;
8175bc3cb74SMauro Carvalho Chehab 	}
8185bc3cb74SMauro Carvalho Chehab }
8195bc3cb74SMauro Carvalho Chehab 
8205bc3cb74SMauro Carvalho Chehab static void v4l_print_event_subscription(const void *arg, bool write_only)
8215bc3cb74SMauro Carvalho Chehab {
8225bc3cb74SMauro Carvalho Chehab 	const struct v4l2_event_subscription *p = arg;
8235bc3cb74SMauro Carvalho Chehab 
8245bc3cb74SMauro Carvalho Chehab 	pr_cont("type=0x%x, id=0x%x, flags=0x%x\n",
8255bc3cb74SMauro Carvalho Chehab 			p->type, p->id, p->flags);
8265bc3cb74SMauro Carvalho Chehab }
8275bc3cb74SMauro Carvalho Chehab 
8285bc3cb74SMauro Carvalho Chehab static void v4l_print_sliced_vbi_cap(const void *arg, bool write_only)
8295bc3cb74SMauro Carvalho Chehab {
8305bc3cb74SMauro Carvalho Chehab 	const struct v4l2_sliced_vbi_cap *p = arg;
8315bc3cb74SMauro Carvalho Chehab 	int i;
8325bc3cb74SMauro Carvalho Chehab 
8335bc3cb74SMauro Carvalho Chehab 	pr_cont("type=%s, service_set=0x%08x\n",
8345bc3cb74SMauro Carvalho Chehab 			prt_names(p->type, v4l2_type_names), p->service_set);
8355bc3cb74SMauro Carvalho Chehab 	for (i = 0; i < 24; i++)
8365bc3cb74SMauro Carvalho Chehab 		printk(KERN_DEBUG "line[%02u]=0x%04x, 0x%04x\n", i,
8375bc3cb74SMauro Carvalho Chehab 				p->service_lines[0][i],
8385bc3cb74SMauro Carvalho Chehab 				p->service_lines[1][i]);
8395bc3cb74SMauro Carvalho Chehab }
8405bc3cb74SMauro Carvalho Chehab 
8415bc3cb74SMauro Carvalho Chehab static void v4l_print_freq_band(const void *arg, bool write_only)
8425bc3cb74SMauro Carvalho Chehab {
8435bc3cb74SMauro Carvalho Chehab 	const struct v4l2_frequency_band *p = arg;
8445bc3cb74SMauro Carvalho Chehab 
8458720427cSMauro Carvalho Chehab 	pr_cont("tuner=%u, type=%u, index=%u, capability=0x%x, rangelow=%u, rangehigh=%u, modulation=0x%x\n",
8465bc3cb74SMauro Carvalho Chehab 			p->tuner, p->type, p->index,
8475bc3cb74SMauro Carvalho Chehab 			p->capability, p->rangelow,
8485bc3cb74SMauro Carvalho Chehab 			p->rangehigh, p->modulation);
8495bc3cb74SMauro Carvalho Chehab }
8505bc3cb74SMauro Carvalho Chehab 
851dd519bb3SHans Verkuil static void v4l_print_edid(const void *arg, bool write_only)
852dd519bb3SHans Verkuil {
853dd519bb3SHans Verkuil 	const struct v4l2_edid *p = arg;
854dd519bb3SHans Verkuil 
855dd519bb3SHans Verkuil 	pr_cont("pad=%u, start_block=%u, blocks=%u\n",
856dd519bb3SHans Verkuil 		p->pad, p->start_block, p->blocks);
857dd519bb3SHans Verkuil }
858dd519bb3SHans Verkuil 
8595bc3cb74SMauro Carvalho Chehab static void v4l_print_u32(const void *arg, bool write_only)
8605bc3cb74SMauro Carvalho Chehab {
8615bc3cb74SMauro Carvalho Chehab 	pr_cont("value=%u\n", *(const u32 *)arg);
8625bc3cb74SMauro Carvalho Chehab }
8635bc3cb74SMauro Carvalho Chehab 
8645bc3cb74SMauro Carvalho Chehab static void v4l_print_newline(const void *arg, bool write_only)
8655bc3cb74SMauro Carvalho Chehab {
8665bc3cb74SMauro Carvalho Chehab 	pr_cont("\n");
8675bc3cb74SMauro Carvalho Chehab }
8685bc3cb74SMauro Carvalho Chehab 
8695bc3cb74SMauro Carvalho Chehab static void v4l_print_default(const void *arg, bool write_only)
8705bc3cb74SMauro Carvalho Chehab {
8715bc3cb74SMauro Carvalho Chehab 	pr_cont("driver-specific ioctl\n");
8725bc3cb74SMauro Carvalho Chehab }
8735bc3cb74SMauro Carvalho Chehab 
874861f92cbSRicardo Ribalda static bool check_ext_ctrls(struct v4l2_ext_controls *c, unsigned long ioctl)
8755bc3cb74SMauro Carvalho Chehab {
8765bc3cb74SMauro Carvalho Chehab 	__u32 i;
8775bc3cb74SMauro Carvalho Chehab 
8785bc3cb74SMauro Carvalho Chehab 	/* zero the reserved fields */
879f23317adSAlexandre Courbot 	c->reserved[0] = 0;
8805bc3cb74SMauro Carvalho Chehab 	for (i = 0; i < c->count; i++)
8815bc3cb74SMauro Carvalho Chehab 		c->controls[i].reserved2[0] = 0;
8825bc3cb74SMauro Carvalho Chehab 
883861f92cbSRicardo Ribalda 	switch (c->which) {
884861f92cbSRicardo Ribalda 	case V4L2_CID_PRIVATE_BASE:
885861f92cbSRicardo Ribalda 		/*
886861f92cbSRicardo Ribalda 		 * V4L2_CID_PRIVATE_BASE cannot be used as control class
887861f92cbSRicardo Ribalda 		 * when using extended controls.
888861f92cbSRicardo Ribalda 		 * Only when passed in through VIDIOC_G_CTRL and VIDIOC_S_CTRL
889861f92cbSRicardo Ribalda 		 * is it allowed for backwards compatibility.
8905bc3cb74SMauro Carvalho Chehab 		 */
891861f92cbSRicardo Ribalda 		if (ioctl == VIDIOC_G_CTRL || ioctl == VIDIOC_S_CTRL)
892861f92cbSRicardo Ribalda 			return false;
893861f92cbSRicardo Ribalda 		break;
894861f92cbSRicardo Ribalda 	case V4L2_CTRL_WHICH_DEF_VAL:
895861f92cbSRicardo Ribalda 		/* Default value cannot be changed */
896861f92cbSRicardo Ribalda 		if (ioctl == VIDIOC_S_EXT_CTRLS ||
897861f92cbSRicardo Ribalda 		    ioctl == VIDIOC_TRY_EXT_CTRLS) {
898861f92cbSRicardo Ribalda 			c->error_idx = c->count;
899861f92cbSRicardo Ribalda 			return false;
900861f92cbSRicardo Ribalda 		}
901861f92cbSRicardo Ribalda 		return true;
902861f92cbSRicardo Ribalda 	case V4L2_CTRL_WHICH_CUR_VAL:
903861f92cbSRicardo Ribalda 		return true;
904861f92cbSRicardo Ribalda 	case V4L2_CTRL_WHICH_REQUEST_VAL:
905861f92cbSRicardo Ribalda 		c->error_idx = c->count;
906861f92cbSRicardo Ribalda 		return false;
907861f92cbSRicardo Ribalda 	}
908861f92cbSRicardo Ribalda 
9095bc3cb74SMauro Carvalho Chehab 	/* Check that all controls are from the same control class. */
9105bc3cb74SMauro Carvalho Chehab 	for (i = 0; i < c->count; i++) {
9110f8017beSRicardo Ribalda 		if (V4L2_CTRL_ID2WHICH(c->controls[i].id) != c->which) {
912861f92cbSRicardo Ribalda 			c->error_idx = ioctl == VIDIOC_TRY_EXT_CTRLS ? i :
913861f92cbSRicardo Ribalda 								      c->count;
914861f92cbSRicardo Ribalda 			return false;
9155bc3cb74SMauro Carvalho Chehab 		}
9165bc3cb74SMauro Carvalho Chehab 	}
917861f92cbSRicardo Ribalda 	return true;
9185bc3cb74SMauro Carvalho Chehab }
9195bc3cb74SMauro Carvalho Chehab 
9204b20259fSHans Verkuil static int check_fmt(struct file *file, enum v4l2_buf_type type)
9215bc3cb74SMauro Carvalho Chehab {
92296f49c1aSVandana BN 	const u32 vid_caps = V4L2_CAP_VIDEO_CAPTURE |
92396f49c1aSVandana BN 			     V4L2_CAP_VIDEO_CAPTURE_MPLANE |
92496f49c1aSVandana BN 			     V4L2_CAP_VIDEO_OUTPUT |
92596f49c1aSVandana BN 			     V4L2_CAP_VIDEO_OUTPUT_MPLANE |
92696f49c1aSVandana BN 			     V4L2_CAP_VIDEO_M2M | V4L2_CAP_VIDEO_M2M_MPLANE;
92796f49c1aSVandana BN 	const u32 meta_caps = V4L2_CAP_META_CAPTURE |
92896f49c1aSVandana BN 			      V4L2_CAP_META_OUTPUT;
9294b20259fSHans Verkuil 	struct video_device *vfd = video_devdata(file);
9304b20259fSHans Verkuil 	const struct v4l2_ioctl_ops *ops = vfd->ioctl_ops;
931238e4a5bSHans Verkuil 	bool is_vid = vfd->vfl_type == VFL_TYPE_VIDEO &&
93296f49c1aSVandana BN 		      (vfd->device_caps & vid_caps);
9334b20259fSHans Verkuil 	bool is_vbi = vfd->vfl_type == VFL_TYPE_VBI;
934582c52cbSAntti Palosaari 	bool is_sdr = vfd->vfl_type == VFL_TYPE_SDR;
935b2fe22d0SNick Dyer 	bool is_tch = vfd->vfl_type == VFL_TYPE_TOUCH;
936238e4a5bSHans Verkuil 	bool is_meta = vfd->vfl_type == VFL_TYPE_VIDEO &&
93796f49c1aSVandana BN 		       (vfd->device_caps & meta_caps);
9384b20259fSHans Verkuil 	bool is_rx = vfd->vfl_dir != VFL_DIR_TX;
9394b20259fSHans Verkuil 	bool is_tx = vfd->vfl_dir != VFL_DIR_RX;
9404b20259fSHans Verkuil 
9415bc3cb74SMauro Carvalho Chehab 	if (ops == NULL)
9425bc3cb74SMauro Carvalho Chehab 		return -EINVAL;
9435bc3cb74SMauro Carvalho Chehab 
9445bc3cb74SMauro Carvalho Chehab 	switch (type) {
9455bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_CAPTURE:
946b2fe22d0SNick Dyer 		if ((is_vid || is_tch) && is_rx &&
9474b20259fSHans Verkuil 		    (ops->vidioc_g_fmt_vid_cap || ops->vidioc_g_fmt_vid_cap_mplane))
9485bc3cb74SMauro Carvalho Chehab 			return 0;
9495bc3cb74SMauro Carvalho Chehab 		break;
9505bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
951095c21d3SHans Verkuil 		if ((is_vid || is_tch) && is_rx && ops->vidioc_g_fmt_vid_cap_mplane)
9525bc3cb74SMauro Carvalho Chehab 			return 0;
9535bc3cb74SMauro Carvalho Chehab 		break;
9545bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_OVERLAY:
9554b20259fSHans Verkuil 		if (is_vid && is_rx && ops->vidioc_g_fmt_vid_overlay)
9565bc3cb74SMauro Carvalho Chehab 			return 0;
9575bc3cb74SMauro Carvalho Chehab 		break;
9585bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_OUTPUT:
9594b20259fSHans Verkuil 		if (is_vid && is_tx &&
9604b20259fSHans Verkuil 		    (ops->vidioc_g_fmt_vid_out || ops->vidioc_g_fmt_vid_out_mplane))
9615bc3cb74SMauro Carvalho Chehab 			return 0;
9625bc3cb74SMauro Carvalho Chehab 		break;
9635bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
9644b20259fSHans Verkuil 		if (is_vid && is_tx && ops->vidioc_g_fmt_vid_out_mplane)
9655bc3cb74SMauro Carvalho Chehab 			return 0;
9665bc3cb74SMauro Carvalho Chehab 		break;
9675bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
9684b20259fSHans Verkuil 		if (is_vid && is_tx && ops->vidioc_g_fmt_vid_out_overlay)
9695bc3cb74SMauro Carvalho Chehab 			return 0;
9705bc3cb74SMauro Carvalho Chehab 		break;
9715bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VBI_CAPTURE:
9724b20259fSHans Verkuil 		if (is_vbi && is_rx && ops->vidioc_g_fmt_vbi_cap)
9735bc3cb74SMauro Carvalho Chehab 			return 0;
9745bc3cb74SMauro Carvalho Chehab 		break;
9755bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VBI_OUTPUT:
9764b20259fSHans Verkuil 		if (is_vbi && is_tx && ops->vidioc_g_fmt_vbi_out)
9775bc3cb74SMauro Carvalho Chehab 			return 0;
9785bc3cb74SMauro Carvalho Chehab 		break;
9795bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
9804b20259fSHans Verkuil 		if (is_vbi && is_rx && ops->vidioc_g_fmt_sliced_vbi_cap)
9815bc3cb74SMauro Carvalho Chehab 			return 0;
9825bc3cb74SMauro Carvalho Chehab 		break;
9835bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
9844b20259fSHans Verkuil 		if (is_vbi && is_tx && ops->vidioc_g_fmt_sliced_vbi_out)
9855bc3cb74SMauro Carvalho Chehab 			return 0;
9865bc3cb74SMauro Carvalho Chehab 		break;
987582c52cbSAntti Palosaari 	case V4L2_BUF_TYPE_SDR_CAPTURE:
988582c52cbSAntti Palosaari 		if (is_sdr && is_rx && ops->vidioc_g_fmt_sdr_cap)
989582c52cbSAntti Palosaari 			return 0;
990582c52cbSAntti Palosaari 		break;
9919effc72fSAntti Palosaari 	case V4L2_BUF_TYPE_SDR_OUTPUT:
9929effc72fSAntti Palosaari 		if (is_sdr && is_tx && ops->vidioc_g_fmt_sdr_out)
9939effc72fSAntti Palosaari 			return 0;
9949effc72fSAntti Palosaari 		break;
995fb9ffa6aSLaurent Pinchart 	case V4L2_BUF_TYPE_META_CAPTURE:
99696f49c1aSVandana BN 		if (is_meta && is_rx && ops->vidioc_g_fmt_meta_cap)
997fb9ffa6aSLaurent Pinchart 			return 0;
998fb9ffa6aSLaurent Pinchart 		break;
99972148d1aSSakari Ailus 	case V4L2_BUF_TYPE_META_OUTPUT:
100096f49c1aSVandana BN 		if (is_meta && is_tx && ops->vidioc_g_fmt_meta_out)
100172148d1aSSakari Ailus 			return 0;
100272148d1aSSakari Ailus 		break;
1003633c98e5SHans Verkuil 	default:
10045bc3cb74SMauro Carvalho Chehab 		break;
10055bc3cb74SMauro Carvalho Chehab 	}
10065bc3cb74SMauro Carvalho Chehab 	return -EINVAL;
10075bc3cb74SMauro Carvalho Chehab }
10085bc3cb74SMauro Carvalho Chehab 
1009d52e2381SLaurent Pinchart static void v4l_sanitize_format(struct v4l2_format *fmt)
1010d52e2381SLaurent Pinchart {
1011d52e2381SLaurent Pinchart 	unsigned int offset;
1012d52e2381SLaurent Pinchart 
101314c8e80eSEzequiel Garcia 	/* Make sure num_planes is not bogus */
101414c8e80eSEzequiel Garcia 	if (fmt->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE ||
101514c8e80eSEzequiel Garcia 	    fmt->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)
101614c8e80eSEzequiel Garcia 		fmt->fmt.pix_mp.num_planes = min_t(u32, fmt->fmt.pix_mp.num_planes,
101714c8e80eSEzequiel Garcia 					       VIDEO_MAX_PLANES);
101814c8e80eSEzequiel Garcia 
1019d52e2381SLaurent Pinchart 	/*
1020d52e2381SLaurent Pinchart 	 * The v4l2_pix_format structure has been extended with fields that were
1021d52e2381SLaurent Pinchart 	 * not previously required to be set to zero by applications. The priv
1022d52e2381SLaurent Pinchart 	 * field, when set to a magic value, indicates the the extended fields
1023d52e2381SLaurent Pinchart 	 * are valid. Otherwise they will contain undefined values. To simplify
1024d52e2381SLaurent Pinchart 	 * the API towards drivers zero the extended fields and set the priv
1025d52e2381SLaurent Pinchart 	 * field to the magic value when the extended pixel format structure
1026d52e2381SLaurent Pinchart 	 * isn't used by applications.
1027d52e2381SLaurent Pinchart 	 */
1028d52e2381SLaurent Pinchart 
1029d52e2381SLaurent Pinchart 	if (fmt->type != V4L2_BUF_TYPE_VIDEO_CAPTURE &&
1030d52e2381SLaurent Pinchart 	    fmt->type != V4L2_BUF_TYPE_VIDEO_OUTPUT)
1031d52e2381SLaurent Pinchart 		return;
1032d52e2381SLaurent Pinchart 
1033d52e2381SLaurent Pinchart 	if (fmt->fmt.pix.priv == V4L2_PIX_FMT_PRIV_MAGIC)
1034d52e2381SLaurent Pinchart 		return;
1035d52e2381SLaurent Pinchart 
1036d52e2381SLaurent Pinchart 	fmt->fmt.pix.priv = V4L2_PIX_FMT_PRIV_MAGIC;
1037d52e2381SLaurent Pinchart 
1038d52e2381SLaurent Pinchart 	offset = offsetof(struct v4l2_pix_format, priv)
1039d52e2381SLaurent Pinchart 	       + sizeof(fmt->fmt.pix.priv);
1040d52e2381SLaurent Pinchart 	memset(((void *)&fmt->fmt.pix) + offset, 0,
1041d52e2381SLaurent Pinchart 	       sizeof(fmt->fmt.pix) - offset);
1042d52e2381SLaurent Pinchart }
1043d52e2381SLaurent Pinchart 
10445bc3cb74SMauro Carvalho Chehab static int v4l_querycap(const struct v4l2_ioctl_ops *ops,
10455bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
10465bc3cb74SMauro Carvalho Chehab {
10475bc3cb74SMauro Carvalho Chehab 	struct v4l2_capability *cap = (struct v4l2_capability *)arg;
10487bbe7813SHans Verkuil 	struct video_device *vfd = video_devdata(file);
1049d52e2381SLaurent Pinchart 	int ret;
10505bc3cb74SMauro Carvalho Chehab 
10515bc3cb74SMauro Carvalho Chehab 	cap->version = LINUX_VERSION_CODE;
10527bbe7813SHans Verkuil 	cap->device_caps = vfd->device_caps;
10537bbe7813SHans Verkuil 	cap->capabilities = vfd->device_caps | V4L2_CAP_DEVICE_CAPS;
1054d52e2381SLaurent Pinchart 
1055d52e2381SLaurent Pinchart 	ret = ops->vidioc_querycap(file, fh, cap);
1056d52e2381SLaurent Pinchart 
1057454a4e72SHans Verkuil 	/*
10583c135050SHans Verkuil 	 * Drivers must not change device_caps, so check for this and
10593c135050SHans Verkuil 	 * warn if this happened.
1060454a4e72SHans Verkuil 	 */
10613c135050SHans Verkuil 	WARN_ON(cap->device_caps != vfd->device_caps);
10623c135050SHans Verkuil 	/*
10633c135050SHans Verkuil 	 * Check that capabilities is a superset of
10643c135050SHans Verkuil 	 * vfd->device_caps | V4L2_CAP_DEVICE_CAPS
10653c135050SHans Verkuil 	 */
10663c135050SHans Verkuil 	WARN_ON((cap->capabilities &
10673c135050SHans Verkuil 		 (vfd->device_caps | V4L2_CAP_DEVICE_CAPS)) !=
10683c135050SHans Verkuil 		(vfd->device_caps | V4L2_CAP_DEVICE_CAPS));
10693c135050SHans Verkuil 	cap->capabilities |= V4L2_CAP_EXT_PIX_FORMAT;
1070796a2bd2SHans Verkuil 	cap->device_caps |= V4L2_CAP_EXT_PIX_FORMAT;
1071d52e2381SLaurent Pinchart 
1072d52e2381SLaurent Pinchart 	return ret;
10735bc3cb74SMauro Carvalho Chehab }
10745bc3cb74SMauro Carvalho Chehab 
1075f645e625SNiklas Söderlund static int v4l_g_input(const struct v4l2_ioctl_ops *ops,
1076f645e625SNiklas Söderlund 		       struct file *file, void *fh, void *arg)
1077f645e625SNiklas Söderlund {
1078f645e625SNiklas Söderlund 	struct video_device *vfd = video_devdata(file);
1079f645e625SNiklas Söderlund 
1080f645e625SNiklas Söderlund 	if (vfd->device_caps & V4L2_CAP_IO_MC) {
1081f645e625SNiklas Söderlund 		*(int *)arg = 0;
1082f645e625SNiklas Söderlund 		return 0;
1083f645e625SNiklas Söderlund 	}
1084f645e625SNiklas Söderlund 
1085f645e625SNiklas Söderlund 	return ops->vidioc_g_input(file, fh, arg);
1086f645e625SNiklas Söderlund }
1087f645e625SNiklas Söderlund 
1088f645e625SNiklas Söderlund static int v4l_g_output(const struct v4l2_ioctl_ops *ops,
1089f645e625SNiklas Söderlund 			struct file *file, void *fh, void *arg)
1090f645e625SNiklas Söderlund {
1091f645e625SNiklas Söderlund 	struct video_device *vfd = video_devdata(file);
1092f645e625SNiklas Söderlund 
1093f645e625SNiklas Söderlund 	if (vfd->device_caps & V4L2_CAP_IO_MC) {
1094f645e625SNiklas Söderlund 		*(int *)arg = 0;
1095f645e625SNiklas Söderlund 		return 0;
1096f645e625SNiklas Söderlund 	}
1097f645e625SNiklas Söderlund 
1098f645e625SNiklas Söderlund 	return ops->vidioc_g_output(file, fh, arg);
1099f645e625SNiklas Söderlund }
1100f645e625SNiklas Söderlund 
11015bc3cb74SMauro Carvalho Chehab static int v4l_s_input(const struct v4l2_ioctl_ops *ops,
11025bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
11035bc3cb74SMauro Carvalho Chehab {
110477fa4e07SShuah Khan 	struct video_device *vfd = video_devdata(file);
110577fa4e07SShuah Khan 	int ret;
110677fa4e07SShuah Khan 
110777fa4e07SShuah Khan 	ret = v4l_enable_media_source(vfd);
110877fa4e07SShuah Khan 	if (ret)
110977fa4e07SShuah Khan 		return ret;
1110f645e625SNiklas Söderlund 
1111f645e625SNiklas Söderlund 	if (vfd->device_caps & V4L2_CAP_IO_MC)
1112f645e625SNiklas Söderlund 		return  *(int *)arg ? -EINVAL : 0;
1113f645e625SNiklas Söderlund 
11145bc3cb74SMauro Carvalho Chehab 	return ops->vidioc_s_input(file, fh, *(unsigned int *)arg);
11155bc3cb74SMauro Carvalho Chehab }
11165bc3cb74SMauro Carvalho Chehab 
11175bc3cb74SMauro Carvalho Chehab static int v4l_s_output(const struct v4l2_ioctl_ops *ops,
11185bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
11195bc3cb74SMauro Carvalho Chehab {
1120f645e625SNiklas Söderlund 	struct video_device *vfd = video_devdata(file);
1121f645e625SNiklas Söderlund 
1122f645e625SNiklas Söderlund 	if (vfd->device_caps & V4L2_CAP_IO_MC)
1123f645e625SNiklas Söderlund 		return  *(int *)arg ? -EINVAL : 0;
1124f645e625SNiklas Söderlund 
11255bc3cb74SMauro Carvalho Chehab 	return ops->vidioc_s_output(file, fh, *(unsigned int *)arg);
11265bc3cb74SMauro Carvalho Chehab }
11275bc3cb74SMauro Carvalho Chehab 
11285bc3cb74SMauro Carvalho Chehab static int v4l_g_priority(const struct v4l2_ioctl_ops *ops,
11295bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
11305bc3cb74SMauro Carvalho Chehab {
11315bc3cb74SMauro Carvalho Chehab 	struct video_device *vfd;
11325bc3cb74SMauro Carvalho Chehab 	u32 *p = arg;
11335bc3cb74SMauro Carvalho Chehab 
11345bc3cb74SMauro Carvalho Chehab 	vfd = video_devdata(file);
113559b702eaSLaurent Pinchart 	*p = v4l2_prio_max(vfd->prio);
11365bc3cb74SMauro Carvalho Chehab 	return 0;
11375bc3cb74SMauro Carvalho Chehab }
11385bc3cb74SMauro Carvalho Chehab 
11395bc3cb74SMauro Carvalho Chehab static int v4l_s_priority(const struct v4l2_ioctl_ops *ops,
11405bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
11415bc3cb74SMauro Carvalho Chehab {
11425bc3cb74SMauro Carvalho Chehab 	struct video_device *vfd;
11435bc3cb74SMauro Carvalho Chehab 	struct v4l2_fh *vfh;
11445bc3cb74SMauro Carvalho Chehab 	u32 *p = arg;
11455bc3cb74SMauro Carvalho Chehab 
11465bc3cb74SMauro Carvalho Chehab 	vfd = video_devdata(file);
11472438e78aSHans Verkuil 	if (!test_bit(V4L2_FL_USES_V4L2_FH, &vfd->flags))
11482438e78aSHans Verkuil 		return -ENOTTY;
11495bc3cb74SMauro Carvalho Chehab 	vfh = file->private_data;
115059b702eaSLaurent Pinchart 	return v4l2_prio_change(vfd->prio, &vfh->prio, *p);
11515bc3cb74SMauro Carvalho Chehab }
11525bc3cb74SMauro Carvalho Chehab 
11535bc3cb74SMauro Carvalho Chehab static int v4l_enuminput(const struct v4l2_ioctl_ops *ops,
11545bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
11555bc3cb74SMauro Carvalho Chehab {
115673f35418SHans Verkuil 	struct video_device *vfd = video_devdata(file);
11575bc3cb74SMauro Carvalho Chehab 	struct v4l2_input *p = arg;
11585bc3cb74SMauro Carvalho Chehab 
11595bc3cb74SMauro Carvalho Chehab 	/*
116002fa6282SHans Verkuil 	 * We set the flags for CAP_DV_TIMINGS &
11615bc3cb74SMauro Carvalho Chehab 	 * CAP_STD here based on ioctl handler provided by the
11625bc3cb74SMauro Carvalho Chehab 	 * driver. If the driver doesn't support these
11635bc3cb74SMauro Carvalho Chehab 	 * for a specific input, it must override these flags.
11645bc3cb74SMauro Carvalho Chehab 	 */
116573f35418SHans Verkuil 	if (is_valid_ioctl(vfd, VIDIOC_S_STD))
11665bc3cb74SMauro Carvalho Chehab 		p->capabilities |= V4L2_IN_CAP_STD;
11675bc3cb74SMauro Carvalho Chehab 
1168f645e625SNiklas Söderlund 	if (vfd->device_caps & V4L2_CAP_IO_MC) {
1169f645e625SNiklas Söderlund 		if (p->index)
1170f645e625SNiklas Söderlund 			return -EINVAL;
1171f645e625SNiklas Söderlund 		strscpy(p->name, vfd->name, sizeof(p->name));
1172f645e625SNiklas Söderlund 		p->type = V4L2_INPUT_TYPE_CAMERA;
1173f645e625SNiklas Söderlund 		return 0;
1174f645e625SNiklas Söderlund 	}
1175f645e625SNiklas Söderlund 
11765bc3cb74SMauro Carvalho Chehab 	return ops->vidioc_enum_input(file, fh, p);
11775bc3cb74SMauro Carvalho Chehab }
11785bc3cb74SMauro Carvalho Chehab 
11795bc3cb74SMauro Carvalho Chehab static int v4l_enumoutput(const struct v4l2_ioctl_ops *ops,
11805bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
11815bc3cb74SMauro Carvalho Chehab {
118273f35418SHans Verkuil 	struct video_device *vfd = video_devdata(file);
11835bc3cb74SMauro Carvalho Chehab 	struct v4l2_output *p = arg;
11845bc3cb74SMauro Carvalho Chehab 
11855bc3cb74SMauro Carvalho Chehab 	/*
118602fa6282SHans Verkuil 	 * We set the flags for CAP_DV_TIMINGS &
11875bc3cb74SMauro Carvalho Chehab 	 * CAP_STD here based on ioctl handler provided by the
11885bc3cb74SMauro Carvalho Chehab 	 * driver. If the driver doesn't support these
11895bc3cb74SMauro Carvalho Chehab 	 * for a specific output, it must override these flags.
11905bc3cb74SMauro Carvalho Chehab 	 */
119173f35418SHans Verkuil 	if (is_valid_ioctl(vfd, VIDIOC_S_STD))
11925bc3cb74SMauro Carvalho Chehab 		p->capabilities |= V4L2_OUT_CAP_STD;
11935bc3cb74SMauro Carvalho Chehab 
1194f645e625SNiklas Söderlund 	if (vfd->device_caps & V4L2_CAP_IO_MC) {
1195f645e625SNiklas Söderlund 		if (p->index)
1196f645e625SNiklas Söderlund 			return -EINVAL;
1197f645e625SNiklas Söderlund 		strscpy(p->name, vfd->name, sizeof(p->name));
1198f645e625SNiklas Söderlund 		p->type = V4L2_OUTPUT_TYPE_ANALOG;
1199f645e625SNiklas Söderlund 		return 0;
1200f645e625SNiklas Söderlund 	}
1201f645e625SNiklas Söderlund 
12025bc3cb74SMauro Carvalho Chehab 	return ops->vidioc_enum_output(file, fh, p);
12035bc3cb74SMauro Carvalho Chehab }
12045bc3cb74SMauro Carvalho Chehab 
1205ba300204SHans Verkuil static void v4l_fill_fmtdesc(struct v4l2_fmtdesc *fmt)
1206ba300204SHans Verkuil {
1207ba300204SHans Verkuil 	const unsigned sz = sizeof(fmt->description);
1208ba300204SHans Verkuil 	const char *descr = NULL;
1209ba300204SHans Verkuil 	u32 flags = 0;
1210ba300204SHans Verkuil 
1211ba300204SHans Verkuil 	/*
1212ba300204SHans Verkuil 	 * We depart from the normal coding style here since the descriptions
1213ba300204SHans Verkuil 	 * should be aligned so it is easy to see which descriptions will be
1214ba300204SHans Verkuil 	 * longer than 31 characters (the max length for a description).
1215ba300204SHans Verkuil 	 * And frankly, this is easier to read anyway.
1216ba300204SHans Verkuil 	 *
1217ba300204SHans Verkuil 	 * Note that gcc will use O(log N) comparisons to find the right case.
1218ba300204SHans Verkuil 	 */
1219ba300204SHans Verkuil 	switch (fmt->pixelformat) {
1220ba300204SHans Verkuil 	/* Max description length mask:	descr = "0123456789012345678901234567890" */
1221ba300204SHans Verkuil 	case V4L2_PIX_FMT_RGB332:	descr = "8-bit RGB 3-3-2"; break;
1222ba300204SHans Verkuil 	case V4L2_PIX_FMT_RGB444:	descr = "16-bit A/XRGB 4-4-4-4"; break;
1223ba300204SHans Verkuil 	case V4L2_PIX_FMT_ARGB444:	descr = "16-bit ARGB 4-4-4-4"; break;
1224ba300204SHans Verkuil 	case V4L2_PIX_FMT_XRGB444:	descr = "16-bit XRGB 4-4-4-4"; break;
12254747bd0fSHans Verkuil 	case V4L2_PIX_FMT_RGBA444:	descr = "16-bit RGBA 4-4-4-4"; break;
12264747bd0fSHans Verkuil 	case V4L2_PIX_FMT_RGBX444:	descr = "16-bit RGBX 4-4-4-4"; break;
12274747bd0fSHans Verkuil 	case V4L2_PIX_FMT_ABGR444:	descr = "16-bit ABGR 4-4-4-4"; break;
12284747bd0fSHans Verkuil 	case V4L2_PIX_FMT_XBGR444:	descr = "16-bit XBGR 4-4-4-4"; break;
12294747bd0fSHans Verkuil 	case V4L2_PIX_FMT_BGRA444:	descr = "16-bit BGRA 4-4-4-4"; break;
12304747bd0fSHans Verkuil 	case V4L2_PIX_FMT_BGRX444:	descr = "16-bit BGRX 4-4-4-4"; break;
1231ba300204SHans Verkuil 	case V4L2_PIX_FMT_RGB555:	descr = "16-bit A/XRGB 1-5-5-5"; break;
1232ba300204SHans Verkuil 	case V4L2_PIX_FMT_ARGB555:	descr = "16-bit ARGB 1-5-5-5"; break;
1233ba300204SHans Verkuil 	case V4L2_PIX_FMT_XRGB555:	descr = "16-bit XRGB 1-5-5-5"; break;
12344747bd0fSHans Verkuil 	case V4L2_PIX_FMT_ABGR555:	descr = "16-bit ABGR 1-5-5-5"; break;
12354747bd0fSHans Verkuil 	case V4L2_PIX_FMT_XBGR555:	descr = "16-bit XBGR 1-5-5-5"; break;
12364747bd0fSHans Verkuil 	case V4L2_PIX_FMT_RGBA555:	descr = "16-bit RGBA 5-5-5-1"; break;
12374747bd0fSHans Verkuil 	case V4L2_PIX_FMT_RGBX555:	descr = "16-bit RGBX 5-5-5-1"; break;
12384747bd0fSHans Verkuil 	case V4L2_PIX_FMT_BGRA555:	descr = "16-bit BGRA 5-5-5-1"; break;
12394747bd0fSHans Verkuil 	case V4L2_PIX_FMT_BGRX555:	descr = "16-bit BGRX 5-5-5-1"; break;
1240ba300204SHans Verkuil 	case V4L2_PIX_FMT_RGB565:	descr = "16-bit RGB 5-6-5"; break;
1241ba300204SHans Verkuil 	case V4L2_PIX_FMT_RGB555X:	descr = "16-bit A/XRGB 1-5-5-5 BE"; break;
1242ba300204SHans Verkuil 	case V4L2_PIX_FMT_ARGB555X:	descr = "16-bit ARGB 1-5-5-5 BE"; break;
1243ba300204SHans Verkuil 	case V4L2_PIX_FMT_XRGB555X:	descr = "16-bit XRGB 1-5-5-5 BE"; break;
1244ba300204SHans Verkuil 	case V4L2_PIX_FMT_RGB565X:	descr = "16-bit RGB 5-6-5 BE"; break;
1245ba300204SHans Verkuil 	case V4L2_PIX_FMT_BGR666:	descr = "18-bit BGRX 6-6-6-14"; break;
1246ba300204SHans Verkuil 	case V4L2_PIX_FMT_BGR24:	descr = "24-bit BGR 8-8-8"; break;
1247ba300204SHans Verkuil 	case V4L2_PIX_FMT_RGB24:	descr = "24-bit RGB 8-8-8"; break;
1248ba300204SHans Verkuil 	case V4L2_PIX_FMT_BGR32:	descr = "32-bit BGRA/X 8-8-8-8"; break;
1249ba300204SHans Verkuil 	case V4L2_PIX_FMT_ABGR32:	descr = "32-bit BGRA 8-8-8-8"; break;
1250ba300204SHans Verkuil 	case V4L2_PIX_FMT_XBGR32:	descr = "32-bit BGRX 8-8-8-8"; break;
1251ba300204SHans Verkuil 	case V4L2_PIX_FMT_RGB32:	descr = "32-bit A/XRGB 8-8-8-8"; break;
1252ba300204SHans Verkuil 	case V4L2_PIX_FMT_ARGB32:	descr = "32-bit ARGB 8-8-8-8"; break;
1253ba300204SHans Verkuil 	case V4L2_PIX_FMT_XRGB32:	descr = "32-bit XRGB 8-8-8-8"; break;
12544747bd0fSHans Verkuil 	case V4L2_PIX_FMT_BGRA32:	descr = "32-bit ABGR 8-8-8-8"; break;
12554747bd0fSHans Verkuil 	case V4L2_PIX_FMT_BGRX32:	descr = "32-bit XBGR 8-8-8-8"; break;
12564747bd0fSHans Verkuil 	case V4L2_PIX_FMT_RGBA32:	descr = "32-bit RGBA 8-8-8-8"; break;
12574747bd0fSHans Verkuil 	case V4L2_PIX_FMT_RGBX32:	descr = "32-bit RGBX 8-8-8-8"; break;
1258ba300204SHans Verkuil 	case V4L2_PIX_FMT_GREY:		descr = "8-bit Greyscale"; break;
1259ba300204SHans Verkuil 	case V4L2_PIX_FMT_Y4:		descr = "4-bit Greyscale"; break;
1260ba300204SHans Verkuil 	case V4L2_PIX_FMT_Y6:		descr = "6-bit Greyscale"; break;
1261ba300204SHans Verkuil 	case V4L2_PIX_FMT_Y10:		descr = "10-bit Greyscale"; break;
1262ba300204SHans Verkuil 	case V4L2_PIX_FMT_Y12:		descr = "12-bit Greyscale"; break;
1263ae9753a0SDaniel Glöckner 	case V4L2_PIX_FMT_Y14:		descr = "14-bit Greyscale"; break;
1264ba300204SHans Verkuil 	case V4L2_PIX_FMT_Y16:		descr = "16-bit Greyscale"; break;
12652e5e435fSRicardo Ribalda 	case V4L2_PIX_FMT_Y16_BE:	descr = "16-bit Greyscale BE"; break;
1266ba300204SHans Verkuil 	case V4L2_PIX_FMT_Y10BPACK:	descr = "10-bit Greyscale (Packed)"; break;
12676e15bec4STodor Tomov 	case V4L2_PIX_FMT_Y10P:		descr = "10-bit Greyscale (MIPI Packed)"; break;
12685b382290SLaurent Pinchart 	case V4L2_PIX_FMT_Y8I:		descr = "Interleaved 8-bit Greyscale"; break;
12695b382290SLaurent Pinchart 	case V4L2_PIX_FMT_Y12I:		descr = "Interleaved 12-bit Greyscale"; break;
12705b382290SLaurent Pinchart 	case V4L2_PIX_FMT_Z16:		descr = "16-bit Depth"; break;
12715df082e2SEvgeni Raikhel 	case V4L2_PIX_FMT_INZI:		descr = "Planar 10:16 Greyscale Depth"; break;
127292799ef7SSergey Dorodnicov 	case V4L2_PIX_FMT_CNF4:		descr = "4-bit Depth Confidence (Packed)"; break;
1273ba300204SHans Verkuil 	case V4L2_PIX_FMT_PAL8:		descr = "8-bit Palette"; break;
1274ba300204SHans Verkuil 	case V4L2_PIX_FMT_UV8:		descr = "8-bit Chrominance UV 4-4"; break;
1275ba300204SHans Verkuil 	case V4L2_PIX_FMT_YVU410:	descr = "Planar YVU 4:1:0"; break;
1276ba300204SHans Verkuil 	case V4L2_PIX_FMT_YVU420:	descr = "Planar YVU 4:2:0"; break;
1277ba300204SHans Verkuil 	case V4L2_PIX_FMT_YUYV:		descr = "YUYV 4:2:2"; break;
1278ba300204SHans Verkuil 	case V4L2_PIX_FMT_YYUV:		descr = "YYUV 4:2:2"; break;
1279ba300204SHans Verkuil 	case V4L2_PIX_FMT_YVYU:		descr = "YVYU 4:2:2"; break;
1280ba300204SHans Verkuil 	case V4L2_PIX_FMT_UYVY:		descr = "UYVY 4:2:2"; break;
1281ba300204SHans Verkuil 	case V4L2_PIX_FMT_VYUY:		descr = "VYUY 4:2:2"; break;
1282fcbafafbSPhilipp Zabel 	case V4L2_PIX_FMT_YUV422P:	descr = "Planar YUV 4:2:2"; break;
1283ba300204SHans Verkuil 	case V4L2_PIX_FMT_YUV411P:	descr = "Planar YUV 4:1:1"; break;
1284ba300204SHans Verkuil 	case V4L2_PIX_FMT_Y41P:		descr = "YUV 4:1:1 (Packed)"; break;
1285ba300204SHans Verkuil 	case V4L2_PIX_FMT_YUV444:	descr = "16-bit A/XYUV 4-4-4-4"; break;
1286ba300204SHans Verkuil 	case V4L2_PIX_FMT_YUV555:	descr = "16-bit A/XYUV 1-5-5-5"; break;
1287ba300204SHans Verkuil 	case V4L2_PIX_FMT_YUV565:	descr = "16-bit YUV 5-6-5"; break;
12880376a51fSMirela Rabulea 	case V4L2_PIX_FMT_YUV24:	descr = "24-bit YUV 4:4:4 8-8-8"; break;
1289ba300204SHans Verkuil 	case V4L2_PIX_FMT_YUV32:	descr = "32-bit A/XYUV 8-8-8-8"; break;
1290a7fe4ca7SVivek Kasireddy 	case V4L2_PIX_FMT_AYUV32:	descr = "32-bit AYUV 8-8-8-8"; break;
1291a7fe4ca7SVivek Kasireddy 	case V4L2_PIX_FMT_XYUV32:	descr = "32-bit XYUV 8-8-8-8"; break;
1292a7fe4ca7SVivek Kasireddy 	case V4L2_PIX_FMT_VUYA32:	descr = "32-bit VUYA 8-8-8-8"; break;
1293a7fe4ca7SVivek Kasireddy 	case V4L2_PIX_FMT_VUYX32:	descr = "32-bit VUYX 8-8-8-8"; break;
1294ba300204SHans Verkuil 	case V4L2_PIX_FMT_YUV410:	descr = "Planar YUV 4:1:0"; break;
1295ba300204SHans Verkuil 	case V4L2_PIX_FMT_YUV420:	descr = "Planar YUV 4:2:0"; break;
1296ba300204SHans Verkuil 	case V4L2_PIX_FMT_HI240:	descr = "8-bit Dithered RGB (BTTV)"; break;
1297ba300204SHans Verkuil 	case V4L2_PIX_FMT_M420:		descr = "YUV 4:2:0 (M420)"; break;
1298ba300204SHans Verkuil 	case V4L2_PIX_FMT_NV12:		descr = "Y/CbCr 4:2:0"; break;
1299ba300204SHans Verkuil 	case V4L2_PIX_FMT_NV21:		descr = "Y/CrCb 4:2:0"; break;
1300ba300204SHans Verkuil 	case V4L2_PIX_FMT_NV16:		descr = "Y/CbCr 4:2:2"; break;
1301ba300204SHans Verkuil 	case V4L2_PIX_FMT_NV61:		descr = "Y/CrCb 4:2:2"; break;
1302ba300204SHans Verkuil 	case V4L2_PIX_FMT_NV24:		descr = "Y/CbCr 4:4:4"; break;
1303ba300204SHans Verkuil 	case V4L2_PIX_FMT_NV42:		descr = "Y/CrCb 4:4:4"; break;
1304683f71ebSEzequiel Garcia 	case V4L2_PIX_FMT_NV12_4L4:	descr = "Y/CbCr 4:2:0 (4x4 Linear)"; break;
130578eee7b5SEzequiel Garcia 	case V4L2_PIX_FMT_NV12_16L16:	descr = "Y/CbCr 4:2:0 (16x16 Linear)"; break;
1306b84f60a3SEzequiel Garcia 	case V4L2_PIX_FMT_NV12_32L32:   descr = "Y/CbCr 4:2:0 (32x32 Linear)"; break;
1307ba300204SHans Verkuil 	case V4L2_PIX_FMT_NV12M:	descr = "Y/CbCr 4:2:0 (N-C)"; break;
1308ba300204SHans Verkuil 	case V4L2_PIX_FMT_NV21M:	descr = "Y/CrCb 4:2:0 (N-C)"; break;
1309ba300204SHans Verkuil 	case V4L2_PIX_FMT_NV16M:	descr = "Y/CbCr 4:2:2 (N-C)"; break;
1310ba300204SHans Verkuil 	case V4L2_PIX_FMT_NV61M:	descr = "Y/CrCb 4:2:2 (N-C)"; break;
1311ba300204SHans Verkuil 	case V4L2_PIX_FMT_NV12MT:	descr = "Y/CbCr 4:2:0 (64x32 MB, N-C)"; break;
1312ba300204SHans Verkuil 	case V4L2_PIX_FMT_NV12MT_16X16:	descr = "Y/CbCr 4:2:0 (16x16 MB, N-C)"; break;
1313ba300204SHans Verkuil 	case V4L2_PIX_FMT_YUV420M:	descr = "Planar YUV 4:2:0 (N-C)"; break;
1314ba300204SHans Verkuil 	case V4L2_PIX_FMT_YVU420M:	descr = "Planar YVU 4:2:0 (N-C)"; break;
1315d65fae92SLaurent Pinchart 	case V4L2_PIX_FMT_YUV422M:	descr = "Planar YUV 4:2:2 (N-C)"; break;
1316d65fae92SLaurent Pinchart 	case V4L2_PIX_FMT_YVU422M:	descr = "Planar YVU 4:2:2 (N-C)"; break;
1317d65fae92SLaurent Pinchart 	case V4L2_PIX_FMT_YUV444M:	descr = "Planar YUV 4:4:4 (N-C)"; break;
1318d65fae92SLaurent Pinchart 	case V4L2_PIX_FMT_YVU444M:	descr = "Planar YVU 4:4:4 (N-C)"; break;
1319ba300204SHans Verkuil 	case V4L2_PIX_FMT_SBGGR8:	descr = "8-bit Bayer BGBG/GRGR"; break;
1320ba300204SHans Verkuil 	case V4L2_PIX_FMT_SGBRG8:	descr = "8-bit Bayer GBGB/RGRG"; break;
1321ba300204SHans Verkuil 	case V4L2_PIX_FMT_SGRBG8:	descr = "8-bit Bayer GRGR/BGBG"; break;
1322ba300204SHans Verkuil 	case V4L2_PIX_FMT_SRGGB8:	descr = "8-bit Bayer RGRG/GBGB"; break;
1323ba300204SHans Verkuil 	case V4L2_PIX_FMT_SBGGR10:	descr = "10-bit Bayer BGBG/GRGR"; break;
1324ba300204SHans Verkuil 	case V4L2_PIX_FMT_SGBRG10:	descr = "10-bit Bayer GBGB/RGRG"; break;
1325ba300204SHans Verkuil 	case V4L2_PIX_FMT_SGRBG10:	descr = "10-bit Bayer GRGR/BGBG"; break;
1326ba300204SHans Verkuil 	case V4L2_PIX_FMT_SRGGB10:	descr = "10-bit Bayer RGRG/GBGB"; break;
1327ba300204SHans Verkuil 	case V4L2_PIX_FMT_SBGGR10P:	descr = "10-bit Bayer BGBG/GRGR Packed"; break;
1328ba300204SHans Verkuil 	case V4L2_PIX_FMT_SGBRG10P:	descr = "10-bit Bayer GBGB/RGRG Packed"; break;
1329ba300204SHans Verkuil 	case V4L2_PIX_FMT_SGRBG10P:	descr = "10-bit Bayer GRGR/BGBG Packed"; break;
1330ba300204SHans Verkuil 	case V4L2_PIX_FMT_SRGGB10P:	descr = "10-bit Bayer RGRG/GBGB Packed"; break;
1331e8391b76SYong Zhi 	case V4L2_PIX_FMT_IPU3_SBGGR10: descr = "10-bit bayer BGGR IPU3 Packed"; break;
1332e8391b76SYong Zhi 	case V4L2_PIX_FMT_IPU3_SGBRG10: descr = "10-bit bayer GBRG IPU3 Packed"; break;
1333e8391b76SYong Zhi 	case V4L2_PIX_FMT_IPU3_SGRBG10: descr = "10-bit bayer GRBG IPU3 Packed"; break;
1334e8391b76SYong Zhi 	case V4L2_PIX_FMT_IPU3_SRGGB10: descr = "10-bit bayer RGGB IPU3 Packed"; break;
1335ba300204SHans Verkuil 	case V4L2_PIX_FMT_SBGGR10ALAW8:	descr = "8-bit Bayer BGBG/GRGR (A-law)"; break;
1336ba300204SHans Verkuil 	case V4L2_PIX_FMT_SGBRG10ALAW8:	descr = "8-bit Bayer GBGB/RGRG (A-law)"; break;
1337ba300204SHans Verkuil 	case V4L2_PIX_FMT_SGRBG10ALAW8:	descr = "8-bit Bayer GRGR/BGBG (A-law)"; break;
1338ba300204SHans Verkuil 	case V4L2_PIX_FMT_SRGGB10ALAW8:	descr = "8-bit Bayer RGRG/GBGB (A-law)"; break;
1339ba300204SHans Verkuil 	case V4L2_PIX_FMT_SBGGR10DPCM8:	descr = "8-bit Bayer BGBG/GRGR (DPCM)"; break;
1340ba300204SHans Verkuil 	case V4L2_PIX_FMT_SGBRG10DPCM8:	descr = "8-bit Bayer GBGB/RGRG (DPCM)"; break;
1341ba300204SHans Verkuil 	case V4L2_PIX_FMT_SGRBG10DPCM8:	descr = "8-bit Bayer GRGR/BGBG (DPCM)"; break;
1342ba300204SHans Verkuil 	case V4L2_PIX_FMT_SRGGB10DPCM8:	descr = "8-bit Bayer RGRG/GBGB (DPCM)"; break;
1343d1b3437eSSakari Ailus 	case V4L2_PIX_FMT_SBGGR12:	descr = "12-bit Bayer BGBG/GRGR"; break;
1344d1b3437eSSakari Ailus 	case V4L2_PIX_FMT_SGBRG12:	descr = "12-bit Bayer GBGB/RGRG"; break;
1345d1b3437eSSakari Ailus 	case V4L2_PIX_FMT_SGRBG12:	descr = "12-bit Bayer GRGR/BGBG"; break;
1346d1b3437eSSakari Ailus 	case V4L2_PIX_FMT_SRGGB12:	descr = "12-bit Bayer RGRG/GBGB"; break;
1347d1b3437eSSakari Ailus 	case V4L2_PIX_FMT_SBGGR12P:	descr = "12-bit Bayer BGBG/GRGR Packed"; break;
1348d1b3437eSSakari Ailus 	case V4L2_PIX_FMT_SGBRG12P:	descr = "12-bit Bayer GBGB/RGRG Packed"; break;
1349d1b3437eSSakari Ailus 	case V4L2_PIX_FMT_SGRBG12P:	descr = "12-bit Bayer GRGR/BGBG Packed"; break;
1350d1b3437eSSakari Ailus 	case V4L2_PIX_FMT_SRGGB12P:	descr = "12-bit Bayer RGRG/GBGB Packed"; break;
1351d12127edSSakari Ailus 	case V4L2_PIX_FMT_SBGGR14:	descr = "14-bit Bayer BGBG/GRGR"; break;
1352d12127edSSakari Ailus 	case V4L2_PIX_FMT_SGBRG14:	descr = "14-bit Bayer GBGB/RGRG"; break;
1353d12127edSSakari Ailus 	case V4L2_PIX_FMT_SGRBG14:	descr = "14-bit Bayer GRGR/BGBG"; break;
1354d12127edSSakari Ailus 	case V4L2_PIX_FMT_SRGGB14:	descr = "14-bit Bayer RGRG/GBGB"; break;
135583b15832SSakari Ailus 	case V4L2_PIX_FMT_SBGGR14P:	descr = "14-bit Bayer BGBG/GRGR Packed"; break;
135683b15832SSakari Ailus 	case V4L2_PIX_FMT_SGBRG14P:	descr = "14-bit Bayer GBGB/RGRG Packed"; break;
135783b15832SSakari Ailus 	case V4L2_PIX_FMT_SGRBG14P:	descr = "14-bit Bayer GRGR/BGBG Packed"; break;
135883b15832SSakari Ailus 	case V4L2_PIX_FMT_SRGGB14P:	descr = "14-bit Bayer RGRG/GBGB Packed"; break;
1359b9a4b13cSSakari Ailus 	case V4L2_PIX_FMT_SBGGR16:	descr = "16-bit Bayer BGBG/GRGR"; break;
1360b9a4b13cSSakari Ailus 	case V4L2_PIX_FMT_SGBRG16:	descr = "16-bit Bayer GBGB/RGRG"; break;
1361b9a4b13cSSakari Ailus 	case V4L2_PIX_FMT_SGRBG16:	descr = "16-bit Bayer GRGR/BGBG"; break;
1362b9a4b13cSSakari Ailus 	case V4L2_PIX_FMT_SRGGB16:	descr = "16-bit Bayer RGRG/GBGB"; break;
136399b74277SMauro Carvalho Chehab 	case V4L2_PIX_FMT_SN9C20X_I420:	descr = "GSPCA SN9C20X I420"; break;
1364ba300204SHans Verkuil 	case V4L2_PIX_FMT_SPCA501:	descr = "GSPCA SPCA501"; break;
1365ba300204SHans Verkuil 	case V4L2_PIX_FMT_SPCA505:	descr = "GSPCA SPCA505"; break;
1366ba300204SHans Verkuil 	case V4L2_PIX_FMT_SPCA508:	descr = "GSPCA SPCA508"; break;
1367ba300204SHans Verkuil 	case V4L2_PIX_FMT_STV0680:	descr = "GSPCA STV0680"; break;
1368ba300204SHans Verkuil 	case V4L2_PIX_FMT_TM6000:	descr = "A/V + VBI Mux Packet"; break;
1369ba300204SHans Verkuil 	case V4L2_PIX_FMT_CIT_YYVYUY:	descr = "GSPCA CIT YYVYUY"; break;
1370ba300204SHans Verkuil 	case V4L2_PIX_FMT_KONICA420:	descr = "GSPCA KONICA420"; break;
1371ffe5350cSAlexandre Courbot 	case V4L2_PIX_FMT_MM21:		descr = "Mediatek 8-bit Block Format"; break;
137266b2ab27SRicardo Ribalda Delgado 	case V4L2_PIX_FMT_HSV24:	descr = "24-bit HSV 8-8-8"; break;
137366b2ab27SRicardo Ribalda Delgado 	case V4L2_PIX_FMT_HSV32:	descr = "32-bit XHSV 8-8-8-8"; break;
137448fc10aaSAntti Palosaari 	case V4L2_SDR_FMT_CU8:		descr = "Complex U8"; break;
137548fc10aaSAntti Palosaari 	case V4L2_SDR_FMT_CU16LE:	descr = "Complex U16LE"; break;
1376ba300204SHans Verkuil 	case V4L2_SDR_FMT_CS8:		descr = "Complex S8"; break;
1377ba300204SHans Verkuil 	case V4L2_SDR_FMT_CS14LE:	descr = "Complex S14LE"; break;
1378ba300204SHans Verkuil 	case V4L2_SDR_FMT_RU12LE:	descr = "Real U12LE"; break;
1379c28f2118SRamesh Shanmugasundaram 	case V4L2_SDR_FMT_PCU16BE:	descr = "Planar Complex U16BE"; break;
1380c28f2118SRamesh Shanmugasundaram 	case V4L2_SDR_FMT_PCU18BE:	descr = "Planar Complex U18BE"; break;
1381c28f2118SRamesh Shanmugasundaram 	case V4L2_SDR_FMT_PCU20BE:	descr = "Planar Complex U20BE"; break;
13824747bd0fSHans Verkuil 	case V4L2_TCH_FMT_DELTA_TD16:	descr = "16-bit Signed Deltas"; break;
13834747bd0fSHans Verkuil 	case V4L2_TCH_FMT_DELTA_TD08:	descr = "8-bit Signed Deltas"; break;
13844747bd0fSHans Verkuil 	case V4L2_TCH_FMT_TU16:		descr = "16-bit Unsigned Touch Data"; break;
13854747bd0fSHans Verkuil 	case V4L2_TCH_FMT_TU08:		descr = "8-bit Unsigned Touch Data"; break;
138614d66538SLaurent Pinchart 	case V4L2_META_FMT_VSP1_HGO:	descr = "R-Car VSP1 1-D Histogram"; break;
13875deb1c04SNiklas Söderlund 	case V4L2_META_FMT_VSP1_HGT:	descr = "R-Car VSP1 2-D Histogram"; break;
13884747bd0fSHans Verkuil 	case V4L2_META_FMT_UVC:		descr = "UVC Payload Header Metadata"; break;
13894747bd0fSHans Verkuil 	case V4L2_META_FMT_D4XX:	descr = "Intel D4xx UVC Metadata"; break;
139078892b6bSVandana BN 	case V4L2_META_FMT_VIVID:       descr = "Vivid Metadata"; break;
1391df22026aSShunqian Zheng 	case V4L2_META_FMT_RK_ISP1_PARAMS:	descr = "Rockchip ISP1 3A Parameters"; break;
1392df22026aSShunqian Zheng 	case V4L2_META_FMT_RK_ISP1_STAT_3A:	descr = "Rockchip ISP1 3A Statistics"; break;
1393*72a74c8fSMing Qian 	case V4L2_PIX_FMT_NV12M_8L128:	descr = "NV12M (8x128 Linear)"; break;
1394*72a74c8fSMing Qian 	case V4L2_PIX_FMT_NV12M_10BE_8L128:	descr = "10-bit NV12M (8x128 Linear, BE)"; break;
1395ba300204SHans Verkuil 
1396ba300204SHans Verkuil 	default:
1397ba300204SHans Verkuil 		/* Compressed formats */
1398ba300204SHans Verkuil 		flags = V4L2_FMT_FLAG_COMPRESSED;
1399ba300204SHans Verkuil 		switch (fmt->pixelformat) {
1400ba300204SHans Verkuil 		/* Max description length mask:	descr = "0123456789012345678901234567890" */
1401ba300204SHans Verkuil 		case V4L2_PIX_FMT_MJPEG:	descr = "Motion-JPEG"; break;
1402ba300204SHans Verkuil 		case V4L2_PIX_FMT_JPEG:		descr = "JFIF JPEG"; break;
1403ba300204SHans Verkuil 		case V4L2_PIX_FMT_DV:		descr = "1394"; break;
1404ba300204SHans Verkuil 		case V4L2_PIX_FMT_MPEG:		descr = "MPEG-1/2/4"; break;
1405ba300204SHans Verkuil 		case V4L2_PIX_FMT_H264:		descr = "H.264"; break;
1406ba300204SHans Verkuil 		case V4L2_PIX_FMT_H264_NO_SC:	descr = "H.264 (No Start Codes)"; break;
1407ba300204SHans Verkuil 		case V4L2_PIX_FMT_H264_MVC:	descr = "H.264 MVC"; break;
14087bb3c32aSEzequiel Garcia 		case V4L2_PIX_FMT_H264_SLICE:	descr = "H.264 Parsed Slice Data"; break;
1409ba300204SHans Verkuil 		case V4L2_PIX_FMT_H263:		descr = "H.263"; break;
1410ba300204SHans Verkuil 		case V4L2_PIX_FMT_MPEG1:	descr = "MPEG-1 ES"; break;
1411ba300204SHans Verkuil 		case V4L2_PIX_FMT_MPEG2:	descr = "MPEG-2 ES"; break;
1412c27bb30eSPaul Kocialkowski 		case V4L2_PIX_FMT_MPEG2_SLICE:	descr = "MPEG-2 Parsed Slice Data"; break;
14134747bd0fSHans Verkuil 		case V4L2_PIX_FMT_MPEG4:	descr = "MPEG-4 Part 2 ES"; break;
1414ba300204SHans Verkuil 		case V4L2_PIX_FMT_XVID:		descr = "Xvid"; break;
1415ba300204SHans Verkuil 		case V4L2_PIX_FMT_VC1_ANNEX_G:	descr = "VC-1 (SMPTE 412M Annex G)"; break;
1416ba300204SHans Verkuil 		case V4L2_PIX_FMT_VC1_ANNEX_L:	descr = "VC-1 (SMPTE 412M Annex L)"; break;
1417ba300204SHans Verkuil 		case V4L2_PIX_FMT_VP8:		descr = "VP8"; break;
1418a57d6acaSPawel Osciak 		case V4L2_PIX_FMT_VP8_FRAME:    descr = "VP8 Frame"; break;
1419fa14a564SWu-Cheng Li 		case V4L2_PIX_FMT_VP9:		descr = "VP9"; break;
1420b88dbe38SAndrzej Pietrasiewicz 		case V4L2_PIX_FMT_VP9_FRAME:    descr = "VP9 Frame"; break;
14211c791727SSmitha T Murthy 		case V4L2_PIX_FMT_HEVC:		descr = "HEVC"; break; /* aka H.265 */
1422256fa392SPaul Kocialkowski 		case V4L2_PIX_FMT_HEVC_SLICE:	descr = "HEVC Parsed Slice Data"; break;
142362c3fce0SHans Verkuil 		case V4L2_PIX_FMT_FWHT:		descr = "FWHT"; break; /* used in vicodec */
1424f05a51b9SHans Verkuil 		case V4L2_PIX_FMT_FWHT_STATELESS:	descr = "FWHT Stateless"; break; /* used in vicodec */
1425ba300204SHans Verkuil 		case V4L2_PIX_FMT_CPIA1:	descr = "GSPCA CPiA YUV"; break;
1426ba300204SHans Verkuil 		case V4L2_PIX_FMT_WNVA:		descr = "WNVA"; break;
1427ba300204SHans Verkuil 		case V4L2_PIX_FMT_SN9C10X:	descr = "GSPCA SN9C10X"; break;
1428ba300204SHans Verkuil 		case V4L2_PIX_FMT_PWC1:		descr = "Raw Philips Webcam Type (Old)"; break;
1429ba300204SHans Verkuil 		case V4L2_PIX_FMT_PWC2:		descr = "Raw Philips Webcam Type (New)"; break;
1430ba300204SHans Verkuil 		case V4L2_PIX_FMT_ET61X251:	descr = "GSPCA ET61X251"; break;
1431ba300204SHans Verkuil 		case V4L2_PIX_FMT_SPCA561:	descr = "GSPCA SPCA561"; break;
1432ba300204SHans Verkuil 		case V4L2_PIX_FMT_PAC207:	descr = "GSPCA PAC207"; break;
1433ba300204SHans Verkuil 		case V4L2_PIX_FMT_MR97310A:	descr = "GSPCA MR97310A"; break;
1434ba300204SHans Verkuil 		case V4L2_PIX_FMT_JL2005BCD:	descr = "GSPCA JL2005BCD"; break;
1435ba300204SHans Verkuil 		case V4L2_PIX_FMT_SN9C2028:	descr = "GSPCA SN9C2028"; break;
1436ba300204SHans Verkuil 		case V4L2_PIX_FMT_SQ905C:	descr = "GSPCA SQ905C"; break;
1437ba300204SHans Verkuil 		case V4L2_PIX_FMT_PJPG:		descr = "GSPCA PJPG"; break;
1438ba300204SHans Verkuil 		case V4L2_PIX_FMT_OV511:	descr = "GSPCA OV511"; break;
1439ba300204SHans Verkuil 		case V4L2_PIX_FMT_OV518:	descr = "GSPCA OV518"; break;
1440ba300204SHans Verkuil 		case V4L2_PIX_FMT_JPGL:		descr = "JPEG Lite"; break;
1441ba300204SHans Verkuil 		case V4L2_PIX_FMT_SE401:	descr = "GSPCA SE401"; break;
1442ba300204SHans Verkuil 		case V4L2_PIX_FMT_S5C_UYVY_JPG:	descr = "S5C73MX interleaved UYVY/JPEG"; break;
1443d4de6634STiffany Lin 		case V4L2_PIX_FMT_MT21C:	descr = "Mediatek Compressed Format"; break;
1444ba300204SHans Verkuil 		default:
1445ba300204SHans Verkuil 			if (fmt->description[0])
1446ba300204SHans Verkuil 				return;
1447c2286cc0SSakari Ailus 			WARN(1, "Unknown pixelformat 0x%08x\n", fmt->pixelformat);
1448ba300204SHans Verkuil 			flags = 0;
1449e927e1e0SSakari Ailus 			snprintf(fmt->description, sz, "%p4cc",
1450e927e1e0SSakari Ailus 				 &fmt->pixelformat);
1451ba300204SHans Verkuil 			break;
1452ba300204SHans Verkuil 		}
1453ba300204SHans Verkuil 	}
1454ba300204SHans Verkuil 
1455ba300204SHans Verkuil 	if (descr)
1456e7dd89ceSHans Petter Selasky 		WARN_ON(strscpy(fmt->description, descr, sz) < 0);
14577c490e25SHans Verkuil 	fmt->flags |= flags;
1458ba300204SHans Verkuil }
1459ba300204SHans Verkuil 
14605bc3cb74SMauro Carvalho Chehab static int v4l_enum_fmt(const struct v4l2_ioctl_ops *ops,
14615bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
14625bc3cb74SMauro Carvalho Chehab {
14637e98b7b5SBoris Brezillon 	struct video_device *vdev = video_devdata(file);
14645bc3cb74SMauro Carvalho Chehab 	struct v4l2_fmtdesc *p = arg;
1465b2469c81SHans Verkuil 	int ret = check_fmt(file, p->type);
1466e5b6b07aSLaurent Pinchart 	u32 mbus_code;
1467f0d2b7a8SBoris Brezillon 	u32 cap_mask;
1468b2469c81SHans Verkuil 
1469b2469c81SHans Verkuil 	if (ret)
1470b2469c81SHans Verkuil 		return ret;
1471b2469c81SHans Verkuil 	ret = -EINVAL;
14725bc3cb74SMauro Carvalho Chehab 
1473e5b6b07aSLaurent Pinchart 	if (!(vdev->device_caps & V4L2_CAP_IO_MC))
1474e5b6b07aSLaurent Pinchart 		p->mbus_code = 0;
1475e5b6b07aSLaurent Pinchart 
1476e5b6b07aSLaurent Pinchart 	mbus_code = p->mbus_code;
1477e5b6b07aSLaurent Pinchart 	CLEAR_AFTER_FIELD(p, type);
1478e5b6b07aSLaurent Pinchart 	p->mbus_code = mbus_code;
1479e5b6b07aSLaurent Pinchart 
14805bc3cb74SMauro Carvalho Chehab 	switch (p->type) {
14815bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_CAPTURE:
14827e98b7b5SBoris Brezillon 	case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
1483f0d2b7a8SBoris Brezillon 		cap_mask = V4L2_CAP_VIDEO_CAPTURE_MPLANE |
1484f0d2b7a8SBoris Brezillon 			   V4L2_CAP_VIDEO_M2M_MPLANE;
1485f0d2b7a8SBoris Brezillon 		if (!!(vdev->device_caps & cap_mask) !=
14867e98b7b5SBoris Brezillon 		    (p->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE))
14877e98b7b5SBoris Brezillon 			break;
14887e98b7b5SBoris Brezillon 
1489b2469c81SHans Verkuil 		if (unlikely(!ops->vidioc_enum_fmt_vid_cap))
14905bc3cb74SMauro Carvalho Chehab 			break;
1491ba300204SHans Verkuil 		ret = ops->vidioc_enum_fmt_vid_cap(file, fh, arg);
1492ba300204SHans Verkuil 		break;
14935bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_OVERLAY:
1494b2469c81SHans Verkuil 		if (unlikely(!ops->vidioc_enum_fmt_vid_overlay))
14955bc3cb74SMauro Carvalho Chehab 			break;
1496ba300204SHans Verkuil 		ret = ops->vidioc_enum_fmt_vid_overlay(file, fh, arg);
1497ba300204SHans Verkuil 		break;
14985bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_OUTPUT:
14997e98b7b5SBoris Brezillon 	case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
1500f0d2b7a8SBoris Brezillon 		cap_mask = V4L2_CAP_VIDEO_OUTPUT_MPLANE |
1501f0d2b7a8SBoris Brezillon 			   V4L2_CAP_VIDEO_M2M_MPLANE;
1502f0d2b7a8SBoris Brezillon 		if (!!(vdev->device_caps & cap_mask) !=
15037e98b7b5SBoris Brezillon 		    (p->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE))
15047e98b7b5SBoris Brezillon 			break;
15057e98b7b5SBoris Brezillon 
1506b2469c81SHans Verkuil 		if (unlikely(!ops->vidioc_enum_fmt_vid_out))
15075bc3cb74SMauro Carvalho Chehab 			break;
1508ba300204SHans Verkuil 		ret = ops->vidioc_enum_fmt_vid_out(file, fh, arg);
1509ba300204SHans Verkuil 		break;
1510582c52cbSAntti Palosaari 	case V4L2_BUF_TYPE_SDR_CAPTURE:
1511b2469c81SHans Verkuil 		if (unlikely(!ops->vidioc_enum_fmt_sdr_cap))
1512582c52cbSAntti Palosaari 			break;
1513ba300204SHans Verkuil 		ret = ops->vidioc_enum_fmt_sdr_cap(file, fh, arg);
1514ba300204SHans Verkuil 		break;
15159effc72fSAntti Palosaari 	case V4L2_BUF_TYPE_SDR_OUTPUT:
1516b2469c81SHans Verkuil 		if (unlikely(!ops->vidioc_enum_fmt_sdr_out))
15179effc72fSAntti Palosaari 			break;
15189effc72fSAntti Palosaari 		ret = ops->vidioc_enum_fmt_sdr_out(file, fh, arg);
15199effc72fSAntti Palosaari 		break;
1520fb9ffa6aSLaurent Pinchart 	case V4L2_BUF_TYPE_META_CAPTURE:
1521b2469c81SHans Verkuil 		if (unlikely(!ops->vidioc_enum_fmt_meta_cap))
1522fb9ffa6aSLaurent Pinchart 			break;
1523fb9ffa6aSLaurent Pinchart 		ret = ops->vidioc_enum_fmt_meta_cap(file, fh, arg);
1524fb9ffa6aSLaurent Pinchart 		break;
152572148d1aSSakari Ailus 	case V4L2_BUF_TYPE_META_OUTPUT:
152672148d1aSSakari Ailus 		if (unlikely(!ops->vidioc_enum_fmt_meta_out))
152772148d1aSSakari Ailus 			break;
152872148d1aSSakari Ailus 		ret = ops->vidioc_enum_fmt_meta_out(file, fh, arg);
152972148d1aSSakari Ailus 		break;
15305bc3cb74SMauro Carvalho Chehab 	}
1531ba300204SHans Verkuil 	if (ret == 0)
1532ba300204SHans Verkuil 		v4l_fill_fmtdesc(p);
1533ba300204SHans Verkuil 	return ret;
15345bc3cb74SMauro Carvalho Chehab }
15355bc3cb74SMauro Carvalho Chehab 
1536545b618cSVandana BN static void v4l_pix_format_touch(struct v4l2_pix_format *p)
1537545b618cSVandana BN {
1538545b618cSVandana BN 	/*
1539545b618cSVandana BN 	 * The v4l2_pix_format structure contains fields that make no sense for
1540545b618cSVandana BN 	 * touch. Set them to default values in this case.
1541545b618cSVandana BN 	 */
1542545b618cSVandana BN 
1543545b618cSVandana BN 	p->field = V4L2_FIELD_NONE;
1544545b618cSVandana BN 	p->colorspace = V4L2_COLORSPACE_RAW;
1545545b618cSVandana BN 	p->flags = 0;
1546545b618cSVandana BN 	p->ycbcr_enc = 0;
1547545b618cSVandana BN 	p->quantization = 0;
1548545b618cSVandana BN 	p->xfer_func = 0;
1549545b618cSVandana BN }
1550545b618cSVandana BN 
15515bc3cb74SMauro Carvalho Chehab static int v4l_g_fmt(const struct v4l2_ioctl_ops *ops,
15525bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
15535bc3cb74SMauro Carvalho Chehab {
15545bc3cb74SMauro Carvalho Chehab 	struct v4l2_format *p = arg;
1555545b618cSVandana BN 	struct video_device *vfd = video_devdata(file);
1556b2469c81SHans Verkuil 	int ret = check_fmt(file, p->type);
1557b2469c81SHans Verkuil 
1558b2469c81SHans Verkuil 	if (ret)
1559b2469c81SHans Verkuil 		return ret;
1560d52e2381SLaurent Pinchart 
1561e5ce558aSHans Verkuil 	/*
1562e5ce558aSHans Verkuil 	 * fmt can't be cleared for these overlay types due to the 'clips'
1563e5ce558aSHans Verkuil 	 * 'clipcount' and 'bitmap' pointers in struct v4l2_window.
1564e5ce558aSHans Verkuil 	 * Those are provided by the user. So handle these two overlay types
1565e5ce558aSHans Verkuil 	 * first, and then just do a simple memset for the other types.
1566e5ce558aSHans Verkuil 	 */
1567e5ce558aSHans Verkuil 	switch (p->type) {
1568e5ce558aSHans Verkuil 	case V4L2_BUF_TYPE_VIDEO_OVERLAY:
1569e5ce558aSHans Verkuil 	case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY: {
15703f65c6f6SArnd Bergmann 		struct v4l2_clip *clips = p->fmt.win.clips;
1571e5ce558aSHans Verkuil 		u32 clipcount = p->fmt.win.clipcount;
15724d1afa51SHans Verkuil 		void __user *bitmap = p->fmt.win.bitmap;
1573e5ce558aSHans Verkuil 
1574e5ce558aSHans Verkuil 		memset(&p->fmt, 0, sizeof(p->fmt));
1575e5ce558aSHans Verkuil 		p->fmt.win.clips = clips;
1576e5ce558aSHans Verkuil 		p->fmt.win.clipcount = clipcount;
1577e5ce558aSHans Verkuil 		p->fmt.win.bitmap = bitmap;
1578e5ce558aSHans Verkuil 		break;
1579e5ce558aSHans Verkuil 	}
1580e5ce558aSHans Verkuil 	default:
1581e5ce558aSHans Verkuil 		memset(&p->fmt, 0, sizeof(p->fmt));
1582e5ce558aSHans Verkuil 		break;
1583e5ce558aSHans Verkuil 	}
1584e5ce558aSHans Verkuil 
15855bc3cb74SMauro Carvalho Chehab 	switch (p->type) {
15865bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_CAPTURE:
1587b2469c81SHans Verkuil 		if (unlikely(!ops->vidioc_g_fmt_vid_cap))
15885bc3cb74SMauro Carvalho Chehab 			break;
158948f2650aSHans Verkuil 		p->fmt.pix.priv = V4L2_PIX_FMT_PRIV_MAGIC;
1590d52e2381SLaurent Pinchart 		ret = ops->vidioc_g_fmt_vid_cap(file, fh, arg);
159148f2650aSHans Verkuil 		/* just in case the driver zeroed it again */
1592d52e2381SLaurent Pinchart 		p->fmt.pix.priv = V4L2_PIX_FMT_PRIV_MAGIC;
1593545b618cSVandana BN 		if (vfd->vfl_type == VFL_TYPE_TOUCH)
1594545b618cSVandana BN 			v4l_pix_format_touch(&p->fmt.pix);
1595d52e2381SLaurent Pinchart 		return ret;
15965bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
15975bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_g_fmt_vid_cap_mplane(file, fh, arg);
15985bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_OVERLAY:
15995bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_g_fmt_vid_overlay(file, fh, arg);
16004b20259fSHans Verkuil 	case V4L2_BUF_TYPE_VBI_CAPTURE:
16014b20259fSHans Verkuil 		return ops->vidioc_g_fmt_vbi_cap(file, fh, arg);
16024b20259fSHans Verkuil 	case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
16034b20259fSHans Verkuil 		return ops->vidioc_g_fmt_sliced_vbi_cap(file, fh, arg);
16045bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_OUTPUT:
1605b2469c81SHans Verkuil 		if (unlikely(!ops->vidioc_g_fmt_vid_out))
16065bc3cb74SMauro Carvalho Chehab 			break;
160748f2650aSHans Verkuil 		p->fmt.pix.priv = V4L2_PIX_FMT_PRIV_MAGIC;
1608d52e2381SLaurent Pinchart 		ret = ops->vidioc_g_fmt_vid_out(file, fh, arg);
160948f2650aSHans Verkuil 		/* just in case the driver zeroed it again */
1610d52e2381SLaurent Pinchart 		p->fmt.pix.priv = V4L2_PIX_FMT_PRIV_MAGIC;
1611d52e2381SLaurent Pinchart 		return ret;
16125bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
16135bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_g_fmt_vid_out_mplane(file, fh, arg);
16145bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
16155bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_g_fmt_vid_out_overlay(file, fh, arg);
16165bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VBI_OUTPUT:
16175bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_g_fmt_vbi_out(file, fh, arg);
16185bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
16195bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_g_fmt_sliced_vbi_out(file, fh, arg);
1620582c52cbSAntti Palosaari 	case V4L2_BUF_TYPE_SDR_CAPTURE:
1621582c52cbSAntti Palosaari 		return ops->vidioc_g_fmt_sdr_cap(file, fh, arg);
16229effc72fSAntti Palosaari 	case V4L2_BUF_TYPE_SDR_OUTPUT:
16239effc72fSAntti Palosaari 		return ops->vidioc_g_fmt_sdr_out(file, fh, arg);
1624fb9ffa6aSLaurent Pinchart 	case V4L2_BUF_TYPE_META_CAPTURE:
1625fb9ffa6aSLaurent Pinchart 		return ops->vidioc_g_fmt_meta_cap(file, fh, arg);
162672148d1aSSakari Ailus 	case V4L2_BUF_TYPE_META_OUTPUT:
162772148d1aSSakari Ailus 		return ops->vidioc_g_fmt_meta_out(file, fh, arg);
16285bc3cb74SMauro Carvalho Chehab 	}
16295bc3cb74SMauro Carvalho Chehab 	return -EINVAL;
16305bc3cb74SMauro Carvalho Chehab }
16315bc3cb74SMauro Carvalho Chehab 
16325bc3cb74SMauro Carvalho Chehab static int v4l_s_fmt(const struct v4l2_ioctl_ops *ops,
16335bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
16345bc3cb74SMauro Carvalho Chehab {
16355bc3cb74SMauro Carvalho Chehab 	struct v4l2_format *p = arg;
16364b20259fSHans Verkuil 	struct video_device *vfd = video_devdata(file);
1637b2469c81SHans Verkuil 	int ret = check_fmt(file, p->type);
16384e1e0eb0SEzequiel Garcia 	unsigned int i;
1639b2469c81SHans Verkuil 
1640b2469c81SHans Verkuil 	if (ret)
1641b2469c81SHans Verkuil 		return ret;
16425bc3cb74SMauro Carvalho Chehab 
164377fa4e07SShuah Khan 	ret = v4l_enable_media_source(vfd);
164477fa4e07SShuah Khan 	if (ret)
164577fa4e07SShuah Khan 		return ret;
1646d52e2381SLaurent Pinchart 	v4l_sanitize_format(p);
1647d52e2381SLaurent Pinchart 
16485bc3cb74SMauro Carvalho Chehab 	switch (p->type) {
16495bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_CAPTURE:
1650b2469c81SHans Verkuil 		if (unlikely(!ops->vidioc_s_fmt_vid_cap))
16515bc3cb74SMauro Carvalho Chehab 			break;
16525bc3cb74SMauro Carvalho Chehab 		CLEAR_AFTER_FIELD(p, fmt.pix);
165348f2650aSHans Verkuil 		ret = ops->vidioc_s_fmt_vid_cap(file, fh, arg);
165448f2650aSHans Verkuil 		/* just in case the driver zeroed it again */
165548f2650aSHans Verkuil 		p->fmt.pix.priv = V4L2_PIX_FMT_PRIV_MAGIC;
1656b2469c81SHans Verkuil 		if (vfd->vfl_type == VFL_TYPE_TOUCH)
1657b2fe22d0SNick Dyer 			v4l_pix_format_touch(&p->fmt.pix);
165848f2650aSHans Verkuil 		return ret;
16595bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
1660b2469c81SHans Verkuil 		if (unlikely(!ops->vidioc_s_fmt_vid_cap_mplane))
16615bc3cb74SMauro Carvalho Chehab 			break;
1662c49148e8SLaurent Pinchart 		CLEAR_AFTER_FIELD(p, fmt.pix_mp.xfer_func);
16634e1e0eb0SEzequiel Garcia 		for (i = 0; i < p->fmt.pix_mp.num_planes; i++)
1664dd91642aSThierry Reding 			CLEAR_AFTER_FIELD(&p->fmt.pix_mp.plane_fmt[i],
1665dd91642aSThierry Reding 					  bytesperline);
16665bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_s_fmt_vid_cap_mplane(file, fh, arg);
16675bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_OVERLAY:
1668b2469c81SHans Verkuil 		if (unlikely(!ops->vidioc_s_fmt_vid_overlay))
16695bc3cb74SMauro Carvalho Chehab 			break;
16705bc3cb74SMauro Carvalho Chehab 		CLEAR_AFTER_FIELD(p, fmt.win);
16715bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_s_fmt_vid_overlay(file, fh, arg);
16724b20259fSHans Verkuil 	case V4L2_BUF_TYPE_VBI_CAPTURE:
1673b2469c81SHans Verkuil 		if (unlikely(!ops->vidioc_s_fmt_vbi_cap))
16744b20259fSHans Verkuil 			break;
1675ee8951e5SHans Verkuil 		CLEAR_AFTER_FIELD(p, fmt.vbi.flags);
16764b20259fSHans Verkuil 		return ops->vidioc_s_fmt_vbi_cap(file, fh, arg);
16774b20259fSHans Verkuil 	case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
1678b2469c81SHans Verkuil 		if (unlikely(!ops->vidioc_s_fmt_sliced_vbi_cap))
16794b20259fSHans Verkuil 			break;
1680ee8951e5SHans Verkuil 		CLEAR_AFTER_FIELD(p, fmt.sliced.io_size);
16814b20259fSHans Verkuil 		return ops->vidioc_s_fmt_sliced_vbi_cap(file, fh, arg);
16825bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_OUTPUT:
1683b2469c81SHans Verkuil 		if (unlikely(!ops->vidioc_s_fmt_vid_out))
16845bc3cb74SMauro Carvalho Chehab 			break;
16855bc3cb74SMauro Carvalho Chehab 		CLEAR_AFTER_FIELD(p, fmt.pix);
168648f2650aSHans Verkuil 		ret = ops->vidioc_s_fmt_vid_out(file, fh, arg);
168748f2650aSHans Verkuil 		/* just in case the driver zeroed it again */
168848f2650aSHans Verkuil 		p->fmt.pix.priv = V4L2_PIX_FMT_PRIV_MAGIC;
168948f2650aSHans Verkuil 		return ret;
16905bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
1691b2469c81SHans Verkuil 		if (unlikely(!ops->vidioc_s_fmt_vid_out_mplane))
16925bc3cb74SMauro Carvalho Chehab 			break;
1693c49148e8SLaurent Pinchart 		CLEAR_AFTER_FIELD(p, fmt.pix_mp.xfer_func);
16944e1e0eb0SEzequiel Garcia 		for (i = 0; i < p->fmt.pix_mp.num_planes; i++)
1695dd91642aSThierry Reding 			CLEAR_AFTER_FIELD(&p->fmt.pix_mp.plane_fmt[i],
1696dd91642aSThierry Reding 					  bytesperline);
16975bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_s_fmt_vid_out_mplane(file, fh, arg);
16985bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
1699b2469c81SHans Verkuil 		if (unlikely(!ops->vidioc_s_fmt_vid_out_overlay))
17005bc3cb74SMauro Carvalho Chehab 			break;
17015bc3cb74SMauro Carvalho Chehab 		CLEAR_AFTER_FIELD(p, fmt.win);
17025bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_s_fmt_vid_out_overlay(file, fh, arg);
17035bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VBI_OUTPUT:
1704b2469c81SHans Verkuil 		if (unlikely(!ops->vidioc_s_fmt_vbi_out))
17055bc3cb74SMauro Carvalho Chehab 			break;
1706ee8951e5SHans Verkuil 		CLEAR_AFTER_FIELD(p, fmt.vbi.flags);
17075bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_s_fmt_vbi_out(file, fh, arg);
17085bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
1709b2469c81SHans Verkuil 		if (unlikely(!ops->vidioc_s_fmt_sliced_vbi_out))
17105bc3cb74SMauro Carvalho Chehab 			break;
1711ee8951e5SHans Verkuil 		CLEAR_AFTER_FIELD(p, fmt.sliced.io_size);
17125bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_s_fmt_sliced_vbi_out(file, fh, arg);
1713582c52cbSAntti Palosaari 	case V4L2_BUF_TYPE_SDR_CAPTURE:
1714b2469c81SHans Verkuil 		if (unlikely(!ops->vidioc_s_fmt_sdr_cap))
1715582c52cbSAntti Palosaari 			break;
1716ee8951e5SHans Verkuil 		CLEAR_AFTER_FIELD(p, fmt.sdr.buffersize);
1717582c52cbSAntti Palosaari 		return ops->vidioc_s_fmt_sdr_cap(file, fh, arg);
17189effc72fSAntti Palosaari 	case V4L2_BUF_TYPE_SDR_OUTPUT:
1719b2469c81SHans Verkuil 		if (unlikely(!ops->vidioc_s_fmt_sdr_out))
17209effc72fSAntti Palosaari 			break;
1721ee8951e5SHans Verkuil 		CLEAR_AFTER_FIELD(p, fmt.sdr.buffersize);
17229effc72fSAntti Palosaari 		return ops->vidioc_s_fmt_sdr_out(file, fh, arg);
1723fb9ffa6aSLaurent Pinchart 	case V4L2_BUF_TYPE_META_CAPTURE:
1724b2469c81SHans Verkuil 		if (unlikely(!ops->vidioc_s_fmt_meta_cap))
1725fb9ffa6aSLaurent Pinchart 			break;
1726fb9ffa6aSLaurent Pinchart 		CLEAR_AFTER_FIELD(p, fmt.meta);
1727fb9ffa6aSLaurent Pinchart 		return ops->vidioc_s_fmt_meta_cap(file, fh, arg);
172872148d1aSSakari Ailus 	case V4L2_BUF_TYPE_META_OUTPUT:
172972148d1aSSakari Ailus 		if (unlikely(!ops->vidioc_s_fmt_meta_out))
173072148d1aSSakari Ailus 			break;
173172148d1aSSakari Ailus 		CLEAR_AFTER_FIELD(p, fmt.meta);
173272148d1aSSakari Ailus 		return ops->vidioc_s_fmt_meta_out(file, fh, arg);
17335bc3cb74SMauro Carvalho Chehab 	}
17345bc3cb74SMauro Carvalho Chehab 	return -EINVAL;
17355bc3cb74SMauro Carvalho Chehab }
17365bc3cb74SMauro Carvalho Chehab 
17375bc3cb74SMauro Carvalho Chehab static int v4l_try_fmt(const struct v4l2_ioctl_ops *ops,
17385bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
17395bc3cb74SMauro Carvalho Chehab {
17405bc3cb74SMauro Carvalho Chehab 	struct v4l2_format *p = arg;
1741999a4312SHans Verkuil 	struct video_device *vfd = video_devdata(file);
1742b2469c81SHans Verkuil 	int ret = check_fmt(file, p->type);
17434e1e0eb0SEzequiel Garcia 	unsigned int i;
1744b2469c81SHans Verkuil 
1745b2469c81SHans Verkuil 	if (ret)
1746b2469c81SHans Verkuil 		return ret;
17475bc3cb74SMauro Carvalho Chehab 
1748d52e2381SLaurent Pinchart 	v4l_sanitize_format(p);
1749d52e2381SLaurent Pinchart 
17505bc3cb74SMauro Carvalho Chehab 	switch (p->type) {
17515bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_CAPTURE:
1752b2469c81SHans Verkuil 		if (unlikely(!ops->vidioc_try_fmt_vid_cap))
17535bc3cb74SMauro Carvalho Chehab 			break;
17545bc3cb74SMauro Carvalho Chehab 		CLEAR_AFTER_FIELD(p, fmt.pix);
175548f2650aSHans Verkuil 		ret = ops->vidioc_try_fmt_vid_cap(file, fh, arg);
175648f2650aSHans Verkuil 		/* just in case the driver zeroed it again */
175748f2650aSHans Verkuil 		p->fmt.pix.priv = V4L2_PIX_FMT_PRIV_MAGIC;
1758999a4312SHans Verkuil 		if (vfd->vfl_type == VFL_TYPE_TOUCH)
1759999a4312SHans Verkuil 			v4l_pix_format_touch(&p->fmt.pix);
176048f2650aSHans Verkuil 		return ret;
17615bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
1762b2469c81SHans Verkuil 		if (unlikely(!ops->vidioc_try_fmt_vid_cap_mplane))
17635bc3cb74SMauro Carvalho Chehab 			break;
1764c49148e8SLaurent Pinchart 		CLEAR_AFTER_FIELD(p, fmt.pix_mp.xfer_func);
17654e1e0eb0SEzequiel Garcia 		for (i = 0; i < p->fmt.pix_mp.num_planes; i++)
1766dd91642aSThierry Reding 			CLEAR_AFTER_FIELD(&p->fmt.pix_mp.plane_fmt[i],
1767dd91642aSThierry Reding 					  bytesperline);
17685bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_try_fmt_vid_cap_mplane(file, fh, arg);
17695bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_OVERLAY:
1770b2469c81SHans Verkuil 		if (unlikely(!ops->vidioc_try_fmt_vid_overlay))
17715bc3cb74SMauro Carvalho Chehab 			break;
17725bc3cb74SMauro Carvalho Chehab 		CLEAR_AFTER_FIELD(p, fmt.win);
17735bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_try_fmt_vid_overlay(file, fh, arg);
17744b20259fSHans Verkuil 	case V4L2_BUF_TYPE_VBI_CAPTURE:
1775b2469c81SHans Verkuil 		if (unlikely(!ops->vidioc_try_fmt_vbi_cap))
17764b20259fSHans Verkuil 			break;
1777ee8951e5SHans Verkuil 		CLEAR_AFTER_FIELD(p, fmt.vbi.flags);
17784b20259fSHans Verkuil 		return ops->vidioc_try_fmt_vbi_cap(file, fh, arg);
17794b20259fSHans Verkuil 	case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
1780b2469c81SHans Verkuil 		if (unlikely(!ops->vidioc_try_fmt_sliced_vbi_cap))
17814b20259fSHans Verkuil 			break;
1782ee8951e5SHans Verkuil 		CLEAR_AFTER_FIELD(p, fmt.sliced.io_size);
17834b20259fSHans Verkuil 		return ops->vidioc_try_fmt_sliced_vbi_cap(file, fh, arg);
17845bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_OUTPUT:
1785b2469c81SHans Verkuil 		if (unlikely(!ops->vidioc_try_fmt_vid_out))
17865bc3cb74SMauro Carvalho Chehab 			break;
17875bc3cb74SMauro Carvalho Chehab 		CLEAR_AFTER_FIELD(p, fmt.pix);
178848f2650aSHans Verkuil 		ret = ops->vidioc_try_fmt_vid_out(file, fh, arg);
178948f2650aSHans Verkuil 		/* just in case the driver zeroed it again */
179048f2650aSHans Verkuil 		p->fmt.pix.priv = V4L2_PIX_FMT_PRIV_MAGIC;
179148f2650aSHans Verkuil 		return ret;
17925bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
1793b2469c81SHans Verkuil 		if (unlikely(!ops->vidioc_try_fmt_vid_out_mplane))
17945bc3cb74SMauro Carvalho Chehab 			break;
1795c49148e8SLaurent Pinchart 		CLEAR_AFTER_FIELD(p, fmt.pix_mp.xfer_func);
17964e1e0eb0SEzequiel Garcia 		for (i = 0; i < p->fmt.pix_mp.num_planes; i++)
1797dd91642aSThierry Reding 			CLEAR_AFTER_FIELD(&p->fmt.pix_mp.plane_fmt[i],
1798dd91642aSThierry Reding 					  bytesperline);
17995bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_try_fmt_vid_out_mplane(file, fh, arg);
18005bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
1801b2469c81SHans Verkuil 		if (unlikely(!ops->vidioc_try_fmt_vid_out_overlay))
18025bc3cb74SMauro Carvalho Chehab 			break;
18035bc3cb74SMauro Carvalho Chehab 		CLEAR_AFTER_FIELD(p, fmt.win);
18045bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_try_fmt_vid_out_overlay(file, fh, arg);
18055bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VBI_OUTPUT:
1806b2469c81SHans Verkuil 		if (unlikely(!ops->vidioc_try_fmt_vbi_out))
18075bc3cb74SMauro Carvalho Chehab 			break;
1808ee8951e5SHans Verkuil 		CLEAR_AFTER_FIELD(p, fmt.vbi.flags);
18095bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_try_fmt_vbi_out(file, fh, arg);
18105bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
1811b2469c81SHans Verkuil 		if (unlikely(!ops->vidioc_try_fmt_sliced_vbi_out))
18125bc3cb74SMauro Carvalho Chehab 			break;
1813ee8951e5SHans Verkuil 		CLEAR_AFTER_FIELD(p, fmt.sliced.io_size);
18145bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_try_fmt_sliced_vbi_out(file, fh, arg);
1815582c52cbSAntti Palosaari 	case V4L2_BUF_TYPE_SDR_CAPTURE:
1816b2469c81SHans Verkuil 		if (unlikely(!ops->vidioc_try_fmt_sdr_cap))
1817582c52cbSAntti Palosaari 			break;
1818ee8951e5SHans Verkuil 		CLEAR_AFTER_FIELD(p, fmt.sdr.buffersize);
1819582c52cbSAntti Palosaari 		return ops->vidioc_try_fmt_sdr_cap(file, fh, arg);
18209effc72fSAntti Palosaari 	case V4L2_BUF_TYPE_SDR_OUTPUT:
1821b2469c81SHans Verkuil 		if (unlikely(!ops->vidioc_try_fmt_sdr_out))
18229effc72fSAntti Palosaari 			break;
1823ee8951e5SHans Verkuil 		CLEAR_AFTER_FIELD(p, fmt.sdr.buffersize);
18249effc72fSAntti Palosaari 		return ops->vidioc_try_fmt_sdr_out(file, fh, arg);
1825fb9ffa6aSLaurent Pinchart 	case V4L2_BUF_TYPE_META_CAPTURE:
1826b2469c81SHans Verkuil 		if (unlikely(!ops->vidioc_try_fmt_meta_cap))
1827fb9ffa6aSLaurent Pinchart 			break;
1828fb9ffa6aSLaurent Pinchart 		CLEAR_AFTER_FIELD(p, fmt.meta);
1829fb9ffa6aSLaurent Pinchart 		return ops->vidioc_try_fmt_meta_cap(file, fh, arg);
183072148d1aSSakari Ailus 	case V4L2_BUF_TYPE_META_OUTPUT:
183172148d1aSSakari Ailus 		if (unlikely(!ops->vidioc_try_fmt_meta_out))
183272148d1aSSakari Ailus 			break;
183372148d1aSSakari Ailus 		CLEAR_AFTER_FIELD(p, fmt.meta);
183472148d1aSSakari Ailus 		return ops->vidioc_try_fmt_meta_out(file, fh, arg);
18355bc3cb74SMauro Carvalho Chehab 	}
18365bc3cb74SMauro Carvalho Chehab 	return -EINVAL;
18375bc3cb74SMauro Carvalho Chehab }
18385bc3cb74SMauro Carvalho Chehab 
18395bc3cb74SMauro Carvalho Chehab static int v4l_streamon(const struct v4l2_ioctl_ops *ops,
18405bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
18415bc3cb74SMauro Carvalho Chehab {
18425bc3cb74SMauro Carvalho Chehab 	return ops->vidioc_streamon(file, fh, *(unsigned int *)arg);
18435bc3cb74SMauro Carvalho Chehab }
18445bc3cb74SMauro Carvalho Chehab 
18455bc3cb74SMauro Carvalho Chehab static int v4l_streamoff(const struct v4l2_ioctl_ops *ops,
18465bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
18475bc3cb74SMauro Carvalho Chehab {
18485bc3cb74SMauro Carvalho Chehab 	return ops->vidioc_streamoff(file, fh, *(unsigned int *)arg);
18495bc3cb74SMauro Carvalho Chehab }
18505bc3cb74SMauro Carvalho Chehab 
18515bc3cb74SMauro Carvalho Chehab static int v4l_g_tuner(const struct v4l2_ioctl_ops *ops,
18525bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
18535bc3cb74SMauro Carvalho Chehab {
18545bc3cb74SMauro Carvalho Chehab 	struct video_device *vfd = video_devdata(file);
18555bc3cb74SMauro Carvalho Chehab 	struct v4l2_tuner *p = arg;
18565bc3cb74SMauro Carvalho Chehab 	int err;
18575bc3cb74SMauro Carvalho Chehab 
18585bc3cb74SMauro Carvalho Chehab 	p->type = (vfd->vfl_type == VFL_TYPE_RADIO) ?
18595bc3cb74SMauro Carvalho Chehab 			V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV;
18605bc3cb74SMauro Carvalho Chehab 	err = ops->vidioc_g_tuner(file, fh, p);
18615bc3cb74SMauro Carvalho Chehab 	if (!err)
18625bc3cb74SMauro Carvalho Chehab 		p->capability |= V4L2_TUNER_CAP_FREQ_BANDS;
18635bc3cb74SMauro Carvalho Chehab 	return err;
18645bc3cb74SMauro Carvalho Chehab }
18655bc3cb74SMauro Carvalho Chehab 
18665bc3cb74SMauro Carvalho Chehab static int v4l_s_tuner(const struct v4l2_ioctl_ops *ops,
18675bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
18685bc3cb74SMauro Carvalho Chehab {
18695bc3cb74SMauro Carvalho Chehab 	struct video_device *vfd = video_devdata(file);
18705bc3cb74SMauro Carvalho Chehab 	struct v4l2_tuner *p = arg;
187177fa4e07SShuah Khan 	int ret;
18725bc3cb74SMauro Carvalho Chehab 
187377fa4e07SShuah Khan 	ret = v4l_enable_media_source(vfd);
187477fa4e07SShuah Khan 	if (ret)
187577fa4e07SShuah Khan 		return ret;
18765bc3cb74SMauro Carvalho Chehab 	p->type = (vfd->vfl_type == VFL_TYPE_RADIO) ?
18775bc3cb74SMauro Carvalho Chehab 			V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV;
18785bc3cb74SMauro Carvalho Chehab 	return ops->vidioc_s_tuner(file, fh, p);
18795bc3cb74SMauro Carvalho Chehab }
18805bc3cb74SMauro Carvalho Chehab 
18815bc3cb74SMauro Carvalho Chehab static int v4l_g_modulator(const struct v4l2_ioctl_ops *ops,
18825bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
18835bc3cb74SMauro Carvalho Chehab {
18844124a3c4SAntti Palosaari 	struct video_device *vfd = video_devdata(file);
18855bc3cb74SMauro Carvalho Chehab 	struct v4l2_modulator *p = arg;
18865bc3cb74SMauro Carvalho Chehab 	int err;
18875bc3cb74SMauro Carvalho Chehab 
18884124a3c4SAntti Palosaari 	if (vfd->vfl_type == VFL_TYPE_RADIO)
18894124a3c4SAntti Palosaari 		p->type = V4L2_TUNER_RADIO;
18904124a3c4SAntti Palosaari 
18915bc3cb74SMauro Carvalho Chehab 	err = ops->vidioc_g_modulator(file, fh, p);
18925bc3cb74SMauro Carvalho Chehab 	if (!err)
18935bc3cb74SMauro Carvalho Chehab 		p->capability |= V4L2_TUNER_CAP_FREQ_BANDS;
18945bc3cb74SMauro Carvalho Chehab 	return err;
18955bc3cb74SMauro Carvalho Chehab }
18965bc3cb74SMauro Carvalho Chehab 
18974124a3c4SAntti Palosaari static int v4l_s_modulator(const struct v4l2_ioctl_ops *ops,
18984124a3c4SAntti Palosaari 				struct file *file, void *fh, void *arg)
18994124a3c4SAntti Palosaari {
19004124a3c4SAntti Palosaari 	struct video_device *vfd = video_devdata(file);
19014124a3c4SAntti Palosaari 	struct v4l2_modulator *p = arg;
19024124a3c4SAntti Palosaari 
19034124a3c4SAntti Palosaari 	if (vfd->vfl_type == VFL_TYPE_RADIO)
19044124a3c4SAntti Palosaari 		p->type = V4L2_TUNER_RADIO;
19054124a3c4SAntti Palosaari 
19064124a3c4SAntti Palosaari 	return ops->vidioc_s_modulator(file, fh, p);
19074124a3c4SAntti Palosaari }
19084124a3c4SAntti Palosaari 
19095bc3cb74SMauro Carvalho Chehab static int v4l_g_frequency(const struct v4l2_ioctl_ops *ops,
19105bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
19115bc3cb74SMauro Carvalho Chehab {
19125bc3cb74SMauro Carvalho Chehab 	struct video_device *vfd = video_devdata(file);
19135bc3cb74SMauro Carvalho Chehab 	struct v4l2_frequency *p = arg;
19145bc3cb74SMauro Carvalho Chehab 
191584099a28SAntti Palosaari 	if (vfd->vfl_type == VFL_TYPE_SDR)
1916f3c3ececSAntti Palosaari 		p->type = V4L2_TUNER_SDR;
191784099a28SAntti Palosaari 	else
19185bc3cb74SMauro Carvalho Chehab 		p->type = (vfd->vfl_type == VFL_TYPE_RADIO) ?
19195bc3cb74SMauro Carvalho Chehab 				V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV;
19205bc3cb74SMauro Carvalho Chehab 	return ops->vidioc_g_frequency(file, fh, p);
19215bc3cb74SMauro Carvalho Chehab }
19225bc3cb74SMauro Carvalho Chehab 
19235bc3cb74SMauro Carvalho Chehab static int v4l_s_frequency(const struct v4l2_ioctl_ops *ops,
19245bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
19255bc3cb74SMauro Carvalho Chehab {
19265bc3cb74SMauro Carvalho Chehab 	struct video_device *vfd = video_devdata(file);
1927b530a447SHans Verkuil 	const struct v4l2_frequency *p = arg;
19285bc3cb74SMauro Carvalho Chehab 	enum v4l2_tuner_type type;
192977fa4e07SShuah Khan 	int ret;
19305bc3cb74SMauro Carvalho Chehab 
193177fa4e07SShuah Khan 	ret = v4l_enable_media_source(vfd);
193277fa4e07SShuah Khan 	if (ret)
193377fa4e07SShuah Khan 		return ret;
193484099a28SAntti Palosaari 	if (vfd->vfl_type == VFL_TYPE_SDR) {
1935f3c3ececSAntti Palosaari 		if (p->type != V4L2_TUNER_SDR && p->type != V4L2_TUNER_RF)
193684099a28SAntti Palosaari 			return -EINVAL;
193784099a28SAntti Palosaari 	} else {
19385bc3cb74SMauro Carvalho Chehab 		type = (vfd->vfl_type == VFL_TYPE_RADIO) ?
19395bc3cb74SMauro Carvalho Chehab 				V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV;
194084099a28SAntti Palosaari 		if (type != p->type)
19415bc3cb74SMauro Carvalho Chehab 			return -EINVAL;
194284099a28SAntti Palosaari 	}
19435bc3cb74SMauro Carvalho Chehab 	return ops->vidioc_s_frequency(file, fh, p);
19445bc3cb74SMauro Carvalho Chehab }
19455bc3cb74SMauro Carvalho Chehab 
19465bc3cb74SMauro Carvalho Chehab static int v4l_enumstd(const struct v4l2_ioctl_ops *ops,
19475bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
19485bc3cb74SMauro Carvalho Chehab {
19495bc3cb74SMauro Carvalho Chehab 	struct video_device *vfd = video_devdata(file);
19505bc3cb74SMauro Carvalho Chehab 	struct v4l2_standard *p = arg;
19515bc3cb74SMauro Carvalho Chehab 
1952aa2f8871SNiklas Söderlund 	return v4l_video_std_enumstd(p, vfd->tvnorms);
19535bc3cb74SMauro Carvalho Chehab }
19545bc3cb74SMauro Carvalho Chehab 
19555bc3cb74SMauro Carvalho Chehab static int v4l_s_std(const struct v4l2_ioctl_ops *ops,
19565bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
19575bc3cb74SMauro Carvalho Chehab {
19585bc3cb74SMauro Carvalho Chehab 	struct video_device *vfd = video_devdata(file);
1959314527acSHans Verkuil 	v4l2_std_id id = *(v4l2_std_id *)arg, norm;
196077fa4e07SShuah Khan 	int ret;
19615bc3cb74SMauro Carvalho Chehab 
196277fa4e07SShuah Khan 	ret = v4l_enable_media_source(vfd);
196377fa4e07SShuah Khan 	if (ret)
196477fa4e07SShuah Khan 		return ret;
1965314527acSHans Verkuil 	norm = id & vfd->tvnorms;
19665bc3cb74SMauro Carvalho Chehab 	if (vfd->tvnorms && !norm)	/* Check if std is supported */
19675bc3cb74SMauro Carvalho Chehab 		return -EINVAL;
19685bc3cb74SMauro Carvalho Chehab 
19695bc3cb74SMauro Carvalho Chehab 	/* Calls the specific handler */
1970ca371575SHans Verkuil 	return ops->vidioc_s_std(file, fh, norm);
19715bc3cb74SMauro Carvalho Chehab }
19725bc3cb74SMauro Carvalho Chehab 
19735bc3cb74SMauro Carvalho Chehab static int v4l_querystd(const struct v4l2_ioctl_ops *ops,
19745bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
19755bc3cb74SMauro Carvalho Chehab {
19765bc3cb74SMauro Carvalho Chehab 	struct video_device *vfd = video_devdata(file);
19775bc3cb74SMauro Carvalho Chehab 	v4l2_std_id *p = arg;
197877fa4e07SShuah Khan 	int ret;
19795bc3cb74SMauro Carvalho Chehab 
198077fa4e07SShuah Khan 	ret = v4l_enable_media_source(vfd);
198177fa4e07SShuah Khan 	if (ret)
198277fa4e07SShuah Khan 		return ret;
19835bc3cb74SMauro Carvalho Chehab 	/*
19841a2c6866SHans Verkuil 	 * If no signal is detected, then the driver should return
19851a2c6866SHans Verkuil 	 * V4L2_STD_UNKNOWN. Otherwise it should return tvnorms with
19861a2c6866SHans Verkuil 	 * any standards that do not apply removed.
19871a2c6866SHans Verkuil 	 *
19885bc3cb74SMauro Carvalho Chehab 	 * This means that tuners, audio and video decoders can join
19895bc3cb74SMauro Carvalho Chehab 	 * their efforts to improve the standards detection.
19905bc3cb74SMauro Carvalho Chehab 	 */
19915bc3cb74SMauro Carvalho Chehab 	*p = vfd->tvnorms;
19925bc3cb74SMauro Carvalho Chehab 	return ops->vidioc_querystd(file, fh, arg);
19935bc3cb74SMauro Carvalho Chehab }
19945bc3cb74SMauro Carvalho Chehab 
19955bc3cb74SMauro Carvalho Chehab static int v4l_s_hw_freq_seek(const struct v4l2_ioctl_ops *ops,
19965bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
19975bc3cb74SMauro Carvalho Chehab {
19985bc3cb74SMauro Carvalho Chehab 	struct video_device *vfd = video_devdata(file);
19995bc3cb74SMauro Carvalho Chehab 	struct v4l2_hw_freq_seek *p = arg;
20005bc3cb74SMauro Carvalho Chehab 	enum v4l2_tuner_type type;
200177fa4e07SShuah Khan 	int ret;
20025bc3cb74SMauro Carvalho Chehab 
200377fa4e07SShuah Khan 	ret = v4l_enable_media_source(vfd);
200477fa4e07SShuah Khan 	if (ret)
200577fa4e07SShuah Khan 		return ret;
200684099a28SAntti Palosaari 	/* s_hw_freq_seek is not supported for SDR for now */
200784099a28SAntti Palosaari 	if (vfd->vfl_type == VFL_TYPE_SDR)
200884099a28SAntti Palosaari 		return -EINVAL;
200984099a28SAntti Palosaari 
20105bc3cb74SMauro Carvalho Chehab 	type = (vfd->vfl_type == VFL_TYPE_RADIO) ?
20115bc3cb74SMauro Carvalho Chehab 		V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV;
20125bc3cb74SMauro Carvalho Chehab 	if (p->type != type)
20135bc3cb74SMauro Carvalho Chehab 		return -EINVAL;
20145bc3cb74SMauro Carvalho Chehab 	return ops->vidioc_s_hw_freq_seek(file, fh, p);
20155bc3cb74SMauro Carvalho Chehab }
20165bc3cb74SMauro Carvalho Chehab 
2017737c097bSHans Verkuil static int v4l_overlay(const struct v4l2_ioctl_ops *ops,
2018737c097bSHans Verkuil 				struct file *file, void *fh, void *arg)
2019737c097bSHans Verkuil {
2020737c097bSHans Verkuil 	return ops->vidioc_overlay(file, fh, *(unsigned int *)arg);
2021737c097bSHans Verkuil }
2022737c097bSHans Verkuil 
20235bc3cb74SMauro Carvalho Chehab static int v4l_reqbufs(const struct v4l2_ioctl_ops *ops,
20245bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
20255bc3cb74SMauro Carvalho Chehab {
20265bc3cb74SMauro Carvalho Chehab 	struct v4l2_requestbuffers *p = arg;
20274b20259fSHans Verkuil 	int ret = check_fmt(file, p->type);
20285bc3cb74SMauro Carvalho Chehab 
20295bc3cb74SMauro Carvalho Chehab 	if (ret)
20305bc3cb74SMauro Carvalho Chehab 		return ret;
2031129134e5SSergey Senozhatsky 
2032c0acf9cfSSergey Senozhatsky 	CLEAR_AFTER_FIELD(p, flags);
2033129134e5SSergey Senozhatsky 
20345bc3cb74SMauro Carvalho Chehab 	return ops->vidioc_reqbufs(file, fh, p);
20355bc3cb74SMauro Carvalho Chehab }
20365bc3cb74SMauro Carvalho Chehab 
20375bc3cb74SMauro Carvalho Chehab static int v4l_querybuf(const struct v4l2_ioctl_ops *ops,
20385bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
20395bc3cb74SMauro Carvalho Chehab {
20405bc3cb74SMauro Carvalho Chehab 	struct v4l2_buffer *p = arg;
20414b20259fSHans Verkuil 	int ret = check_fmt(file, p->type);
20425bc3cb74SMauro Carvalho Chehab 
20435bc3cb74SMauro Carvalho Chehab 	return ret ? ret : ops->vidioc_querybuf(file, fh, p);
20445bc3cb74SMauro Carvalho Chehab }
20455bc3cb74SMauro Carvalho Chehab 
20465bc3cb74SMauro Carvalho Chehab static int v4l_qbuf(const struct v4l2_ioctl_ops *ops,
20475bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
20485bc3cb74SMauro Carvalho Chehab {
20495bc3cb74SMauro Carvalho Chehab 	struct v4l2_buffer *p = arg;
20504b20259fSHans Verkuil 	int ret = check_fmt(file, p->type);
20515bc3cb74SMauro Carvalho Chehab 
20525bc3cb74SMauro Carvalho Chehab 	return ret ? ret : ops->vidioc_qbuf(file, fh, p);
20535bc3cb74SMauro Carvalho Chehab }
20545bc3cb74SMauro Carvalho Chehab 
20555bc3cb74SMauro Carvalho Chehab static int v4l_dqbuf(const struct v4l2_ioctl_ops *ops,
20565bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
20575bc3cb74SMauro Carvalho Chehab {
20585bc3cb74SMauro Carvalho Chehab 	struct v4l2_buffer *p = arg;
20594b20259fSHans Verkuil 	int ret = check_fmt(file, p->type);
20605bc3cb74SMauro Carvalho Chehab 
20615bc3cb74SMauro Carvalho Chehab 	return ret ? ret : ops->vidioc_dqbuf(file, fh, p);
20625bc3cb74SMauro Carvalho Chehab }
20635bc3cb74SMauro Carvalho Chehab 
20645bc3cb74SMauro Carvalho Chehab static int v4l_create_bufs(const struct v4l2_ioctl_ops *ops,
20655bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
20665bc3cb74SMauro Carvalho Chehab {
20675bc3cb74SMauro Carvalho Chehab 	struct v4l2_create_buffers *create = arg;
20684b20259fSHans Verkuil 	int ret = check_fmt(file, create->format.type);
20695bc3cb74SMauro Carvalho Chehab 
2070d52e2381SLaurent Pinchart 	if (ret)
2071d52e2381SLaurent Pinchart 		return ret;
2072d52e2381SLaurent Pinchart 
2073c0acf9cfSSergey Senozhatsky 	CLEAR_AFTER_FIELD(create, flags);
20745d351251SHans Verkuil 
2075d52e2381SLaurent Pinchart 	v4l_sanitize_format(&create->format);
2076d52e2381SLaurent Pinchart 
2077d52e2381SLaurent Pinchart 	ret = ops->vidioc_create_bufs(file, fh, create);
2078d52e2381SLaurent Pinchart 
2079d52e2381SLaurent Pinchart 	if (create->format.type == V4L2_BUF_TYPE_VIDEO_CAPTURE ||
2080d52e2381SLaurent Pinchart 	    create->format.type == V4L2_BUF_TYPE_VIDEO_OUTPUT)
2081d52e2381SLaurent Pinchart 		create->format.fmt.pix.priv = V4L2_PIX_FMT_PRIV_MAGIC;
2082d52e2381SLaurent Pinchart 
2083d52e2381SLaurent Pinchart 	return ret;
20845bc3cb74SMauro Carvalho Chehab }
20855bc3cb74SMauro Carvalho Chehab 
20865bc3cb74SMauro Carvalho Chehab static int v4l_prepare_buf(const struct v4l2_ioctl_ops *ops,
20875bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
20885bc3cb74SMauro Carvalho Chehab {
20895bc3cb74SMauro Carvalho Chehab 	struct v4l2_buffer *b = arg;
20904b20259fSHans Verkuil 	int ret = check_fmt(file, b->type);
20915bc3cb74SMauro Carvalho Chehab 
20925bc3cb74SMauro Carvalho Chehab 	return ret ? ret : ops->vidioc_prepare_buf(file, fh, b);
20935bc3cb74SMauro Carvalho Chehab }
20945bc3cb74SMauro Carvalho Chehab 
20955bc3cb74SMauro Carvalho Chehab static int v4l_g_parm(const struct v4l2_ioctl_ops *ops,
20965bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
20975bc3cb74SMauro Carvalho Chehab {
2098cd9d9377SHans Verkuil 	struct video_device *vfd = video_devdata(file);
20995bc3cb74SMauro Carvalho Chehab 	struct v4l2_streamparm *p = arg;
21005bc3cb74SMauro Carvalho Chehab 	v4l2_std_id std;
21014b20259fSHans Verkuil 	int ret = check_fmt(file, p->type);
21025bc3cb74SMauro Carvalho Chehab 
21035bc3cb74SMauro Carvalho Chehab 	if (ret)
21045bc3cb74SMauro Carvalho Chehab 		return ret;
21055bc3cb74SMauro Carvalho Chehab 	if (ops->vidioc_g_parm)
21065bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_g_parm(file, fh, p);
21075bc3cb74SMauro Carvalho Chehab 	if (p->type != V4L2_BUF_TYPE_VIDEO_CAPTURE &&
21085bc3cb74SMauro Carvalho Chehab 	    p->type != V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
21095bc3cb74SMauro Carvalho Chehab 		return -EINVAL;
2110cd9d9377SHans Verkuil 	if (vfd->device_caps & V4L2_CAP_READWRITE)
21115bc3cb74SMauro Carvalho Chehab 		p->parm.capture.readbuffers = 2;
21125bc3cb74SMauro Carvalho Chehab 	ret = ops->vidioc_g_std(file, fh, &std);
21135bc3cb74SMauro Carvalho Chehab 	if (ret == 0)
2114ca371575SHans Verkuil 		v4l2_video_std_frame_period(std, &p->parm.capture.timeperframe);
21155bc3cb74SMauro Carvalho Chehab 	return ret;
21165bc3cb74SMauro Carvalho Chehab }
21175bc3cb74SMauro Carvalho Chehab 
21185bc3cb74SMauro Carvalho Chehab static int v4l_s_parm(const struct v4l2_ioctl_ops *ops,
21195bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
21205bc3cb74SMauro Carvalho Chehab {
21215bc3cb74SMauro Carvalho Chehab 	struct v4l2_streamparm *p = arg;
21224b20259fSHans Verkuil 	int ret = check_fmt(file, p->type);
21235bc3cb74SMauro Carvalho Chehab 
21248a7c5594SHans Verkuil 	if (ret)
21258a7c5594SHans Verkuil 		return ret;
21268a7c5594SHans Verkuil 
21274f62e840SHans Verkuil 	/* Note: extendedmode is never used in drivers */
21288a7c5594SHans Verkuil 	if (V4L2_TYPE_IS_OUTPUT(p->type)) {
21298a7c5594SHans Verkuil 		memset(p->parm.output.reserved, 0,
21308a7c5594SHans Verkuil 		       sizeof(p->parm.output.reserved));
21318a7c5594SHans Verkuil 		p->parm.output.extendedmode = 0;
21328a7c5594SHans Verkuil 		p->parm.output.outputmode &= V4L2_MODE_HIGHQUALITY;
21338a7c5594SHans Verkuil 	} else {
21348a7c5594SHans Verkuil 		memset(p->parm.capture.reserved, 0,
21358a7c5594SHans Verkuil 		       sizeof(p->parm.capture.reserved));
21364f62e840SHans Verkuil 		p->parm.capture.extendedmode = 0;
21378a7c5594SHans Verkuil 		p->parm.capture.capturemode &= V4L2_MODE_HIGHQUALITY;
21388a7c5594SHans Verkuil 	}
21398a7c5594SHans Verkuil 	return ops->vidioc_s_parm(file, fh, p);
21405bc3cb74SMauro Carvalho Chehab }
21415bc3cb74SMauro Carvalho Chehab 
21425bc3cb74SMauro Carvalho Chehab static int v4l_queryctrl(const struct v4l2_ioctl_ops *ops,
21435bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
21445bc3cb74SMauro Carvalho Chehab {
21455bc3cb74SMauro Carvalho Chehab 	struct video_device *vfd = video_devdata(file);
21465bc3cb74SMauro Carvalho Chehab 	struct v4l2_queryctrl *p = arg;
21475bc3cb74SMauro Carvalho Chehab 	struct v4l2_fh *vfh =
21485bc3cb74SMauro Carvalho Chehab 		test_bit(V4L2_FL_USES_V4L2_FH, &vfd->flags) ? fh : NULL;
21495bc3cb74SMauro Carvalho Chehab 
21505bc3cb74SMauro Carvalho Chehab 	if (vfh && vfh->ctrl_handler)
21515bc3cb74SMauro Carvalho Chehab 		return v4l2_queryctrl(vfh->ctrl_handler, p);
21525bc3cb74SMauro Carvalho Chehab 	if (vfd->ctrl_handler)
21535bc3cb74SMauro Carvalho Chehab 		return v4l2_queryctrl(vfd->ctrl_handler, p);
21545bc3cb74SMauro Carvalho Chehab 	if (ops->vidioc_queryctrl)
21555bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_queryctrl(file, fh, p);
21565bc3cb74SMauro Carvalho Chehab 	return -ENOTTY;
21575bc3cb74SMauro Carvalho Chehab }
21585bc3cb74SMauro Carvalho Chehab 
2159e6bee368SHans Verkuil static int v4l_query_ext_ctrl(const struct v4l2_ioctl_ops *ops,
2160e6bee368SHans Verkuil 				struct file *file, void *fh, void *arg)
2161e6bee368SHans Verkuil {
2162e6bee368SHans Verkuil 	struct video_device *vfd = video_devdata(file);
2163e6bee368SHans Verkuil 	struct v4l2_query_ext_ctrl *p = arg;
2164e6bee368SHans Verkuil 	struct v4l2_fh *vfh =
2165e6bee368SHans Verkuil 		test_bit(V4L2_FL_USES_V4L2_FH, &vfd->flags) ? fh : NULL;
2166e6bee368SHans Verkuil 
2167e6bee368SHans Verkuil 	if (vfh && vfh->ctrl_handler)
2168e6bee368SHans Verkuil 		return v4l2_query_ext_ctrl(vfh->ctrl_handler, p);
2169e6bee368SHans Verkuil 	if (vfd->ctrl_handler)
2170e6bee368SHans Verkuil 		return v4l2_query_ext_ctrl(vfd->ctrl_handler, p);
2171e6bee368SHans Verkuil 	if (ops->vidioc_query_ext_ctrl)
2172e6bee368SHans Verkuil 		return ops->vidioc_query_ext_ctrl(file, fh, p);
2173e6bee368SHans Verkuil 	return -ENOTTY;
2174e6bee368SHans Verkuil }
2175e6bee368SHans Verkuil 
21765bc3cb74SMauro Carvalho Chehab static int v4l_querymenu(const struct v4l2_ioctl_ops *ops,
21775bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
21785bc3cb74SMauro Carvalho Chehab {
21795bc3cb74SMauro Carvalho Chehab 	struct video_device *vfd = video_devdata(file);
21805bc3cb74SMauro Carvalho Chehab 	struct v4l2_querymenu *p = arg;
21815bc3cb74SMauro Carvalho Chehab 	struct v4l2_fh *vfh =
21825bc3cb74SMauro Carvalho Chehab 		test_bit(V4L2_FL_USES_V4L2_FH, &vfd->flags) ? fh : NULL;
21835bc3cb74SMauro Carvalho Chehab 
21845bc3cb74SMauro Carvalho Chehab 	if (vfh && vfh->ctrl_handler)
21855bc3cb74SMauro Carvalho Chehab 		return v4l2_querymenu(vfh->ctrl_handler, p);
21865bc3cb74SMauro Carvalho Chehab 	if (vfd->ctrl_handler)
21875bc3cb74SMauro Carvalho Chehab 		return v4l2_querymenu(vfd->ctrl_handler, p);
21885bc3cb74SMauro Carvalho Chehab 	if (ops->vidioc_querymenu)
21895bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_querymenu(file, fh, p);
21905bc3cb74SMauro Carvalho Chehab 	return -ENOTTY;
21915bc3cb74SMauro Carvalho Chehab }
21925bc3cb74SMauro Carvalho Chehab 
21935bc3cb74SMauro Carvalho Chehab static int v4l_g_ctrl(const struct v4l2_ioctl_ops *ops,
21945bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
21955bc3cb74SMauro Carvalho Chehab {
21965bc3cb74SMauro Carvalho Chehab 	struct video_device *vfd = video_devdata(file);
21975bc3cb74SMauro Carvalho Chehab 	struct v4l2_control *p = arg;
21985bc3cb74SMauro Carvalho Chehab 	struct v4l2_fh *vfh =
21995bc3cb74SMauro Carvalho Chehab 		test_bit(V4L2_FL_USES_V4L2_FH, &vfd->flags) ? fh : NULL;
22005bc3cb74SMauro Carvalho Chehab 	struct v4l2_ext_controls ctrls;
22015bc3cb74SMauro Carvalho Chehab 	struct v4l2_ext_control ctrl;
22025bc3cb74SMauro Carvalho Chehab 
22035bc3cb74SMauro Carvalho Chehab 	if (vfh && vfh->ctrl_handler)
22045bc3cb74SMauro Carvalho Chehab 		return v4l2_g_ctrl(vfh->ctrl_handler, p);
22055bc3cb74SMauro Carvalho Chehab 	if (vfd->ctrl_handler)
22065bc3cb74SMauro Carvalho Chehab 		return v4l2_g_ctrl(vfd->ctrl_handler, p);
22075bc3cb74SMauro Carvalho Chehab 	if (ops->vidioc_g_ctrl)
22085bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_g_ctrl(file, fh, p);
22095bc3cb74SMauro Carvalho Chehab 	if (ops->vidioc_g_ext_ctrls == NULL)
22105bc3cb74SMauro Carvalho Chehab 		return -ENOTTY;
22115bc3cb74SMauro Carvalho Chehab 
22120f8017beSRicardo Ribalda 	ctrls.which = V4L2_CTRL_ID2WHICH(p->id);
22135bc3cb74SMauro Carvalho Chehab 	ctrls.count = 1;
22145bc3cb74SMauro Carvalho Chehab 	ctrls.controls = &ctrl;
22155bc3cb74SMauro Carvalho Chehab 	ctrl.id = p->id;
22165bc3cb74SMauro Carvalho Chehab 	ctrl.value = p->value;
2217861f92cbSRicardo Ribalda 	if (check_ext_ctrls(&ctrls, VIDIOC_G_CTRL)) {
22185bc3cb74SMauro Carvalho Chehab 		int ret = ops->vidioc_g_ext_ctrls(file, fh, &ctrls);
22195bc3cb74SMauro Carvalho Chehab 
22205bc3cb74SMauro Carvalho Chehab 		if (ret == 0)
22215bc3cb74SMauro Carvalho Chehab 			p->value = ctrl.value;
22225bc3cb74SMauro Carvalho Chehab 		return ret;
22235bc3cb74SMauro Carvalho Chehab 	}
22245bc3cb74SMauro Carvalho Chehab 	return -EINVAL;
22255bc3cb74SMauro Carvalho Chehab }
22265bc3cb74SMauro Carvalho Chehab 
22275bc3cb74SMauro Carvalho Chehab static int v4l_s_ctrl(const struct v4l2_ioctl_ops *ops,
22285bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
22295bc3cb74SMauro Carvalho Chehab {
22305bc3cb74SMauro Carvalho Chehab 	struct video_device *vfd = video_devdata(file);
22315bc3cb74SMauro Carvalho Chehab 	struct v4l2_control *p = arg;
22325bc3cb74SMauro Carvalho Chehab 	struct v4l2_fh *vfh =
22335bc3cb74SMauro Carvalho Chehab 		test_bit(V4L2_FL_USES_V4L2_FH, &vfd->flags) ? fh : NULL;
22345bc3cb74SMauro Carvalho Chehab 	struct v4l2_ext_controls ctrls;
22355bc3cb74SMauro Carvalho Chehab 	struct v4l2_ext_control ctrl;
2236c87ed935SRicardo Ribalda 	int ret;
22375bc3cb74SMauro Carvalho Chehab 
22385bc3cb74SMauro Carvalho Chehab 	if (vfh && vfh->ctrl_handler)
22395bc3cb74SMauro Carvalho Chehab 		return v4l2_s_ctrl(vfh, vfh->ctrl_handler, p);
22405bc3cb74SMauro Carvalho Chehab 	if (vfd->ctrl_handler)
22415bc3cb74SMauro Carvalho Chehab 		return v4l2_s_ctrl(NULL, vfd->ctrl_handler, p);
22425bc3cb74SMauro Carvalho Chehab 	if (ops->vidioc_s_ctrl)
22435bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_s_ctrl(file, fh, p);
22445bc3cb74SMauro Carvalho Chehab 	if (ops->vidioc_s_ext_ctrls == NULL)
22455bc3cb74SMauro Carvalho Chehab 		return -ENOTTY;
22465bc3cb74SMauro Carvalho Chehab 
22470f8017beSRicardo Ribalda 	ctrls.which = V4L2_CTRL_ID2WHICH(p->id);
22485bc3cb74SMauro Carvalho Chehab 	ctrls.count = 1;
22495bc3cb74SMauro Carvalho Chehab 	ctrls.controls = &ctrl;
22505bc3cb74SMauro Carvalho Chehab 	ctrl.id = p->id;
22515bc3cb74SMauro Carvalho Chehab 	ctrl.value = p->value;
2252c87ed935SRicardo Ribalda 	if (!check_ext_ctrls(&ctrls, VIDIOC_S_CTRL))
22535bc3cb74SMauro Carvalho Chehab 		return -EINVAL;
2254c87ed935SRicardo Ribalda 	ret = ops->vidioc_s_ext_ctrls(file, fh, &ctrls);
2255c87ed935SRicardo Ribalda 	p->value = ctrl.value;
2256c87ed935SRicardo Ribalda 	return ret;
22575bc3cb74SMauro Carvalho Chehab }
22585bc3cb74SMauro Carvalho Chehab 
22595bc3cb74SMauro Carvalho Chehab static int v4l_g_ext_ctrls(const struct v4l2_ioctl_ops *ops,
22605bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
22615bc3cb74SMauro Carvalho Chehab {
22625bc3cb74SMauro Carvalho Chehab 	struct video_device *vfd = video_devdata(file);
22635bc3cb74SMauro Carvalho Chehab 	struct v4l2_ext_controls *p = arg;
22645bc3cb74SMauro Carvalho Chehab 	struct v4l2_fh *vfh =
22655bc3cb74SMauro Carvalho Chehab 		test_bit(V4L2_FL_USES_V4L2_FH, &vfd->flags) ? fh : NULL;
22665bc3cb74SMauro Carvalho Chehab 
22675bc3cb74SMauro Carvalho Chehab 	p->error_idx = p->count;
22685bc3cb74SMauro Carvalho Chehab 	if (vfh && vfh->ctrl_handler)
2269173f6eacSEzequiel Garcia 		return v4l2_g_ext_ctrls(vfh->ctrl_handler,
2270173f6eacSEzequiel Garcia 					vfd, vfd->v4l2_dev->mdev, p);
22715bc3cb74SMauro Carvalho Chehab 	if (vfd->ctrl_handler)
2272173f6eacSEzequiel Garcia 		return v4l2_g_ext_ctrls(vfd->ctrl_handler,
2273173f6eacSEzequiel Garcia 					vfd, vfd->v4l2_dev->mdev, p);
22745bc3cb74SMauro Carvalho Chehab 	if (ops->vidioc_g_ext_ctrls == NULL)
22755bc3cb74SMauro Carvalho Chehab 		return -ENOTTY;
2276861f92cbSRicardo Ribalda 	return check_ext_ctrls(p, VIDIOC_G_EXT_CTRLS) ?
2277861f92cbSRicardo Ribalda 				ops->vidioc_g_ext_ctrls(file, fh, p) : -EINVAL;
22785bc3cb74SMauro Carvalho Chehab }
22795bc3cb74SMauro Carvalho Chehab 
22805bc3cb74SMauro Carvalho Chehab static int v4l_s_ext_ctrls(const struct v4l2_ioctl_ops *ops,
22815bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
22825bc3cb74SMauro Carvalho Chehab {
22835bc3cb74SMauro Carvalho Chehab 	struct video_device *vfd = video_devdata(file);
22845bc3cb74SMauro Carvalho Chehab 	struct v4l2_ext_controls *p = arg;
22855bc3cb74SMauro Carvalho Chehab 	struct v4l2_fh *vfh =
22865bc3cb74SMauro Carvalho Chehab 		test_bit(V4L2_FL_USES_V4L2_FH, &vfd->flags) ? fh : NULL;
22875bc3cb74SMauro Carvalho Chehab 
22885bc3cb74SMauro Carvalho Chehab 	p->error_idx = p->count;
22895bc3cb74SMauro Carvalho Chehab 	if (vfh && vfh->ctrl_handler)
2290173f6eacSEzequiel Garcia 		return v4l2_s_ext_ctrls(vfh, vfh->ctrl_handler,
2291173f6eacSEzequiel Garcia 					vfd, vfd->v4l2_dev->mdev, p);
22925bc3cb74SMauro Carvalho Chehab 	if (vfd->ctrl_handler)
2293173f6eacSEzequiel Garcia 		return v4l2_s_ext_ctrls(NULL, vfd->ctrl_handler,
2294173f6eacSEzequiel Garcia 					vfd, vfd->v4l2_dev->mdev, p);
22955bc3cb74SMauro Carvalho Chehab 	if (ops->vidioc_s_ext_ctrls == NULL)
22965bc3cb74SMauro Carvalho Chehab 		return -ENOTTY;
2297861f92cbSRicardo Ribalda 	return check_ext_ctrls(p, VIDIOC_S_EXT_CTRLS) ?
2298861f92cbSRicardo Ribalda 				ops->vidioc_s_ext_ctrls(file, fh, p) : -EINVAL;
22995bc3cb74SMauro Carvalho Chehab }
23005bc3cb74SMauro Carvalho Chehab 
23015bc3cb74SMauro Carvalho Chehab static int v4l_try_ext_ctrls(const struct v4l2_ioctl_ops *ops,
23025bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
23035bc3cb74SMauro Carvalho Chehab {
23045bc3cb74SMauro Carvalho Chehab 	struct video_device *vfd = video_devdata(file);
23055bc3cb74SMauro Carvalho Chehab 	struct v4l2_ext_controls *p = arg;
23065bc3cb74SMauro Carvalho Chehab 	struct v4l2_fh *vfh =
23075bc3cb74SMauro Carvalho Chehab 		test_bit(V4L2_FL_USES_V4L2_FH, &vfd->flags) ? fh : NULL;
23085bc3cb74SMauro Carvalho Chehab 
23095bc3cb74SMauro Carvalho Chehab 	p->error_idx = p->count;
23105bc3cb74SMauro Carvalho Chehab 	if (vfh && vfh->ctrl_handler)
2311173f6eacSEzequiel Garcia 		return v4l2_try_ext_ctrls(vfh->ctrl_handler,
2312173f6eacSEzequiel Garcia 					  vfd, vfd->v4l2_dev->mdev, p);
23135bc3cb74SMauro Carvalho Chehab 	if (vfd->ctrl_handler)
2314173f6eacSEzequiel Garcia 		return v4l2_try_ext_ctrls(vfd->ctrl_handler,
2315173f6eacSEzequiel Garcia 					  vfd, vfd->v4l2_dev->mdev, p);
23165bc3cb74SMauro Carvalho Chehab 	if (ops->vidioc_try_ext_ctrls == NULL)
23175bc3cb74SMauro Carvalho Chehab 		return -ENOTTY;
2318861f92cbSRicardo Ribalda 	return check_ext_ctrls(p, VIDIOC_TRY_EXT_CTRLS) ?
2319861f92cbSRicardo Ribalda 			ops->vidioc_try_ext_ctrls(file, fh, p) : -EINVAL;
23205bc3cb74SMauro Carvalho Chehab }
23215bc3cb74SMauro Carvalho Chehab 
2322eaec420fSHans Verkuil /*
2323eaec420fSHans Verkuil  * The selection API specified originally that the _MPLANE buffer types
2324eaec420fSHans Verkuil  * shouldn't be used. The reasons for this are lost in the mists of time
2325eaec420fSHans Verkuil  * (or just really crappy memories). Regardless, this is really annoying
2326eaec420fSHans Verkuil  * for userspace. So to keep things simple we map _MPLANE buffer types
2327eaec420fSHans Verkuil  * to their 'regular' counterparts before calling the driver. And we
2328eaec420fSHans Verkuil  * restore it afterwards. This way applications can use either buffer
2329eaec420fSHans Verkuil  * type and drivers don't need to check for both.
2330eaec420fSHans Verkuil  */
2331eaec420fSHans Verkuil static int v4l_g_selection(const struct v4l2_ioctl_ops *ops,
2332eaec420fSHans Verkuil 			   struct file *file, void *fh, void *arg)
2333eaec420fSHans Verkuil {
2334eaec420fSHans Verkuil 	struct v4l2_selection *p = arg;
2335eaec420fSHans Verkuil 	u32 old_type = p->type;
2336eaec420fSHans Verkuil 	int ret;
2337eaec420fSHans Verkuil 
2338eaec420fSHans Verkuil 	if (p->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
2339eaec420fSHans Verkuil 		p->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
2340eaec420fSHans Verkuil 	else if (p->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)
2341eaec420fSHans Verkuil 		p->type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
2342eaec420fSHans Verkuil 	ret = ops->vidioc_g_selection(file, fh, p);
2343eaec420fSHans Verkuil 	p->type = old_type;
2344eaec420fSHans Verkuil 	return ret;
2345eaec420fSHans Verkuil }
2346eaec420fSHans Verkuil 
2347eaec420fSHans Verkuil static int v4l_s_selection(const struct v4l2_ioctl_ops *ops,
2348eaec420fSHans Verkuil 			   struct file *file, void *fh, void *arg)
2349eaec420fSHans Verkuil {
2350eaec420fSHans Verkuil 	struct v4l2_selection *p = arg;
2351eaec420fSHans Verkuil 	u32 old_type = p->type;
2352eaec420fSHans Verkuil 	int ret;
2353eaec420fSHans Verkuil 
2354eaec420fSHans Verkuil 	if (p->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
2355eaec420fSHans Verkuil 		p->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
2356eaec420fSHans Verkuil 	else if (p->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)
2357eaec420fSHans Verkuil 		p->type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
2358eaec420fSHans Verkuil 	ret = ops->vidioc_s_selection(file, fh, p);
2359eaec420fSHans Verkuil 	p->type = old_type;
2360eaec420fSHans Verkuil 	return ret;
2361eaec420fSHans Verkuil }
2362eaec420fSHans Verkuil 
23635bc3cb74SMauro Carvalho Chehab static int v4l_g_crop(const struct v4l2_ioctl_ops *ops,
23645bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
23655bc3cb74SMauro Carvalho Chehab {
23668cbd94bdSHans Verkuil 	struct video_device *vfd = video_devdata(file);
23675bc3cb74SMauro Carvalho Chehab 	struct v4l2_crop *p = arg;
23685bc3cb74SMauro Carvalho Chehab 	struct v4l2_selection s = {
23695bc3cb74SMauro Carvalho Chehab 		.type = p->type,
23705bc3cb74SMauro Carvalho Chehab 	};
23715bc3cb74SMauro Carvalho Chehab 	int ret;
23725bc3cb74SMauro Carvalho Chehab 
23735bc3cb74SMauro Carvalho Chehab 	/* simulate capture crop using selection api */
23745bc3cb74SMauro Carvalho Chehab 
23755bc3cb74SMauro Carvalho Chehab 	/* crop means compose for output devices */
23765bc3cb74SMauro Carvalho Chehab 	if (V4L2_TYPE_IS_OUTPUT(p->type))
23775b79da06SHans Verkuil 		s.target = V4L2_SEL_TGT_COMPOSE;
23785bc3cb74SMauro Carvalho Chehab 	else
23795b79da06SHans Verkuil 		s.target = V4L2_SEL_TGT_CROP;
23805bc3cb74SMauro Carvalho Chehab 
23818cbd94bdSHans Verkuil 	if (test_bit(V4L2_FL_QUIRK_INVERTED_CROP, &vfd->flags))
23828cbd94bdSHans Verkuil 		s.target = s.target == V4L2_SEL_TGT_COMPOSE ?
23838cbd94bdSHans Verkuil 			V4L2_SEL_TGT_CROP : V4L2_SEL_TGT_COMPOSE;
23848cbd94bdSHans Verkuil 
2385eaec420fSHans Verkuil 	ret = v4l_g_selection(ops, file, fh, &s);
23865bc3cb74SMauro Carvalho Chehab 
23875bc3cb74SMauro Carvalho Chehab 	/* copying results to old structure on success */
23885bc3cb74SMauro Carvalho Chehab 	if (!ret)
23895bc3cb74SMauro Carvalho Chehab 		p->c = s.r;
23905bc3cb74SMauro Carvalho Chehab 	return ret;
23915bc3cb74SMauro Carvalho Chehab }
23925bc3cb74SMauro Carvalho Chehab 
23935bc3cb74SMauro Carvalho Chehab static int v4l_s_crop(const struct v4l2_ioctl_ops *ops,
23945bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
23955bc3cb74SMauro Carvalho Chehab {
23968cbd94bdSHans Verkuil 	struct video_device *vfd = video_devdata(file);
23975bc3cb74SMauro Carvalho Chehab 	struct v4l2_crop *p = arg;
23985bc3cb74SMauro Carvalho Chehab 	struct v4l2_selection s = {
23995bc3cb74SMauro Carvalho Chehab 		.type = p->type,
24005bc3cb74SMauro Carvalho Chehab 		.r = p->c,
24015bc3cb74SMauro Carvalho Chehab 	};
24025bc3cb74SMauro Carvalho Chehab 
24035bc3cb74SMauro Carvalho Chehab 	/* simulate capture crop using selection api */
24045bc3cb74SMauro Carvalho Chehab 
24055bc3cb74SMauro Carvalho Chehab 	/* crop means compose for output devices */
24065bc3cb74SMauro Carvalho Chehab 	if (V4L2_TYPE_IS_OUTPUT(p->type))
24075b79da06SHans Verkuil 		s.target = V4L2_SEL_TGT_COMPOSE;
24085bc3cb74SMauro Carvalho Chehab 	else
24095b79da06SHans Verkuil 		s.target = V4L2_SEL_TGT_CROP;
24105bc3cb74SMauro Carvalho Chehab 
24118cbd94bdSHans Verkuil 	if (test_bit(V4L2_FL_QUIRK_INVERTED_CROP, &vfd->flags))
24128cbd94bdSHans Verkuil 		s.target = s.target == V4L2_SEL_TGT_COMPOSE ?
24138cbd94bdSHans Verkuil 			V4L2_SEL_TGT_CROP : V4L2_SEL_TGT_COMPOSE;
24148cbd94bdSHans Verkuil 
2415eaec420fSHans Verkuil 	return v4l_s_selection(ops, file, fh, &s);
24165bc3cb74SMauro Carvalho Chehab }
24175bc3cb74SMauro Carvalho Chehab 
24185bc3cb74SMauro Carvalho Chehab static int v4l_cropcap(const struct v4l2_ioctl_ops *ops,
24195bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
24205bc3cb74SMauro Carvalho Chehab {
24218cbd94bdSHans Verkuil 	struct video_device *vfd = video_devdata(file);
24225bc3cb74SMauro Carvalho Chehab 	struct v4l2_cropcap *p = arg;
24235bc3cb74SMauro Carvalho Chehab 	struct v4l2_selection s = { .type = p->type };
242495dd7b7eSHans Verkuil 	int ret = 0;
242595dd7b7eSHans Verkuil 
242695dd7b7eSHans Verkuil 	/* setting trivial pixelaspect */
242795dd7b7eSHans Verkuil 	p->pixelaspect.numerator = 1;
242895dd7b7eSHans Verkuil 	p->pixelaspect.denominator = 1;
242995dd7b7eSHans Verkuil 
24305200ab6aSHans Verkuil 	if (s.type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
24315200ab6aSHans Verkuil 		s.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
24325200ab6aSHans Verkuil 	else if (s.type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)
24335200ab6aSHans Verkuil 		s.type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
24345200ab6aSHans Verkuil 
243595dd7b7eSHans Verkuil 	/*
243695dd7b7eSHans Verkuil 	 * The determine_valid_ioctls() call already should ensure
243795dd7b7eSHans Verkuil 	 * that this can never happen, but just in case...
243895dd7b7eSHans Verkuil 	 */
24395200ab6aSHans Verkuil 	if (WARN_ON(!ops->vidioc_g_selection))
244095dd7b7eSHans Verkuil 		return -ENOTTY;
244195dd7b7eSHans Verkuil 
24425200ab6aSHans Verkuil 	if (ops->vidioc_g_pixelaspect)
24435200ab6aSHans Verkuil 		ret = ops->vidioc_g_pixelaspect(file, fh, s.type,
24445200ab6aSHans Verkuil 						&p->pixelaspect);
244595dd7b7eSHans Verkuil 
244695dd7b7eSHans Verkuil 	/*
244795dd7b7eSHans Verkuil 	 * Ignore ENOTTY or ENOIOCTLCMD error returns, just use the
244895dd7b7eSHans Verkuil 	 * square pixel aspect ratio in that case.
244995dd7b7eSHans Verkuil 	 */
245095dd7b7eSHans Verkuil 	if (ret && ret != -ENOTTY && ret != -ENOIOCTLCMD)
245195dd7b7eSHans Verkuil 		return ret;
245295dd7b7eSHans Verkuil 
245395dd7b7eSHans Verkuil 	/* Use g_selection() to fill in the bounds and defrect rectangles */
24545bc3cb74SMauro Carvalho Chehab 
24555bc3cb74SMauro Carvalho Chehab 	/* obtaining bounds */
24565bc3cb74SMauro Carvalho Chehab 	if (V4L2_TYPE_IS_OUTPUT(p->type))
24575bc3cb74SMauro Carvalho Chehab 		s.target = V4L2_SEL_TGT_COMPOSE_BOUNDS;
24585bc3cb74SMauro Carvalho Chehab 	else
24595bc3cb74SMauro Carvalho Chehab 		s.target = V4L2_SEL_TGT_CROP_BOUNDS;
24605bc3cb74SMauro Carvalho Chehab 
24618cbd94bdSHans Verkuil 	if (test_bit(V4L2_FL_QUIRK_INVERTED_CROP, &vfd->flags))
24628cbd94bdSHans Verkuil 		s.target = s.target == V4L2_SEL_TGT_COMPOSE_BOUNDS ?
24638cbd94bdSHans Verkuil 			V4L2_SEL_TGT_CROP_BOUNDS : V4L2_SEL_TGT_COMPOSE_BOUNDS;
24648cbd94bdSHans Verkuil 
2465eaec420fSHans Verkuil 	ret = v4l_g_selection(ops, file, fh, &s);
24665bc3cb74SMauro Carvalho Chehab 	if (ret)
24675bc3cb74SMauro Carvalho Chehab 		return ret;
24685bc3cb74SMauro Carvalho Chehab 	p->bounds = s.r;
24695bc3cb74SMauro Carvalho Chehab 
24705bc3cb74SMauro Carvalho Chehab 	/* obtaining defrect */
24718cbd94bdSHans Verkuil 	if (s.target == V4L2_SEL_TGT_COMPOSE_BOUNDS)
24725bc3cb74SMauro Carvalho Chehab 		s.target = V4L2_SEL_TGT_COMPOSE_DEFAULT;
24735bc3cb74SMauro Carvalho Chehab 	else
24745bc3cb74SMauro Carvalho Chehab 		s.target = V4L2_SEL_TGT_CROP_DEFAULT;
24755bc3cb74SMauro Carvalho Chehab 
2476eaec420fSHans Verkuil 	ret = v4l_g_selection(ops, file, fh, &s);
24775bc3cb74SMauro Carvalho Chehab 	if (ret)
24785bc3cb74SMauro Carvalho Chehab 		return ret;
24795bc3cb74SMauro Carvalho Chehab 	p->defrect = s.r;
24809409945cSHans Verkuil 
24815bc3cb74SMauro Carvalho Chehab 	return 0;
24825bc3cb74SMauro Carvalho Chehab }
24835bc3cb74SMauro Carvalho Chehab 
24845bc3cb74SMauro Carvalho Chehab static int v4l_log_status(const struct v4l2_ioctl_ops *ops,
24855bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
24865bc3cb74SMauro Carvalho Chehab {
24875bc3cb74SMauro Carvalho Chehab 	struct video_device *vfd = video_devdata(file);
24885bc3cb74SMauro Carvalho Chehab 	int ret;
24895bc3cb74SMauro Carvalho Chehab 
24905bc3cb74SMauro Carvalho Chehab 	if (vfd->v4l2_dev)
24915bc3cb74SMauro Carvalho Chehab 		pr_info("%s: =================  START STATUS  =================\n",
24925bc3cb74SMauro Carvalho Chehab 			vfd->v4l2_dev->name);
24935bc3cb74SMauro Carvalho Chehab 	ret = ops->vidioc_log_status(file, fh);
24945bc3cb74SMauro Carvalho Chehab 	if (vfd->v4l2_dev)
24955bc3cb74SMauro Carvalho Chehab 		pr_info("%s: ==================  END STATUS  ==================\n",
24965bc3cb74SMauro Carvalho Chehab 			vfd->v4l2_dev->name);
24975bc3cb74SMauro Carvalho Chehab 	return ret;
24985bc3cb74SMauro Carvalho Chehab }
24995bc3cb74SMauro Carvalho Chehab 
25005bc3cb74SMauro Carvalho Chehab static int v4l_dbg_g_register(const struct v4l2_ioctl_ops *ops,
25015bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
25025bc3cb74SMauro Carvalho Chehab {
25035bc3cb74SMauro Carvalho Chehab #ifdef CONFIG_VIDEO_ADV_DEBUG
25045bc3cb74SMauro Carvalho Chehab 	struct v4l2_dbg_register *p = arg;
250579b0c640SHans Verkuil 	struct video_device *vfd = video_devdata(file);
250679b0c640SHans Verkuil 	struct v4l2_subdev *sd;
250779b0c640SHans Verkuil 	int idx = 0;
25085bc3cb74SMauro Carvalho Chehab 
25095bc3cb74SMauro Carvalho Chehab 	if (!capable(CAP_SYS_ADMIN))
25105bc3cb74SMauro Carvalho Chehab 		return -EPERM;
25113eef2510SHans Verkuil 	if (p->match.type == V4L2_CHIP_MATCH_SUBDEV) {
251279b0c640SHans Verkuil 		if (vfd->v4l2_dev == NULL)
251379b0c640SHans Verkuil 			return -EINVAL;
25143eef2510SHans Verkuil 		v4l2_device_for_each_subdev(sd, vfd->v4l2_dev)
25153eef2510SHans Verkuil 			if (p->match.addr == idx++)
251679b0c640SHans Verkuil 				return v4l2_subdev_call(sd, core, g_register, p);
251779b0c640SHans Verkuil 		return -EINVAL;
251879b0c640SHans Verkuil 	}
2519191b79b0SHans Verkuil 	if (ops->vidioc_g_register && p->match.type == V4L2_CHIP_MATCH_BRIDGE &&
2520191b79b0SHans Verkuil 	    (ops->vidioc_g_chip_info || p->match.addr == 0))
25215bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_g_register(file, fh, p);
252279b0c640SHans Verkuil 	return -EINVAL;
25235bc3cb74SMauro Carvalho Chehab #else
25245bc3cb74SMauro Carvalho Chehab 	return -ENOTTY;
25255bc3cb74SMauro Carvalho Chehab #endif
25265bc3cb74SMauro Carvalho Chehab }
25275bc3cb74SMauro Carvalho Chehab 
25285bc3cb74SMauro Carvalho Chehab static int v4l_dbg_s_register(const struct v4l2_ioctl_ops *ops,
25295bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
25305bc3cb74SMauro Carvalho Chehab {
25315bc3cb74SMauro Carvalho Chehab #ifdef CONFIG_VIDEO_ADV_DEBUG
2532977ba3b1SHans Verkuil 	const struct v4l2_dbg_register *p = arg;
253379b0c640SHans Verkuil 	struct video_device *vfd = video_devdata(file);
253479b0c640SHans Verkuil 	struct v4l2_subdev *sd;
253579b0c640SHans Verkuil 	int idx = 0;
25365bc3cb74SMauro Carvalho Chehab 
25375bc3cb74SMauro Carvalho Chehab 	if (!capable(CAP_SYS_ADMIN))
25385bc3cb74SMauro Carvalho Chehab 		return -EPERM;
25393eef2510SHans Verkuil 	if (p->match.type == V4L2_CHIP_MATCH_SUBDEV) {
254079b0c640SHans Verkuil 		if (vfd->v4l2_dev == NULL)
254179b0c640SHans Verkuil 			return -EINVAL;
25423eef2510SHans Verkuil 		v4l2_device_for_each_subdev(sd, vfd->v4l2_dev)
25433eef2510SHans Verkuil 			if (p->match.addr == idx++)
254479b0c640SHans Verkuil 				return v4l2_subdev_call(sd, core, s_register, p);
254579b0c640SHans Verkuil 		return -EINVAL;
254679b0c640SHans Verkuil 	}
2547191b79b0SHans Verkuil 	if (ops->vidioc_s_register && p->match.type == V4L2_CHIP_MATCH_BRIDGE &&
2548191b79b0SHans Verkuil 	    (ops->vidioc_g_chip_info || p->match.addr == 0))
25495bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_s_register(file, fh, p);
255079b0c640SHans Verkuil 	return -EINVAL;
25515bc3cb74SMauro Carvalho Chehab #else
25525bc3cb74SMauro Carvalho Chehab 	return -ENOTTY;
25535bc3cb74SMauro Carvalho Chehab #endif
25545bc3cb74SMauro Carvalho Chehab }
25555bc3cb74SMauro Carvalho Chehab 
255696b03d2aSHans Verkuil static int v4l_dbg_g_chip_info(const struct v4l2_ioctl_ops *ops,
255779b0c640SHans Verkuil 				struct file *file, void *fh, void *arg)
255879b0c640SHans Verkuil {
2559cd634f1bSHans Verkuil #ifdef CONFIG_VIDEO_ADV_DEBUG
256079b0c640SHans Verkuil 	struct video_device *vfd = video_devdata(file);
256196b03d2aSHans Verkuil 	struct v4l2_dbg_chip_info *p = arg;
256279b0c640SHans Verkuil 	struct v4l2_subdev *sd;
256379b0c640SHans Verkuil 	int idx = 0;
256479b0c640SHans Verkuil 
256579b0c640SHans Verkuil 	switch (p->match.type) {
256679b0c640SHans Verkuil 	case V4L2_CHIP_MATCH_BRIDGE:
256779b0c640SHans Verkuil 		if (ops->vidioc_s_register)
256879b0c640SHans Verkuil 			p->flags |= V4L2_CHIP_FL_WRITABLE;
256979b0c640SHans Verkuil 		if (ops->vidioc_g_register)
257079b0c640SHans Verkuil 			p->flags |= V4L2_CHIP_FL_READABLE;
2571c0decac1SMauro Carvalho Chehab 		strscpy(p->name, vfd->v4l2_dev->name, sizeof(p->name));
257296b03d2aSHans Verkuil 		if (ops->vidioc_g_chip_info)
257396b03d2aSHans Verkuil 			return ops->vidioc_g_chip_info(file, fh, arg);
25740f0fe4b9SHans Verkuil 		if (p->match.addr)
25750f0fe4b9SHans Verkuil 			return -EINVAL;
257679b0c640SHans Verkuil 		return 0;
257779b0c640SHans Verkuil 
25783eef2510SHans Verkuil 	case V4L2_CHIP_MATCH_SUBDEV:
257979b0c640SHans Verkuil 		if (vfd->v4l2_dev == NULL)
258079b0c640SHans Verkuil 			break;
258179b0c640SHans Verkuil 		v4l2_device_for_each_subdev(sd, vfd->v4l2_dev) {
25823eef2510SHans Verkuil 			if (p->match.addr != idx++)
25833eef2510SHans Verkuil 				continue;
258479b0c640SHans Verkuil 			if (sd->ops->core && sd->ops->core->s_register)
258579b0c640SHans Verkuil 				p->flags |= V4L2_CHIP_FL_WRITABLE;
258679b0c640SHans Verkuil 			if (sd->ops->core && sd->ops->core->g_register)
258779b0c640SHans Verkuil 				p->flags |= V4L2_CHIP_FL_READABLE;
2588c0decac1SMauro Carvalho Chehab 			strscpy(p->name, sd->name, sizeof(p->name));
258979b0c640SHans Verkuil 			return 0;
259079b0c640SHans Verkuil 		}
259179b0c640SHans Verkuil 		break;
259279b0c640SHans Verkuil 	}
259379b0c640SHans Verkuil 	return -EINVAL;
2594cd634f1bSHans Verkuil #else
2595cd634f1bSHans Verkuil 	return -ENOTTY;
2596cd634f1bSHans Verkuil #endif
259779b0c640SHans Verkuil }
259879b0c640SHans Verkuil 
25995bc3cb74SMauro Carvalho Chehab static int v4l_dqevent(const struct v4l2_ioctl_ops *ops,
26005bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
26015bc3cb74SMauro Carvalho Chehab {
26025bc3cb74SMauro Carvalho Chehab 	return v4l2_event_dequeue(fh, arg, file->f_flags & O_NONBLOCK);
26035bc3cb74SMauro Carvalho Chehab }
26045bc3cb74SMauro Carvalho Chehab 
26055bc3cb74SMauro Carvalho Chehab static int v4l_subscribe_event(const struct v4l2_ioctl_ops *ops,
26065bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
26075bc3cb74SMauro Carvalho Chehab {
26085bc3cb74SMauro Carvalho Chehab 	return ops->vidioc_subscribe_event(fh, arg);
26095bc3cb74SMauro Carvalho Chehab }
26105bc3cb74SMauro Carvalho Chehab 
26115bc3cb74SMauro Carvalho Chehab static int v4l_unsubscribe_event(const struct v4l2_ioctl_ops *ops,
26125bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
26135bc3cb74SMauro Carvalho Chehab {
26145bc3cb74SMauro Carvalho Chehab 	return ops->vidioc_unsubscribe_event(fh, arg);
26155bc3cb74SMauro Carvalho Chehab }
26165bc3cb74SMauro Carvalho Chehab 
26175bc3cb74SMauro Carvalho Chehab static int v4l_g_sliced_vbi_cap(const struct v4l2_ioctl_ops *ops,
26185bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
26195bc3cb74SMauro Carvalho Chehab {
26205bc3cb74SMauro Carvalho Chehab 	struct v4l2_sliced_vbi_cap *p = arg;
26214b20259fSHans Verkuil 	int ret = check_fmt(file, p->type);
26224b20259fSHans Verkuil 
26234b20259fSHans Verkuil 	if (ret)
26244b20259fSHans Verkuil 		return ret;
26255bc3cb74SMauro Carvalho Chehab 
26265bc3cb74SMauro Carvalho Chehab 	/* Clear up to type, everything after type is zeroed already */
26275bc3cb74SMauro Carvalho Chehab 	memset(p, 0, offsetof(struct v4l2_sliced_vbi_cap, type));
26285bc3cb74SMauro Carvalho Chehab 
26295bc3cb74SMauro Carvalho Chehab 	return ops->vidioc_g_sliced_vbi_cap(file, fh, p);
26305bc3cb74SMauro Carvalho Chehab }
26315bc3cb74SMauro Carvalho Chehab 
26325bc3cb74SMauro Carvalho Chehab static int v4l_enum_freq_bands(const struct v4l2_ioctl_ops *ops,
26335bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
26345bc3cb74SMauro Carvalho Chehab {
26355bc3cb74SMauro Carvalho Chehab 	struct video_device *vfd = video_devdata(file);
26365bc3cb74SMauro Carvalho Chehab 	struct v4l2_frequency_band *p = arg;
26375bc3cb74SMauro Carvalho Chehab 	enum v4l2_tuner_type type;
26385bc3cb74SMauro Carvalho Chehab 	int err;
26395bc3cb74SMauro Carvalho Chehab 
264084099a28SAntti Palosaari 	if (vfd->vfl_type == VFL_TYPE_SDR) {
2641f3c3ececSAntti Palosaari 		if (p->type != V4L2_TUNER_SDR && p->type != V4L2_TUNER_RF)
264284099a28SAntti Palosaari 			return -EINVAL;
264384099a28SAntti Palosaari 		type = p->type;
264484099a28SAntti Palosaari 	} else {
26455bc3cb74SMauro Carvalho Chehab 		type = (vfd->vfl_type == VFL_TYPE_RADIO) ?
26465bc3cb74SMauro Carvalho Chehab 				V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV;
26475bc3cb74SMauro Carvalho Chehab 		if (type != p->type)
26485bc3cb74SMauro Carvalho Chehab 			return -EINVAL;
264984099a28SAntti Palosaari 	}
2650a7f404afSHans Verkuil 	if (ops->vidioc_enum_freq_bands) {
2651a7f404afSHans Verkuil 		err = ops->vidioc_enum_freq_bands(file, fh, p);
2652a7f404afSHans Verkuil 		if (err != -ENOTTY)
2653a7f404afSHans Verkuil 			return err;
2654a7f404afSHans Verkuil 	}
265573f35418SHans Verkuil 	if (is_valid_ioctl(vfd, VIDIOC_G_TUNER)) {
26565bc3cb74SMauro Carvalho Chehab 		struct v4l2_tuner t = {
26575bc3cb74SMauro Carvalho Chehab 			.index = p->tuner,
26585bc3cb74SMauro Carvalho Chehab 			.type = type,
26595bc3cb74SMauro Carvalho Chehab 		};
26605bc3cb74SMauro Carvalho Chehab 
266179e8c7beSMauro Carvalho Chehab 		if (p->index)
266279e8c7beSMauro Carvalho Chehab 			return -EINVAL;
26635bc3cb74SMauro Carvalho Chehab 		err = ops->vidioc_g_tuner(file, fh, &t);
26645bc3cb74SMauro Carvalho Chehab 		if (err)
26655bc3cb74SMauro Carvalho Chehab 			return err;
26665bc3cb74SMauro Carvalho Chehab 		p->capability = t.capability | V4L2_TUNER_CAP_FREQ_BANDS;
26675bc3cb74SMauro Carvalho Chehab 		p->rangelow = t.rangelow;
26685bc3cb74SMauro Carvalho Chehab 		p->rangehigh = t.rangehigh;
26695bc3cb74SMauro Carvalho Chehab 		p->modulation = (type == V4L2_TUNER_RADIO) ?
26705bc3cb74SMauro Carvalho Chehab 			V4L2_BAND_MODULATION_FM : V4L2_BAND_MODULATION_VSB;
26715bc3cb74SMauro Carvalho Chehab 		return 0;
26725bc3cb74SMauro Carvalho Chehab 	}
267373f35418SHans Verkuil 	if (is_valid_ioctl(vfd, VIDIOC_G_MODULATOR)) {
26745bc3cb74SMauro Carvalho Chehab 		struct v4l2_modulator m = {
26755bc3cb74SMauro Carvalho Chehab 			.index = p->tuner,
26765bc3cb74SMauro Carvalho Chehab 		};
26775bc3cb74SMauro Carvalho Chehab 
26785bc3cb74SMauro Carvalho Chehab 		if (type != V4L2_TUNER_RADIO)
26795bc3cb74SMauro Carvalho Chehab 			return -EINVAL;
268079e8c7beSMauro Carvalho Chehab 		if (p->index)
268179e8c7beSMauro Carvalho Chehab 			return -EINVAL;
26825bc3cb74SMauro Carvalho Chehab 		err = ops->vidioc_g_modulator(file, fh, &m);
26835bc3cb74SMauro Carvalho Chehab 		if (err)
26845bc3cb74SMauro Carvalho Chehab 			return err;
26855bc3cb74SMauro Carvalho Chehab 		p->capability = m.capability | V4L2_TUNER_CAP_FREQ_BANDS;
26865bc3cb74SMauro Carvalho Chehab 		p->rangelow = m.rangelow;
26875bc3cb74SMauro Carvalho Chehab 		p->rangehigh = m.rangehigh;
26885bc3cb74SMauro Carvalho Chehab 		p->modulation = (type == V4L2_TUNER_RADIO) ?
26895bc3cb74SMauro Carvalho Chehab 			V4L2_BAND_MODULATION_FM : V4L2_BAND_MODULATION_VSB;
26905bc3cb74SMauro Carvalho Chehab 		return 0;
26915bc3cb74SMauro Carvalho Chehab 	}
26925bc3cb74SMauro Carvalho Chehab 	return -ENOTTY;
26935bc3cb74SMauro Carvalho Chehab }
26945bc3cb74SMauro Carvalho Chehab 
26955bc3cb74SMauro Carvalho Chehab struct v4l2_ioctl_info {
26965bc3cb74SMauro Carvalho Chehab 	unsigned int ioctl;
26975bc3cb74SMauro Carvalho Chehab 	u32 flags;
26985bc3cb74SMauro Carvalho Chehab 	const char * const name;
26993ad3b7a2SSami Tolvanen 	int (*func)(const struct v4l2_ioctl_ops *ops, struct file *file,
27003ad3b7a2SSami Tolvanen 		    void *fh, void *p);
27015bc3cb74SMauro Carvalho Chehab 	void (*debug)(const void *arg, bool write_only);
27025bc3cb74SMauro Carvalho Chehab };
27035bc3cb74SMauro Carvalho Chehab 
27045bc3cb74SMauro Carvalho Chehab /* This control needs a priority check */
27055bc3cb74SMauro Carvalho Chehab #define INFO_FL_PRIO		(1 << 0)
27065bc3cb74SMauro Carvalho Chehab /* This control can be valid if the filehandle passes a control handler. */
27075bc3cb74SMauro Carvalho Chehab #define INFO_FL_CTRL		(1 << 1)
27085bc3cb74SMauro Carvalho Chehab /* Queuing ioctl */
27093ad3b7a2SSami Tolvanen #define INFO_FL_QUEUE		(1 << 2)
2710043f77edSHans Verkuil /* Always copy back result, even on error */
27113ad3b7a2SSami Tolvanen #define INFO_FL_ALWAYS_COPY	(1 << 3)
27125bc3cb74SMauro Carvalho Chehab /* Zero struct from after the field to the end */
27135bc3cb74SMauro Carvalho Chehab #define INFO_FL_CLEAR(v4l2_struct, field)			\
27145bc3cb74SMauro Carvalho Chehab 	((offsetof(struct v4l2_struct, field) +			\
2715c593642cSPankaj Bharadiya 	  sizeof_field(struct v4l2_struct, field)) << 16)
27165bc3cb74SMauro Carvalho Chehab #define INFO_FL_CLEAR_MASK	(_IOC_SIZEMASK << 16)
27175bc3cb74SMauro Carvalho Chehab 
27183ad3b7a2SSami Tolvanen #define DEFINE_V4L_STUB_FUNC(_vidioc)				\
27193ad3b7a2SSami Tolvanen 	static int v4l_stub_ ## _vidioc(			\
27203ad3b7a2SSami Tolvanen 			const struct v4l2_ioctl_ops *ops,	\
27213ad3b7a2SSami Tolvanen 			struct file *file, void *fh, void *p)	\
27223ad3b7a2SSami Tolvanen 	{							\
27233ad3b7a2SSami Tolvanen 		return ops->vidioc_ ## _vidioc(file, fh, p);	\
27243ad3b7a2SSami Tolvanen 	}
27253ad3b7a2SSami Tolvanen 
27263ad3b7a2SSami Tolvanen #define IOCTL_INFO(_ioctl, _func, _debug, _flags)		\
27275bc3cb74SMauro Carvalho Chehab 	[_IOC_NR(_ioctl)] = {					\
27285bc3cb74SMauro Carvalho Chehab 		.ioctl = _ioctl,				\
27293ad3b7a2SSami Tolvanen 		.flags = _flags,				\
27305bc3cb74SMauro Carvalho Chehab 		.name = #_ioctl,				\
27313ad3b7a2SSami Tolvanen 		.func = _func,					\
27325bc3cb74SMauro Carvalho Chehab 		.debug = _debug,				\
27335bc3cb74SMauro Carvalho Chehab 	}
27345bc3cb74SMauro Carvalho Chehab 
27353ad3b7a2SSami Tolvanen DEFINE_V4L_STUB_FUNC(g_fbuf)
27363ad3b7a2SSami Tolvanen DEFINE_V4L_STUB_FUNC(s_fbuf)
27373ad3b7a2SSami Tolvanen DEFINE_V4L_STUB_FUNC(expbuf)
27383ad3b7a2SSami Tolvanen DEFINE_V4L_STUB_FUNC(g_std)
27393ad3b7a2SSami Tolvanen DEFINE_V4L_STUB_FUNC(g_audio)
27403ad3b7a2SSami Tolvanen DEFINE_V4L_STUB_FUNC(s_audio)
27413ad3b7a2SSami Tolvanen DEFINE_V4L_STUB_FUNC(g_edid)
27423ad3b7a2SSami Tolvanen DEFINE_V4L_STUB_FUNC(s_edid)
27433ad3b7a2SSami Tolvanen DEFINE_V4L_STUB_FUNC(g_audout)
27443ad3b7a2SSami Tolvanen DEFINE_V4L_STUB_FUNC(s_audout)
27453ad3b7a2SSami Tolvanen DEFINE_V4L_STUB_FUNC(g_jpegcomp)
27463ad3b7a2SSami Tolvanen DEFINE_V4L_STUB_FUNC(s_jpegcomp)
27473ad3b7a2SSami Tolvanen DEFINE_V4L_STUB_FUNC(enumaudio)
27483ad3b7a2SSami Tolvanen DEFINE_V4L_STUB_FUNC(enumaudout)
27493ad3b7a2SSami Tolvanen DEFINE_V4L_STUB_FUNC(enum_framesizes)
27503ad3b7a2SSami Tolvanen DEFINE_V4L_STUB_FUNC(enum_frameintervals)
27513ad3b7a2SSami Tolvanen DEFINE_V4L_STUB_FUNC(g_enc_index)
27523ad3b7a2SSami Tolvanen DEFINE_V4L_STUB_FUNC(encoder_cmd)
27533ad3b7a2SSami Tolvanen DEFINE_V4L_STUB_FUNC(try_encoder_cmd)
27543ad3b7a2SSami Tolvanen DEFINE_V4L_STUB_FUNC(decoder_cmd)
27553ad3b7a2SSami Tolvanen DEFINE_V4L_STUB_FUNC(try_decoder_cmd)
27563ad3b7a2SSami Tolvanen DEFINE_V4L_STUB_FUNC(s_dv_timings)
27573ad3b7a2SSami Tolvanen DEFINE_V4L_STUB_FUNC(g_dv_timings)
27583ad3b7a2SSami Tolvanen DEFINE_V4L_STUB_FUNC(enum_dv_timings)
27593ad3b7a2SSami Tolvanen DEFINE_V4L_STUB_FUNC(query_dv_timings)
27603ad3b7a2SSami Tolvanen DEFINE_V4L_STUB_FUNC(dv_timings_cap)
27615bc3cb74SMauro Carvalho Chehab 
27627c91d0a4SEric Biggers static const struct v4l2_ioctl_info v4l2_ioctls[] = {
27633ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_QUERYCAP, v4l_querycap, v4l_print_querycap, 0),
2764e5b6b07aSLaurent Pinchart 	IOCTL_INFO(VIDIOC_ENUM_FMT, v4l_enum_fmt, v4l_print_fmtdesc, 0),
27653ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_G_FMT, v4l_g_fmt, v4l_print_format, 0),
27663ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_S_FMT, v4l_s_fmt, v4l_print_format, INFO_FL_PRIO),
27673ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_REQBUFS, v4l_reqbufs, v4l_print_requestbuffers, INFO_FL_PRIO | INFO_FL_QUEUE),
27683ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_QUERYBUF, v4l_querybuf, v4l_print_buffer, INFO_FL_QUEUE | INFO_FL_CLEAR(v4l2_buffer, length)),
27693ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_G_FBUF, v4l_stub_g_fbuf, v4l_print_framebuffer, 0),
27703ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_S_FBUF, v4l_stub_s_fbuf, v4l_print_framebuffer, INFO_FL_PRIO),
27713ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_OVERLAY, v4l_overlay, v4l_print_u32, INFO_FL_PRIO),
27723ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_QBUF, v4l_qbuf, v4l_print_buffer, INFO_FL_QUEUE),
27733ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_EXPBUF, v4l_stub_expbuf, v4l_print_exportbuffer, INFO_FL_QUEUE | INFO_FL_CLEAR(v4l2_exportbuffer, flags)),
27743ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_DQBUF, v4l_dqbuf, v4l_print_buffer, INFO_FL_QUEUE),
27753ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_STREAMON, v4l_streamon, v4l_print_buftype, INFO_FL_PRIO | INFO_FL_QUEUE),
27763ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_STREAMOFF, v4l_streamoff, v4l_print_buftype, INFO_FL_PRIO | INFO_FL_QUEUE),
27773ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_G_PARM, v4l_g_parm, v4l_print_streamparm, INFO_FL_CLEAR(v4l2_streamparm, type)),
27783ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_S_PARM, v4l_s_parm, v4l_print_streamparm, INFO_FL_PRIO),
27793ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_G_STD, v4l_stub_g_std, v4l_print_std, 0),
27803ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_S_STD, v4l_s_std, v4l_print_std, INFO_FL_PRIO),
27813ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_ENUMSTD, v4l_enumstd, v4l_print_standard, INFO_FL_CLEAR(v4l2_standard, index)),
27823ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_ENUMINPUT, v4l_enuminput, v4l_print_enuminput, INFO_FL_CLEAR(v4l2_input, index)),
27833ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_G_CTRL, v4l_g_ctrl, v4l_print_control, INFO_FL_CTRL | INFO_FL_CLEAR(v4l2_control, id)),
27843ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_S_CTRL, v4l_s_ctrl, v4l_print_control, INFO_FL_PRIO | INFO_FL_CTRL),
27853ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_G_TUNER, v4l_g_tuner, v4l_print_tuner, INFO_FL_CLEAR(v4l2_tuner, index)),
27863ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_S_TUNER, v4l_s_tuner, v4l_print_tuner, INFO_FL_PRIO),
27873ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_G_AUDIO, v4l_stub_g_audio, v4l_print_audio, 0),
27883ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_S_AUDIO, v4l_stub_s_audio, v4l_print_audio, INFO_FL_PRIO),
27893ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_QUERYCTRL, v4l_queryctrl, v4l_print_queryctrl, INFO_FL_CTRL | INFO_FL_CLEAR(v4l2_queryctrl, id)),
27903ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_QUERYMENU, v4l_querymenu, v4l_print_querymenu, INFO_FL_CTRL | INFO_FL_CLEAR(v4l2_querymenu, index)),
2791f645e625SNiklas Söderlund 	IOCTL_INFO(VIDIOC_G_INPUT, v4l_g_input, v4l_print_u32, 0),
27923ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_S_INPUT, v4l_s_input, v4l_print_u32, INFO_FL_PRIO),
27933ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_G_EDID, v4l_stub_g_edid, v4l_print_edid, INFO_FL_ALWAYS_COPY),
27943ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_S_EDID, v4l_stub_s_edid, v4l_print_edid, INFO_FL_PRIO | INFO_FL_ALWAYS_COPY),
2795f645e625SNiklas Söderlund 	IOCTL_INFO(VIDIOC_G_OUTPUT, v4l_g_output, v4l_print_u32, 0),
27963ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_S_OUTPUT, v4l_s_output, v4l_print_u32, INFO_FL_PRIO),
27973ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_ENUMOUTPUT, v4l_enumoutput, v4l_print_enumoutput, INFO_FL_CLEAR(v4l2_output, index)),
27983ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_G_AUDOUT, v4l_stub_g_audout, v4l_print_audioout, 0),
27993ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_S_AUDOUT, v4l_stub_s_audout, v4l_print_audioout, INFO_FL_PRIO),
28003ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_G_MODULATOR, v4l_g_modulator, v4l_print_modulator, INFO_FL_CLEAR(v4l2_modulator, index)),
28013ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_S_MODULATOR, v4l_s_modulator, v4l_print_modulator, INFO_FL_PRIO),
28023ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_G_FREQUENCY, v4l_g_frequency, v4l_print_frequency, INFO_FL_CLEAR(v4l2_frequency, tuner)),
28033ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_S_FREQUENCY, v4l_s_frequency, v4l_print_frequency, INFO_FL_PRIO),
28043ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_CROPCAP, v4l_cropcap, v4l_print_cropcap, INFO_FL_CLEAR(v4l2_cropcap, type)),
28053ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_G_CROP, v4l_g_crop, v4l_print_crop, INFO_FL_CLEAR(v4l2_crop, type)),
28063ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_S_CROP, v4l_s_crop, v4l_print_crop, INFO_FL_PRIO),
28073ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_G_SELECTION, v4l_g_selection, v4l_print_selection, INFO_FL_CLEAR(v4l2_selection, r)),
28083ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_S_SELECTION, v4l_s_selection, v4l_print_selection, INFO_FL_PRIO | INFO_FL_CLEAR(v4l2_selection, r)),
28093ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_G_JPEGCOMP, v4l_stub_g_jpegcomp, v4l_print_jpegcompression, 0),
28103ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_S_JPEGCOMP, v4l_stub_s_jpegcomp, v4l_print_jpegcompression, INFO_FL_PRIO),
28113ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_QUERYSTD, v4l_querystd, v4l_print_std, 0),
28123ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_TRY_FMT, v4l_try_fmt, v4l_print_format, 0),
28133ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_ENUMAUDIO, v4l_stub_enumaudio, v4l_print_audio, INFO_FL_CLEAR(v4l2_audio, index)),
28143ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_ENUMAUDOUT, v4l_stub_enumaudout, v4l_print_audioout, INFO_FL_CLEAR(v4l2_audioout, index)),
28153ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_G_PRIORITY, v4l_g_priority, v4l_print_u32, 0),
28163ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_S_PRIORITY, v4l_s_priority, v4l_print_u32, INFO_FL_PRIO),
28173ad3b7a2SSami 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)),
28183ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_LOG_STATUS, v4l_log_status, v4l_print_newline, 0),
28193ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_G_EXT_CTRLS, v4l_g_ext_ctrls, v4l_print_ext_controls, INFO_FL_CTRL),
28203ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_S_EXT_CTRLS, v4l_s_ext_ctrls, v4l_print_ext_controls, INFO_FL_PRIO | INFO_FL_CTRL),
28213ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_TRY_EXT_CTRLS, v4l_try_ext_ctrls, v4l_print_ext_controls, INFO_FL_CTRL),
28223ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_ENUM_FRAMESIZES, v4l_stub_enum_framesizes, v4l_print_frmsizeenum, INFO_FL_CLEAR(v4l2_frmsizeenum, pixel_format)),
28233ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_ENUM_FRAMEINTERVALS, v4l_stub_enum_frameintervals, v4l_print_frmivalenum, INFO_FL_CLEAR(v4l2_frmivalenum, height)),
28243ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_G_ENC_INDEX, v4l_stub_g_enc_index, v4l_print_enc_idx, 0),
28253ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_ENCODER_CMD, v4l_stub_encoder_cmd, v4l_print_encoder_cmd, INFO_FL_PRIO | INFO_FL_CLEAR(v4l2_encoder_cmd, flags)),
28263ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_TRY_ENCODER_CMD, v4l_stub_try_encoder_cmd, v4l_print_encoder_cmd, INFO_FL_CLEAR(v4l2_encoder_cmd, flags)),
28273ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_DECODER_CMD, v4l_stub_decoder_cmd, v4l_print_decoder_cmd, INFO_FL_PRIO),
28283ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_TRY_DECODER_CMD, v4l_stub_try_decoder_cmd, v4l_print_decoder_cmd, 0),
28293ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_DBG_S_REGISTER, v4l_dbg_s_register, v4l_print_dbg_register, 0),
28303ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_DBG_G_REGISTER, v4l_dbg_g_register, v4l_print_dbg_register, 0),
28313ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_S_HW_FREQ_SEEK, v4l_s_hw_freq_seek, v4l_print_hw_freq_seek, INFO_FL_PRIO),
28323ad3b7a2SSami 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)),
28333ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_G_DV_TIMINGS, v4l_stub_g_dv_timings, v4l_print_dv_timings, 0),
28343ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_DQEVENT, v4l_dqevent, v4l_print_event, 0),
28353ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_SUBSCRIBE_EVENT, v4l_subscribe_event, v4l_print_event_subscription, 0),
28363ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_UNSUBSCRIBE_EVENT, v4l_unsubscribe_event, v4l_print_event_subscription, 0),
28373ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_CREATE_BUFS, v4l_create_bufs, v4l_print_create_buffers, INFO_FL_PRIO | INFO_FL_QUEUE),
28383ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_PREPARE_BUF, v4l_prepare_buf, v4l_print_buffer, INFO_FL_QUEUE),
28393ad3b7a2SSami 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)),
28403ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_QUERY_DV_TIMINGS, v4l_stub_query_dv_timings, v4l_print_dv_timings, INFO_FL_ALWAYS_COPY),
28413ad3b7a2SSami 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)),
28423ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_ENUM_FREQ_BANDS, v4l_enum_freq_bands, v4l_print_freq_band, 0),
28433ad3b7a2SSami 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)),
28443ad3b7a2SSami 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)),
28455bc3cb74SMauro Carvalho Chehab };
28465bc3cb74SMauro Carvalho Chehab #define V4L2_IOCTLS ARRAY_SIZE(v4l2_ioctls)
28475bc3cb74SMauro Carvalho Chehab 
284873a11062SHans Verkuil static bool v4l2_is_known_ioctl(unsigned int cmd)
28495bc3cb74SMauro Carvalho Chehab {
28505bc3cb74SMauro Carvalho Chehab 	if (_IOC_NR(cmd) >= V4L2_IOCTLS)
28515bc3cb74SMauro Carvalho Chehab 		return false;
28525bc3cb74SMauro Carvalho Chehab 	return v4l2_ioctls[_IOC_NR(cmd)].ioctl == cmd;
28535bc3cb74SMauro Carvalho Chehab }
28545bc3cb74SMauro Carvalho Chehab 
285573a11062SHans Verkuil static struct mutex *v4l2_ioctl_get_lock(struct video_device *vdev,
2856d862bc08SHans Verkuil 					 struct v4l2_fh *vfh, unsigned int cmd,
2857d862bc08SHans Verkuil 					 void *arg)
28585bc3cb74SMauro Carvalho Chehab {
28595bc3cb74SMauro Carvalho Chehab 	if (_IOC_NR(cmd) >= V4L2_IOCTLS)
28605bc3cb74SMauro Carvalho Chehab 		return vdev->lock;
2861d862bc08SHans Verkuil 	if (vfh && vfh->m2m_ctx &&
2862d862bc08SHans Verkuil 	    (v4l2_ioctls[_IOC_NR(cmd)].flags & INFO_FL_QUEUE)) {
2863542a522dSEzequiel Garcia 		if (vfh->m2m_ctx->q_lock)
2864542a522dSEzequiel Garcia 			return vfh->m2m_ctx->q_lock;
2865d862bc08SHans Verkuil 	}
28665bc3cb74SMauro Carvalho Chehab 	if (vdev->queue && vdev->queue->lock &&
28675bc3cb74SMauro Carvalho Chehab 			(v4l2_ioctls[_IOC_NR(cmd)].flags & INFO_FL_QUEUE))
28685bc3cb74SMauro Carvalho Chehab 		return vdev->queue->lock;
28695bc3cb74SMauro Carvalho Chehab 	return vdev->lock;
28705bc3cb74SMauro Carvalho Chehab }
28715bc3cb74SMauro Carvalho Chehab 
28725bc3cb74SMauro Carvalho Chehab /* Common ioctl debug function. This function can be used by
28735bc3cb74SMauro Carvalho Chehab    external ioctl messages as well as internal V4L ioctl */
28745bc3cb74SMauro Carvalho Chehab void v4l_printk_ioctl(const char *prefix, unsigned int cmd)
28755bc3cb74SMauro Carvalho Chehab {
28765bc3cb74SMauro Carvalho Chehab 	const char *dir, *type;
28775bc3cb74SMauro Carvalho Chehab 
28785bc3cb74SMauro Carvalho Chehab 	if (prefix)
28795bc3cb74SMauro Carvalho Chehab 		printk(KERN_DEBUG "%s: ", prefix);
28805bc3cb74SMauro Carvalho Chehab 
28815bc3cb74SMauro Carvalho Chehab 	switch (_IOC_TYPE(cmd)) {
28825bc3cb74SMauro Carvalho Chehab 	case 'd':
28835bc3cb74SMauro Carvalho Chehab 		type = "v4l2_int";
28845bc3cb74SMauro Carvalho Chehab 		break;
28855bc3cb74SMauro Carvalho Chehab 	case 'V':
28865bc3cb74SMauro Carvalho Chehab 		if (_IOC_NR(cmd) >= V4L2_IOCTLS) {
28875bc3cb74SMauro Carvalho Chehab 			type = "v4l2";
28885bc3cb74SMauro Carvalho Chehab 			break;
28895bc3cb74SMauro Carvalho Chehab 		}
28905bc3cb74SMauro Carvalho Chehab 		pr_cont("%s", v4l2_ioctls[_IOC_NR(cmd)].name);
28915bc3cb74SMauro Carvalho Chehab 		return;
28925bc3cb74SMauro Carvalho Chehab 	default:
28935bc3cb74SMauro Carvalho Chehab 		type = "unknown";
28945bc3cb74SMauro Carvalho Chehab 		break;
28955bc3cb74SMauro Carvalho Chehab 	}
28965bc3cb74SMauro Carvalho Chehab 
28975bc3cb74SMauro Carvalho Chehab 	switch (_IOC_DIR(cmd)) {
28985bc3cb74SMauro Carvalho Chehab 	case _IOC_NONE:              dir = "--"; break;
28995bc3cb74SMauro Carvalho Chehab 	case _IOC_READ:              dir = "r-"; break;
29005bc3cb74SMauro Carvalho Chehab 	case _IOC_WRITE:             dir = "-w"; break;
29015bc3cb74SMauro Carvalho Chehab 	case _IOC_READ | _IOC_WRITE: dir = "rw"; break;
29025bc3cb74SMauro Carvalho Chehab 	default:                     dir = "*ERR*"; break;
29035bc3cb74SMauro Carvalho Chehab 	}
29045bc3cb74SMauro Carvalho Chehab 	pr_cont("%s ioctl '%c', dir=%s, #%d (0x%08x)",
29055bc3cb74SMauro Carvalho Chehab 		type, _IOC_TYPE(cmd), dir, _IOC_NR(cmd), cmd);
29065bc3cb74SMauro Carvalho Chehab }
29075bc3cb74SMauro Carvalho Chehab EXPORT_SYMBOL(v4l_printk_ioctl);
29085bc3cb74SMauro Carvalho Chehab 
29095bc3cb74SMauro Carvalho Chehab static long __video_do_ioctl(struct file *file,
29105bc3cb74SMauro Carvalho Chehab 		unsigned int cmd, void *arg)
29115bc3cb74SMauro Carvalho Chehab {
29125bc3cb74SMauro Carvalho Chehab 	struct video_device *vfd = video_devdata(file);
2913cc6eddcdSHans Verkuil 	struct mutex *req_queue_lock = NULL;
291473a11062SHans Verkuil 	struct mutex *lock; /* ioctl serialization mutex */
29155bc3cb74SMauro Carvalho Chehab 	const struct v4l2_ioctl_ops *ops = vfd->ioctl_ops;
29165bc3cb74SMauro Carvalho Chehab 	bool write_only = false;
29175bc3cb74SMauro Carvalho Chehab 	struct v4l2_ioctl_info default_info;
29185bc3cb74SMauro Carvalho Chehab 	const struct v4l2_ioctl_info *info;
29195bc3cb74SMauro Carvalho Chehab 	void *fh = file->private_data;
29205bc3cb74SMauro Carvalho Chehab 	struct v4l2_fh *vfh = NULL;
292117028cdbSHans Verkuil 	int dev_debug = vfd->dev_debug;
29225bc3cb74SMauro Carvalho Chehab 	long ret = -ENOTTY;
29235bc3cb74SMauro Carvalho Chehab 
29245bc3cb74SMauro Carvalho Chehab 	if (ops == NULL) {
29255bc3cb74SMauro Carvalho Chehab 		pr_warn("%s: has no ioctl_ops.\n",
29265bc3cb74SMauro Carvalho Chehab 				video_device_node_name(vfd));
29275bc3cb74SMauro Carvalho Chehab 		return ret;
29285bc3cb74SMauro Carvalho Chehab 	}
29295bc3cb74SMauro Carvalho Chehab 
2930b7284bb0SRamakrishnan Muthukrishnan 	if (test_bit(V4L2_FL_USES_V4L2_FH, &vfd->flags))
29315bc3cb74SMauro Carvalho Chehab 		vfh = file->private_data;
29325bc3cb74SMauro Carvalho Chehab 
2933cc6eddcdSHans Verkuil 	/*
2934cc6eddcdSHans Verkuil 	 * We need to serialize streamon/off with queueing new requests.
2935cc6eddcdSHans Verkuil 	 * These ioctls may trigger the cancellation of a streaming
2936cc6eddcdSHans Verkuil 	 * operation, and that should not be mixed with queueing a new
2937cc6eddcdSHans Verkuil 	 * request at the same time.
2938cc6eddcdSHans Verkuil 	 */
2939cc6eddcdSHans Verkuil 	if (v4l2_device_supports_requests(vfd->v4l2_dev) &&
2940cc6eddcdSHans Verkuil 	    (cmd == VIDIOC_STREAMON || cmd == VIDIOC_STREAMOFF)) {
2941cc6eddcdSHans Verkuil 		req_queue_lock = &vfd->v4l2_dev->mdev->req_queue_mutex;
2942cc6eddcdSHans Verkuil 
2943cc6eddcdSHans Verkuil 		if (mutex_lock_interruptible(req_queue_lock))
2944cc6eddcdSHans Verkuil 			return -ERESTARTSYS;
2945cc6eddcdSHans Verkuil 	}
2946cc6eddcdSHans Verkuil 
2947d862bc08SHans Verkuil 	lock = v4l2_ioctl_get_lock(vfd, vfh, cmd, arg);
294873a11062SHans Verkuil 
2949cc6eddcdSHans Verkuil 	if (lock && mutex_lock_interruptible(lock)) {
2950cc6eddcdSHans Verkuil 		if (req_queue_lock)
2951cc6eddcdSHans Verkuil 			mutex_unlock(req_queue_lock);
295273a11062SHans Verkuil 		return -ERESTARTSYS;
2953cc6eddcdSHans Verkuil 	}
295473a11062SHans Verkuil 
295573a11062SHans Verkuil 	if (!video_is_registered(vfd)) {
295673a11062SHans Verkuil 		ret = -ENODEV;
295773a11062SHans Verkuil 		goto unlock;
295873a11062SHans Verkuil 	}
295973a11062SHans Verkuil 
29605bc3cb74SMauro Carvalho Chehab 	if (v4l2_is_known_ioctl(cmd)) {
29615bc3cb74SMauro Carvalho Chehab 		info = &v4l2_ioctls[_IOC_NR(cmd)];
29625bc3cb74SMauro Carvalho Chehab 
29635bc3cb74SMauro Carvalho Chehab 		if (!test_bit(_IOC_NR(cmd), vfd->valid_ioctls) &&
29645bc3cb74SMauro Carvalho Chehab 		    !((info->flags & INFO_FL_CTRL) && vfh && vfh->ctrl_handler))
29655bc3cb74SMauro Carvalho Chehab 			goto done;
29665bc3cb74SMauro Carvalho Chehab 
2967b7284bb0SRamakrishnan Muthukrishnan 		if (vfh && (info->flags & INFO_FL_PRIO)) {
29685bc3cb74SMauro Carvalho Chehab 			ret = v4l2_prio_check(vfd->prio, vfh->prio);
29695bc3cb74SMauro Carvalho Chehab 			if (ret)
29705bc3cb74SMauro Carvalho Chehab 				goto done;
29715bc3cb74SMauro Carvalho Chehab 		}
29725bc3cb74SMauro Carvalho Chehab 	} else {
29735bc3cb74SMauro Carvalho Chehab 		default_info.ioctl = cmd;
29745bc3cb74SMauro Carvalho Chehab 		default_info.flags = 0;
29755bc3cb74SMauro Carvalho Chehab 		default_info.debug = v4l_print_default;
29765bc3cb74SMauro Carvalho Chehab 		info = &default_info;
29775bc3cb74SMauro Carvalho Chehab 	}
29785bc3cb74SMauro Carvalho Chehab 
29795bc3cb74SMauro Carvalho Chehab 	write_only = _IOC_DIR(cmd) == _IOC_WRITE;
29803ad3b7a2SSami Tolvanen 	if (info != &default_info) {
29813ad3b7a2SSami Tolvanen 		ret = info->func(ops, file, fh, arg);
29825bc3cb74SMauro Carvalho Chehab 	} else if (!ops->vidioc_default) {
29835bc3cb74SMauro Carvalho Chehab 		ret = -ENOTTY;
29845bc3cb74SMauro Carvalho Chehab 	} else {
29855bc3cb74SMauro Carvalho Chehab 		ret = ops->vidioc_default(file, fh,
2986b7284bb0SRamakrishnan Muthukrishnan 			vfh ? v4l2_prio_check(vfd->prio, vfh->prio) >= 0 : 0,
29875bc3cb74SMauro Carvalho Chehab 			cmd, arg);
29885bc3cb74SMauro Carvalho Chehab 	}
29895bc3cb74SMauro Carvalho Chehab 
29905bc3cb74SMauro Carvalho Chehab done:
299117028cdbSHans Verkuil 	if (dev_debug & (V4L2_DEV_DEBUG_IOCTL | V4L2_DEV_DEBUG_IOCTL_ARG)) {
299217028cdbSHans Verkuil 		if (!(dev_debug & V4L2_DEV_DEBUG_STREAMING) &&
299317028cdbSHans Verkuil 		    (cmd == VIDIOC_QBUF || cmd == VIDIOC_DQBUF))
29945983d3bcSHans Verkuil 			goto unlock;
299517028cdbSHans Verkuil 
29965bc3cb74SMauro Carvalho Chehab 		v4l_printk_ioctl(video_device_node_name(vfd), cmd);
29975bc3cb74SMauro Carvalho Chehab 		if (ret < 0)
2998505d04bdSHans Verkuil 			pr_cont(": error %ld", ret);
299917028cdbSHans Verkuil 		if (!(dev_debug & V4L2_DEV_DEBUG_IOCTL_ARG))
30005bc3cb74SMauro Carvalho Chehab 			pr_cont("\n");
30015bc3cb74SMauro Carvalho Chehab 		else if (_IOC_DIR(cmd) == _IOC_NONE)
30025bc3cb74SMauro Carvalho Chehab 			info->debug(arg, write_only);
30035bc3cb74SMauro Carvalho Chehab 		else {
30045bc3cb74SMauro Carvalho Chehab 			pr_cont(": ");
30055bc3cb74SMauro Carvalho Chehab 			info->debug(arg, write_only);
30065bc3cb74SMauro Carvalho Chehab 		}
30075bc3cb74SMauro Carvalho Chehab 	}
30085bc3cb74SMauro Carvalho Chehab 
300973a11062SHans Verkuil unlock:
301073a11062SHans Verkuil 	if (lock)
301173a11062SHans Verkuil 		mutex_unlock(lock);
3012cc6eddcdSHans Verkuil 	if (req_queue_lock)
3013cc6eddcdSHans Verkuil 		mutex_unlock(req_queue_lock);
30145bc3cb74SMauro Carvalho Chehab 	return ret;
30155bc3cb74SMauro Carvalho Chehab }
30165bc3cb74SMauro Carvalho Chehab 
30175bc3cb74SMauro Carvalho Chehab static int check_array_args(unsigned int cmd, void *parg, size_t *array_size,
3018ba2d35c1SHans Verkuil 			    void __user **user_ptr, void ***kernel_ptr)
30195bc3cb74SMauro Carvalho Chehab {
30205bc3cb74SMauro Carvalho Chehab 	int ret = 0;
30215bc3cb74SMauro Carvalho Chehab 
30225bc3cb74SMauro Carvalho Chehab 	switch (cmd) {
302396b1a702SHans Verkuil 	case VIDIOC_PREPARE_BUF:
30245bc3cb74SMauro Carvalho Chehab 	case VIDIOC_QUERYBUF:
30255bc3cb74SMauro Carvalho Chehab 	case VIDIOC_QBUF:
30265bc3cb74SMauro Carvalho Chehab 	case VIDIOC_DQBUF: {
30275bc3cb74SMauro Carvalho Chehab 		struct v4l2_buffer *buf = parg;
30285bc3cb74SMauro Carvalho Chehab 
30295bc3cb74SMauro Carvalho Chehab 		if (V4L2_TYPE_IS_MULTIPLANAR(buf->type) && buf->length > 0) {
30305bc3cb74SMauro Carvalho Chehab 			if (buf->length > VIDEO_MAX_PLANES) {
30315bc3cb74SMauro Carvalho Chehab 				ret = -EINVAL;
30325bc3cb74SMauro Carvalho Chehab 				break;
30335bc3cb74SMauro Carvalho Chehab 			}
30345bc3cb74SMauro Carvalho Chehab 			*user_ptr = (void __user *)buf->m.planes;
3035ba2d35c1SHans Verkuil 			*kernel_ptr = (void **)&buf->m.planes;
30365bc3cb74SMauro Carvalho Chehab 			*array_size = sizeof(struct v4l2_plane) * buf->length;
30375bc3cb74SMauro Carvalho Chehab 			ret = 1;
30385bc3cb74SMauro Carvalho Chehab 		}
30395bc3cb74SMauro Carvalho Chehab 		break;
30405bc3cb74SMauro Carvalho Chehab 	}
30415bc3cb74SMauro Carvalho Chehab 
3042dd519bb3SHans Verkuil 	case VIDIOC_G_EDID:
3043dd519bb3SHans Verkuil 	case VIDIOC_S_EDID: {
3044dd519bb3SHans Verkuil 		struct v4l2_edid *edid = parg;
3045ed45ce2cSHans Verkuil 
3046ed45ce2cSHans Verkuil 		if (edid->blocks) {
30471b8b10ccSHans Verkuil 			if (edid->blocks > 256) {
30481b8b10ccSHans Verkuil 				ret = -EINVAL;
30491b8b10ccSHans Verkuil 				break;
30501b8b10ccSHans Verkuil 			}
3051ed45ce2cSHans Verkuil 			*user_ptr = (void __user *)edid->edid;
3052ba2d35c1SHans Verkuil 			*kernel_ptr = (void **)&edid->edid;
3053ed45ce2cSHans Verkuil 			*array_size = edid->blocks * 128;
3054ed45ce2cSHans Verkuil 			ret = 1;
3055ed45ce2cSHans Verkuil 		}
3056ed45ce2cSHans Verkuil 		break;
3057ed45ce2cSHans Verkuil 	}
3058ed45ce2cSHans Verkuil 
30595bc3cb74SMauro Carvalho Chehab 	case VIDIOC_S_EXT_CTRLS:
30605bc3cb74SMauro Carvalho Chehab 	case VIDIOC_G_EXT_CTRLS:
30615bc3cb74SMauro Carvalho Chehab 	case VIDIOC_TRY_EXT_CTRLS: {
30625bc3cb74SMauro Carvalho Chehab 		struct v4l2_ext_controls *ctrls = parg;
30635bc3cb74SMauro Carvalho Chehab 
30645bc3cb74SMauro Carvalho Chehab 		if (ctrls->count != 0) {
30655bc3cb74SMauro Carvalho Chehab 			if (ctrls->count > V4L2_CID_MAX_CTRLS) {
30665bc3cb74SMauro Carvalho Chehab 				ret = -EINVAL;
30675bc3cb74SMauro Carvalho Chehab 				break;
30685bc3cb74SMauro Carvalho Chehab 			}
30695bc3cb74SMauro Carvalho Chehab 			*user_ptr = (void __user *)ctrls->controls;
3070ba2d35c1SHans Verkuil 			*kernel_ptr = (void **)&ctrls->controls;
30715bc3cb74SMauro Carvalho Chehab 			*array_size = sizeof(struct v4l2_ext_control)
30725bc3cb74SMauro Carvalho Chehab 				    * ctrls->count;
30735bc3cb74SMauro Carvalho Chehab 			ret = 1;
30745bc3cb74SMauro Carvalho Chehab 		}
30755bc3cb74SMauro Carvalho Chehab 		break;
30765bc3cb74SMauro Carvalho Chehab 	}
30773f65c6f6SArnd Bergmann 	case VIDIOC_G_FMT:
30783f65c6f6SArnd Bergmann 	case VIDIOC_S_FMT:
30793f65c6f6SArnd Bergmann 	case VIDIOC_TRY_FMT: {
30803f65c6f6SArnd Bergmann 		struct v4l2_format *fmt = parg;
30813f65c6f6SArnd Bergmann 
30823f65c6f6SArnd Bergmann 		if (fmt->type != V4L2_BUF_TYPE_VIDEO_OVERLAY &&
30833f65c6f6SArnd Bergmann 		    fmt->type != V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY)
30843f65c6f6SArnd Bergmann 			break;
30853f65c6f6SArnd Bergmann 		if (fmt->fmt.win.clipcount > 2048)
30863f65c6f6SArnd Bergmann 			return -EINVAL;
30873f65c6f6SArnd Bergmann 		if (!fmt->fmt.win.clipcount)
30883f65c6f6SArnd Bergmann 			break;
30893f65c6f6SArnd Bergmann 
30903f65c6f6SArnd Bergmann 		*user_ptr = (void __user *)fmt->fmt.win.clips;
30913f65c6f6SArnd Bergmann 		*kernel_ptr = (void **)&fmt->fmt.win.clips;
30923f65c6f6SArnd Bergmann 		*array_size = sizeof(struct v4l2_clip)
30933f65c6f6SArnd Bergmann 				* fmt->fmt.win.clipcount;
30943f65c6f6SArnd Bergmann 
30953f65c6f6SArnd Bergmann 		ret = 1;
30963f65c6f6SArnd Bergmann 		break;
30973f65c6f6SArnd Bergmann 	}
30985bc3cb74SMauro Carvalho Chehab 	}
30995bc3cb74SMauro Carvalho Chehab 
31005bc3cb74SMauro Carvalho Chehab 	return ret;
31015bc3cb74SMauro Carvalho Chehab }
31025bc3cb74SMauro Carvalho Chehab 
3103c8ef1a60SArnd Bergmann static unsigned int video_translate_cmd(unsigned int cmd)
3104c8ef1a60SArnd Bergmann {
3105c344f07aSArnd Bergmann #if !defined(CONFIG_64BIT) && defined(CONFIG_COMPAT_32BIT_TIME)
31061a6c0b36SArnd Bergmann 	switch (cmd) {
31071a6c0b36SArnd Bergmann 	case VIDIOC_DQEVENT_TIME32:
31081a6c0b36SArnd Bergmann 		return VIDIOC_DQEVENT;
3109577c89b0SArnd Bergmann 	case VIDIOC_QUERYBUF_TIME32:
3110577c89b0SArnd Bergmann 		return VIDIOC_QUERYBUF;
3111577c89b0SArnd Bergmann 	case VIDIOC_QBUF_TIME32:
3112577c89b0SArnd Bergmann 		return VIDIOC_QBUF;
3113577c89b0SArnd Bergmann 	case VIDIOC_DQBUF_TIME32:
3114577c89b0SArnd Bergmann 		return VIDIOC_DQBUF;
3115577c89b0SArnd Bergmann 	case VIDIOC_PREPARE_BUF_TIME32:
3116577c89b0SArnd Bergmann 		return VIDIOC_PREPARE_BUF;
31171a6c0b36SArnd Bergmann 	}
3118c344f07aSArnd Bergmann #endif
31198dbcc3faSArnd Bergmann 	if (in_compat_syscall())
31208dbcc3faSArnd Bergmann 		return v4l2_compat_translate_cmd(cmd);
31211a6c0b36SArnd Bergmann 
3122c8ef1a60SArnd Bergmann 	return cmd;
3123c8ef1a60SArnd Bergmann }
3124c8ef1a60SArnd Bergmann 
31258dbcc3faSArnd Bergmann static int video_get_user(void __user *arg, void *parg,
31268dbcc3faSArnd Bergmann 			  unsigned int real_cmd, unsigned int cmd,
3127c8ef1a60SArnd Bergmann 			  bool *always_copy)
3128c8ef1a60SArnd Bergmann {
31298dbcc3faSArnd Bergmann 	unsigned int n = _IOC_SIZE(real_cmd);
31308dbcc3faSArnd Bergmann 	int err = 0;
3131c8ef1a60SArnd Bergmann 
3132c8ef1a60SArnd Bergmann 	if (!(_IOC_DIR(cmd) & _IOC_WRITE)) {
3133c8ef1a60SArnd Bergmann 		/* read-only ioctl */
3134c8ef1a60SArnd Bergmann 		memset(parg, 0, n);
3135c8ef1a60SArnd Bergmann 		return 0;
3136c8ef1a60SArnd Bergmann 	}
3137c8ef1a60SArnd Bergmann 
31388dbcc3faSArnd Bergmann 	/*
31398dbcc3faSArnd Bergmann 	 * In some cases, only a few fields are used as input,
31408dbcc3faSArnd Bergmann 	 * i.e. when the app sets "index" and then the driver
31418dbcc3faSArnd Bergmann 	 * fills in the rest of the structure for the thing
31428dbcc3faSArnd Bergmann 	 * with that index.  We only need to copy up the first
31438dbcc3faSArnd Bergmann 	 * non-input field.
31448dbcc3faSArnd Bergmann 	 */
31458dbcc3faSArnd Bergmann 	if (v4l2_is_known_ioctl(real_cmd)) {
31468dbcc3faSArnd Bergmann 		u32 flags = v4l2_ioctls[_IOC_NR(real_cmd)].flags;
31478dbcc3faSArnd Bergmann 
31488dbcc3faSArnd Bergmann 		if (flags & INFO_FL_CLEAR_MASK)
31498dbcc3faSArnd Bergmann 			n = (flags & INFO_FL_CLEAR_MASK) >> 16;
31508dbcc3faSArnd Bergmann 		*always_copy = flags & INFO_FL_ALWAYS_COPY;
31518dbcc3faSArnd Bergmann 	}
31528dbcc3faSArnd Bergmann 
31538dbcc3faSArnd Bergmann 	if (cmd == real_cmd) {
31548dbcc3faSArnd Bergmann 		if (copy_from_user(parg, (void __user *)arg, n))
31558dbcc3faSArnd Bergmann 			err = -EFAULT;
31568dbcc3faSArnd Bergmann 	} else if (in_compat_syscall()) {
31577b53cca7SArnd Bergmann 		memset(parg, 0, n);
31588dbcc3faSArnd Bergmann 		err = v4l2_compat_get_user(arg, parg, cmd);
31598dbcc3faSArnd Bergmann 	} else {
31607b53cca7SArnd Bergmann 		memset(parg, 0, n);
3161c344f07aSArnd Bergmann #if !defined(CONFIG_64BIT) && defined(CONFIG_COMPAT_32BIT_TIME)
3162c8ef1a60SArnd Bergmann 		switch (cmd) {
3163577c89b0SArnd Bergmann 		case VIDIOC_QUERYBUF_TIME32:
3164577c89b0SArnd Bergmann 		case VIDIOC_QBUF_TIME32:
3165577c89b0SArnd Bergmann 		case VIDIOC_DQBUF_TIME32:
3166577c89b0SArnd Bergmann 		case VIDIOC_PREPARE_BUF_TIME32: {
3167577c89b0SArnd Bergmann 			struct v4l2_buffer_time32 vb32;
3168577c89b0SArnd Bergmann 			struct v4l2_buffer *vb = parg;
3169577c89b0SArnd Bergmann 
3170577c89b0SArnd Bergmann 			if (copy_from_user(&vb32, arg, sizeof(vb32)))
3171577c89b0SArnd Bergmann 				return -EFAULT;
3172577c89b0SArnd Bergmann 
3173577c89b0SArnd Bergmann 			*vb = (struct v4l2_buffer) {
3174577c89b0SArnd Bergmann 				.index		= vb32.index,
3175577c89b0SArnd Bergmann 				.type		= vb32.type,
3176577c89b0SArnd Bergmann 				.bytesused	= vb32.bytesused,
3177577c89b0SArnd Bergmann 				.flags		= vb32.flags,
3178577c89b0SArnd Bergmann 				.field		= vb32.field,
3179577c89b0SArnd Bergmann 				.timestamp.tv_sec	= vb32.timestamp.tv_sec,
3180577c89b0SArnd Bergmann 				.timestamp.tv_usec	= vb32.timestamp.tv_usec,
3181577c89b0SArnd Bergmann 				.timecode	= vb32.timecode,
3182577c89b0SArnd Bergmann 				.sequence	= vb32.sequence,
3183577c89b0SArnd Bergmann 				.memory		= vb32.memory,
3184577c89b0SArnd Bergmann 				.m.userptr	= vb32.m.userptr,
3185577c89b0SArnd Bergmann 				.length		= vb32.length,
3186577c89b0SArnd Bergmann 				.request_fd	= vb32.request_fd,
3187577c89b0SArnd Bergmann 			};
3188577c89b0SArnd Bergmann 			break;
3189577c89b0SArnd Bergmann 		}
3190c8ef1a60SArnd Bergmann 		}
3191c344f07aSArnd Bergmann #endif
31928dbcc3faSArnd Bergmann 	}
3193c8ef1a60SArnd Bergmann 
3194c8ef1a60SArnd Bergmann 	/* zero out anything we don't copy from userspace */
31958dbcc3faSArnd Bergmann 	if (!err && n < _IOC_SIZE(real_cmd))
31968dbcc3faSArnd Bergmann 		memset((u8 *)parg + n, 0, _IOC_SIZE(real_cmd) - n);
31978dbcc3faSArnd Bergmann 	return err;
3198c8ef1a60SArnd Bergmann }
3199c8ef1a60SArnd Bergmann 
32008dbcc3faSArnd Bergmann static int video_put_user(void __user *arg, void *parg,
32018dbcc3faSArnd Bergmann 			  unsigned int real_cmd, unsigned int cmd)
3202c8ef1a60SArnd Bergmann {
3203c8ef1a60SArnd Bergmann 	if (!(_IOC_DIR(cmd) & _IOC_READ))
3204c8ef1a60SArnd Bergmann 		return 0;
3205c8ef1a60SArnd Bergmann 
32068dbcc3faSArnd Bergmann 	if (cmd == real_cmd) {
32078dbcc3faSArnd Bergmann 		/*  Copy results into user buffer  */
32088dbcc3faSArnd Bergmann 		if (copy_to_user(arg, parg, _IOC_SIZE(cmd)))
32098dbcc3faSArnd Bergmann 			return -EFAULT;
32108dbcc3faSArnd Bergmann 		return 0;
32118dbcc3faSArnd Bergmann 	}
32128dbcc3faSArnd Bergmann 
32138dbcc3faSArnd Bergmann 	if (in_compat_syscall())
32148dbcc3faSArnd Bergmann 		return v4l2_compat_put_user(arg, parg, cmd);
32158dbcc3faSArnd Bergmann 
3216c344f07aSArnd Bergmann #if !defined(CONFIG_64BIT) && defined(CONFIG_COMPAT_32BIT_TIME)
3217c8ef1a60SArnd Bergmann 	switch (cmd) {
32181a6c0b36SArnd Bergmann 	case VIDIOC_DQEVENT_TIME32: {
32191a6c0b36SArnd Bergmann 		struct v4l2_event *ev = parg;
32204ffb879eSPeilin Ye 		struct v4l2_event_time32 ev32;
32214ffb879eSPeilin Ye 
32224ffb879eSPeilin Ye 		memset(&ev32, 0, sizeof(ev32));
32234ffb879eSPeilin Ye 
32244ffb879eSPeilin Ye 		ev32.type	= ev->type;
32254ffb879eSPeilin Ye 		ev32.pending	= ev->pending;
32264ffb879eSPeilin Ye 		ev32.sequence	= ev->sequence;
32274ffb879eSPeilin Ye 		ev32.timestamp.tv_sec	= ev->timestamp.tv_sec;
32284ffb879eSPeilin Ye 		ev32.timestamp.tv_nsec	= ev->timestamp.tv_nsec;
32294ffb879eSPeilin Ye 		ev32.id		= ev->id;
32301a6c0b36SArnd Bergmann 
32311a6c0b36SArnd Bergmann 		memcpy(&ev32.u, &ev->u, sizeof(ev->u));
32321a6c0b36SArnd Bergmann 		memcpy(&ev32.reserved, &ev->reserved, sizeof(ev->reserved));
32331a6c0b36SArnd Bergmann 
32341a6c0b36SArnd Bergmann 		if (copy_to_user(arg, &ev32, sizeof(ev32)))
32351a6c0b36SArnd Bergmann 			return -EFAULT;
32361a6c0b36SArnd Bergmann 		break;
32371a6c0b36SArnd Bergmann 	}
3238577c89b0SArnd Bergmann 	case VIDIOC_QUERYBUF_TIME32:
3239577c89b0SArnd Bergmann 	case VIDIOC_QBUF_TIME32:
3240577c89b0SArnd Bergmann 	case VIDIOC_DQBUF_TIME32:
3241577c89b0SArnd Bergmann 	case VIDIOC_PREPARE_BUF_TIME32: {
3242577c89b0SArnd Bergmann 		struct v4l2_buffer *vb = parg;
32434ffb879eSPeilin Ye 		struct v4l2_buffer_time32 vb32;
32444ffb879eSPeilin Ye 
32454ffb879eSPeilin Ye 		memset(&vb32, 0, sizeof(vb32));
32464ffb879eSPeilin Ye 
32474ffb879eSPeilin Ye 		vb32.index	= vb->index;
32484ffb879eSPeilin Ye 		vb32.type	= vb->type;
32494ffb879eSPeilin Ye 		vb32.bytesused	= vb->bytesused;
32504ffb879eSPeilin Ye 		vb32.flags	= vb->flags;
32514ffb879eSPeilin Ye 		vb32.field	= vb->field;
32524ffb879eSPeilin Ye 		vb32.timestamp.tv_sec	= vb->timestamp.tv_sec;
32534ffb879eSPeilin Ye 		vb32.timestamp.tv_usec	= vb->timestamp.tv_usec;
32544ffb879eSPeilin Ye 		vb32.timecode	= vb->timecode;
32554ffb879eSPeilin Ye 		vb32.sequence	= vb->sequence;
32564ffb879eSPeilin Ye 		vb32.memory	= vb->memory;
32574ffb879eSPeilin Ye 		vb32.m.userptr	= vb->m.userptr;
32584ffb879eSPeilin Ye 		vb32.length	= vb->length;
32594ffb879eSPeilin Ye 		vb32.request_fd	= vb->request_fd;
3260577c89b0SArnd Bergmann 
3261577c89b0SArnd Bergmann 		if (copy_to_user(arg, &vb32, sizeof(vb32)))
3262577c89b0SArnd Bergmann 			return -EFAULT;
3263577c89b0SArnd Bergmann 		break;
3264577c89b0SArnd Bergmann 	}
3265c8ef1a60SArnd Bergmann 	}
3266c344f07aSArnd Bergmann #endif
3267c8ef1a60SArnd Bergmann 
3268c8ef1a60SArnd Bergmann 	return 0;
3269c8ef1a60SArnd Bergmann }
3270c8ef1a60SArnd Bergmann 
32715bc3cb74SMauro Carvalho Chehab long
3272c8ef1a60SArnd Bergmann video_usercopy(struct file *file, unsigned int orig_cmd, unsigned long arg,
32735bc3cb74SMauro Carvalho Chehab 	       v4l2_kioctl func)
32745bc3cb74SMauro Carvalho Chehab {
32755bc3cb74SMauro Carvalho Chehab 	char	sbuf[128];
3276fb18802aSSakari Ailus 	void    *mbuf = NULL, *array_buf = NULL;
32775bc3cb74SMauro Carvalho Chehab 	void	*parg = (void *)arg;
32785bc3cb74SMauro Carvalho Chehab 	long	err  = -EINVAL;
32795bc3cb74SMauro Carvalho Chehab 	bool	has_array_args;
3280043f77edSHans Verkuil 	bool	always_copy = false;
32815bc3cb74SMauro Carvalho Chehab 	size_t  array_size = 0;
32825bc3cb74SMauro Carvalho Chehab 	void __user *user_ptr = NULL;
32835bc3cb74SMauro Carvalho Chehab 	void	**kernel_ptr = NULL;
3284c8ef1a60SArnd Bergmann 	unsigned int cmd = video_translate_cmd(orig_cmd);
3285f8a695c4SMauro Carvalho Chehab 	const size_t ioc_size = _IOC_SIZE(cmd);
32865bc3cb74SMauro Carvalho Chehab 
32875bc3cb74SMauro Carvalho Chehab 	/*  Copy arguments into temp kernel buffer  */
32885bc3cb74SMauro Carvalho Chehab 	if (_IOC_DIR(cmd) != _IOC_NONE) {
3289f8a695c4SMauro Carvalho Chehab 		if (ioc_size <= sizeof(sbuf)) {
32905bc3cb74SMauro Carvalho Chehab 			parg = sbuf;
32915bc3cb74SMauro Carvalho Chehab 		} else {
32925bc3cb74SMauro Carvalho Chehab 			/* too big to allocate from stack */
329362a12551SSakari Ailus 			mbuf = kmalloc(ioc_size, GFP_KERNEL);
32945bc3cb74SMauro Carvalho Chehab 			if (NULL == mbuf)
32955bc3cb74SMauro Carvalho Chehab 				return -ENOMEM;
32965bc3cb74SMauro Carvalho Chehab 			parg = mbuf;
32975bc3cb74SMauro Carvalho Chehab 		}
32985bc3cb74SMauro Carvalho Chehab 
32998dbcc3faSArnd Bergmann 		err = video_get_user((void __user *)arg, parg, cmd,
33008dbcc3faSArnd Bergmann 				     orig_cmd, &always_copy);
3301c8ef1a60SArnd Bergmann 		if (err)
33025bc3cb74SMauro Carvalho Chehab 			goto out;
33031dc8b65cSArnd Bergmann 	}
33045bc3cb74SMauro Carvalho Chehab 
33055bc3cb74SMauro Carvalho Chehab 	err = check_array_args(cmd, parg, &array_size, &user_ptr, &kernel_ptr);
33065bc3cb74SMauro Carvalho Chehab 	if (err < 0)
33075bc3cb74SMauro Carvalho Chehab 		goto out;
33085bc3cb74SMauro Carvalho Chehab 	has_array_args = err;
33095bc3cb74SMauro Carvalho Chehab 
33105bc3cb74SMauro Carvalho Chehab 	if (has_array_args) {
3311fb18802aSSakari Ailus 		array_buf = kvmalloc(array_size, GFP_KERNEL);
33125bc3cb74SMauro Carvalho Chehab 		err = -ENOMEM;
3313fb18802aSSakari Ailus 		if (array_buf == NULL)
33145bc3cb74SMauro Carvalho Chehab 			goto out_array_args;
33155bc3cb74SMauro Carvalho Chehab 		err = -EFAULT;
33168dbcc3faSArnd Bergmann 		if (in_compat_syscall())
3317fb18802aSSakari Ailus 			err = v4l2_compat_get_array_args(file, array_buf,
3318fb18802aSSakari Ailus 							 user_ptr, array_size,
3319fb18802aSSakari Ailus 							 orig_cmd, parg);
33208dbcc3faSArnd Bergmann 		else
3321fb18802aSSakari Ailus 			err = copy_from_user(array_buf, user_ptr, array_size) ?
33228dbcc3faSArnd Bergmann 								-EFAULT : 0;
33238dbcc3faSArnd Bergmann 		if (err)
33245bc3cb74SMauro Carvalho Chehab 			goto out_array_args;
3325fb18802aSSakari Ailus 		*kernel_ptr = array_buf;
33265bc3cb74SMauro Carvalho Chehab 	}
33275bc3cb74SMauro Carvalho Chehab 
33285bc3cb74SMauro Carvalho Chehab 	/* Handles IOCTL */
33295bc3cb74SMauro Carvalho Chehab 	err = func(file, cmd, parg);
3330181a4a2dSHans Verkuil 	if (err == -ENOTTY || err == -ENOIOCTLCMD) {
33315bc3cb74SMauro Carvalho Chehab 		err = -ENOTTY;
3332181a4a2dSHans Verkuil 		goto out;
3333181a4a2dSHans Verkuil 	}
3334181a4a2dSHans Verkuil 
3335aa32f4c0SHans Verkuil 	if (err == 0) {
3336aa32f4c0SHans Verkuil 		if (cmd == VIDIOC_DQBUF)
3337aa32f4c0SHans Verkuil 			trace_v4l2_dqbuf(video_devdata(file)->minor, parg);
3338aa32f4c0SHans Verkuil 		else if (cmd == VIDIOC_QBUF)
3339aa32f4c0SHans Verkuil 			trace_v4l2_qbuf(video_devdata(file)->minor, parg);
3340aa32f4c0SHans Verkuil 	}
33415bc3cb74SMauro Carvalho Chehab 
33425bc3cb74SMauro Carvalho Chehab 	if (has_array_args) {
3343ba2d35c1SHans Verkuil 		*kernel_ptr = (void __force *)user_ptr;
33448dbcc3faSArnd Bergmann 		if (in_compat_syscall()) {
33458dbcc3faSArnd Bergmann 			int put_err;
33468dbcc3faSArnd Bergmann 
3347fb18802aSSakari Ailus 			put_err = v4l2_compat_put_array_args(file, user_ptr,
3348fb18802aSSakari Ailus 							     array_buf,
3349fb18802aSSakari Ailus 							     array_size,
3350fb18802aSSakari Ailus 							     orig_cmd, parg);
33518dbcc3faSArnd Bergmann 			if (put_err)
33528dbcc3faSArnd Bergmann 				err = put_err;
3353fb18802aSSakari Ailus 		} else if (copy_to_user(user_ptr, array_buf, array_size)) {
33545bc3cb74SMauro Carvalho Chehab 			err = -EFAULT;
33558dbcc3faSArnd Bergmann 		}
33565bc3cb74SMauro Carvalho Chehab 		goto out_array_args;
33575bc3cb74SMauro Carvalho Chehab 	}
3358043f77edSHans Verkuil 	/*
3359043f77edSHans Verkuil 	 * Some ioctls can return an error, but still have valid
3360043f77edSHans Verkuil 	 * results that must be returned.
3361043f77edSHans Verkuil 	 */
3362043f77edSHans Verkuil 	if (err < 0 && !always_copy)
33635bc3cb74SMauro Carvalho Chehab 		goto out;
33645bc3cb74SMauro Carvalho Chehab 
33655bc3cb74SMauro Carvalho Chehab out_array_args:
33668dbcc3faSArnd Bergmann 	if (video_put_user((void __user *)arg, parg, cmd, orig_cmd))
33675bc3cb74SMauro Carvalho Chehab 		err = -EFAULT;
33685bc3cb74SMauro Carvalho Chehab out:
3369fb18802aSSakari Ailus 	kvfree(array_buf);
337062a12551SSakari Ailus 	kfree(mbuf);
33715bc3cb74SMauro Carvalho Chehab 	return err;
33725bc3cb74SMauro Carvalho Chehab }
33735bc3cb74SMauro Carvalho Chehab 
33745bc3cb74SMauro Carvalho Chehab long video_ioctl2(struct file *file,
33755bc3cb74SMauro Carvalho Chehab 	       unsigned int cmd, unsigned long arg)
33765bc3cb74SMauro Carvalho Chehab {
33775bc3cb74SMauro Carvalho Chehab 	return video_usercopy(file, cmd, arg, __video_do_ioctl);
33785bc3cb74SMauro Carvalho Chehab }
33795bc3cb74SMauro Carvalho Chehab EXPORT_SYMBOL(video_ioctl2);
3380