12874c5fdSThomas Gleixner // SPDX-License-Identifier: GPL-2.0-or-later
25bc3cb74SMauro Carvalho Chehab /*
35bc3cb74SMauro Carvalho Chehab  * Video capture interface for Linux version 2
45bc3cb74SMauro Carvalho Chehab  *
55bc3cb74SMauro Carvalho Chehab  * A generic framework to process V4L2 ioctl commands.
65bc3cb74SMauro Carvalho Chehab  *
75bc3cb74SMauro Carvalho Chehab  * Authors:	Alan Cox, <alan@lxorguk.ukuu.org.uk> (version 1)
832590819SMauro Carvalho Chehab  *              Mauro Carvalho Chehab <mchehab@kernel.org> (version 2)
95bc3cb74SMauro Carvalho Chehab  */
105bc3cb74SMauro Carvalho Chehab 
118dbcc3faSArnd Bergmann #include <linux/compat.h>
12758d90e1STomasz Figa #include <linux/mm.h>
135bc3cb74SMauro Carvalho Chehab #include <linux/module.h>
145bc3cb74SMauro Carvalho Chehab #include <linux/slab.h>
155bc3cb74SMauro Carvalho Chehab #include <linux/types.h>
165bc3cb74SMauro Carvalho Chehab #include <linux/kernel.h>
175bc3cb74SMauro Carvalho Chehab #include <linux/version.h>
185bc3cb74SMauro Carvalho Chehab 
195bc3cb74SMauro Carvalho Chehab #include <linux/videodev2.h>
205bc3cb74SMauro Carvalho Chehab 
21f2d8b691SSakari Ailus #include <media/media-device.h> /* for media_set_bus_info() */
225bc3cb74SMauro Carvalho Chehab #include <media/v4l2-common.h>
235bc3cb74SMauro Carvalho Chehab #include <media/v4l2-ioctl.h>
245bc3cb74SMauro Carvalho Chehab #include <media/v4l2-ctrls.h>
255bc3cb74SMauro Carvalho Chehab #include <media/v4l2-fh.h>
265bc3cb74SMauro Carvalho Chehab #include <media/v4l2-event.h>
275bc3cb74SMauro Carvalho Chehab #include <media/v4l2-device.h>
28c139990eSJunghak Sung #include <media/videobuf2-v4l2.h>
2977fa4e07SShuah Khan #include <media/v4l2-mc.h>
30d862bc08SHans Verkuil #include <media/v4l2-mem2mem.h>
315bc3cb74SMauro Carvalho Chehab 
32aa32f4c0SHans Verkuil #include <trace/events/v4l2.h>
33aa32f4c0SHans Verkuil 
3473f35418SHans Verkuil #define is_valid_ioctl(vfd, cmd) test_bit(_IOC_NR(cmd), (vfd)->valid_ioctls)
3573f35418SHans Verkuil 
365bc3cb74SMauro Carvalho Chehab struct std_descr {
375bc3cb74SMauro Carvalho Chehab 	v4l2_std_id std;
385bc3cb74SMauro Carvalho Chehab 	const char *descr;
395bc3cb74SMauro Carvalho Chehab };
405bc3cb74SMauro Carvalho Chehab 
415bc3cb74SMauro Carvalho Chehab static const struct std_descr standards[] = {
425bc3cb74SMauro Carvalho Chehab 	{ V4L2_STD_NTSC,	"NTSC"      },
435bc3cb74SMauro Carvalho Chehab 	{ V4L2_STD_NTSC_M,	"NTSC-M"    },
445bc3cb74SMauro Carvalho Chehab 	{ V4L2_STD_NTSC_M_JP,	"NTSC-M-JP" },
455bc3cb74SMauro Carvalho Chehab 	{ V4L2_STD_NTSC_M_KR,	"NTSC-M-KR" },
465bc3cb74SMauro Carvalho Chehab 	{ V4L2_STD_NTSC_443,	"NTSC-443"  },
475bc3cb74SMauro Carvalho Chehab 	{ V4L2_STD_PAL,		"PAL"       },
485bc3cb74SMauro Carvalho Chehab 	{ V4L2_STD_PAL_BG,	"PAL-BG"    },
495bc3cb74SMauro Carvalho Chehab 	{ V4L2_STD_PAL_B,	"PAL-B"     },
505bc3cb74SMauro Carvalho Chehab 	{ V4L2_STD_PAL_B1,	"PAL-B1"    },
515bc3cb74SMauro Carvalho Chehab 	{ V4L2_STD_PAL_G,	"PAL-G"     },
525bc3cb74SMauro Carvalho Chehab 	{ V4L2_STD_PAL_H,	"PAL-H"     },
535bc3cb74SMauro Carvalho Chehab 	{ V4L2_STD_PAL_I,	"PAL-I"     },
545bc3cb74SMauro Carvalho Chehab 	{ V4L2_STD_PAL_DK,	"PAL-DK"    },
555bc3cb74SMauro Carvalho Chehab 	{ V4L2_STD_PAL_D,	"PAL-D"     },
565bc3cb74SMauro Carvalho Chehab 	{ V4L2_STD_PAL_D1,	"PAL-D1"    },
575bc3cb74SMauro Carvalho Chehab 	{ V4L2_STD_PAL_K,	"PAL-K"     },
585bc3cb74SMauro Carvalho Chehab 	{ V4L2_STD_PAL_M,	"PAL-M"     },
595bc3cb74SMauro Carvalho Chehab 	{ V4L2_STD_PAL_N,	"PAL-N"     },
605bc3cb74SMauro Carvalho Chehab 	{ V4L2_STD_PAL_Nc,	"PAL-Nc"    },
615bc3cb74SMauro Carvalho Chehab 	{ V4L2_STD_PAL_60,	"PAL-60"    },
625bc3cb74SMauro Carvalho Chehab 	{ V4L2_STD_SECAM,	"SECAM"     },
635bc3cb74SMauro Carvalho Chehab 	{ V4L2_STD_SECAM_B,	"SECAM-B"   },
645bc3cb74SMauro Carvalho Chehab 	{ V4L2_STD_SECAM_G,	"SECAM-G"   },
655bc3cb74SMauro Carvalho Chehab 	{ V4L2_STD_SECAM_H,	"SECAM-H"   },
665bc3cb74SMauro Carvalho Chehab 	{ V4L2_STD_SECAM_DK,	"SECAM-DK"  },
675bc3cb74SMauro Carvalho Chehab 	{ V4L2_STD_SECAM_D,	"SECAM-D"   },
685bc3cb74SMauro Carvalho Chehab 	{ V4L2_STD_SECAM_K,	"SECAM-K"   },
695bc3cb74SMauro Carvalho Chehab 	{ V4L2_STD_SECAM_K1,	"SECAM-K1"  },
705bc3cb74SMauro Carvalho Chehab 	{ V4L2_STD_SECAM_L,	"SECAM-L"   },
715bc3cb74SMauro Carvalho Chehab 	{ V4L2_STD_SECAM_LC,	"SECAM-Lc"  },
725bc3cb74SMauro Carvalho Chehab 	{ 0,			"Unknown"   }
735bc3cb74SMauro Carvalho Chehab };
745bc3cb74SMauro Carvalho Chehab 
755bc3cb74SMauro Carvalho Chehab /* video4linux standard ID conversion to standard name
765bc3cb74SMauro Carvalho Chehab  */
775bc3cb74SMauro Carvalho Chehab const char *v4l2_norm_to_name(v4l2_std_id id)
785bc3cb74SMauro Carvalho Chehab {
795bc3cb74SMauro Carvalho Chehab 	u32 myid = id;
805bc3cb74SMauro Carvalho Chehab 	int i;
815bc3cb74SMauro Carvalho Chehab 
825bc3cb74SMauro Carvalho Chehab 	/* HACK: ppc32 architecture doesn't have __ucmpdi2 function to handle
834faf7066SMauro Carvalho Chehab 	   64 bit comparisons. So, on that architecture, with some gcc
845bc3cb74SMauro Carvalho Chehab 	   variants, compilation fails. Currently, the max value is 30bit wide.
855bc3cb74SMauro Carvalho Chehab 	 */
865bc3cb74SMauro Carvalho Chehab 	BUG_ON(myid != id);
875bc3cb74SMauro Carvalho Chehab 
885bc3cb74SMauro Carvalho Chehab 	for (i = 0; standards[i].std; i++)
895bc3cb74SMauro Carvalho Chehab 		if (myid == standards[i].std)
905bc3cb74SMauro Carvalho Chehab 			break;
915bc3cb74SMauro Carvalho Chehab 	return standards[i].descr;
925bc3cb74SMauro Carvalho Chehab }
935bc3cb74SMauro Carvalho Chehab EXPORT_SYMBOL(v4l2_norm_to_name);
945bc3cb74SMauro Carvalho Chehab 
955bc3cb74SMauro Carvalho Chehab /* Returns frame period for the given standard */
965bc3cb74SMauro Carvalho Chehab void v4l2_video_std_frame_period(int id, struct v4l2_fract *frameperiod)
975bc3cb74SMauro Carvalho Chehab {
985bc3cb74SMauro Carvalho Chehab 	if (id & V4L2_STD_525_60) {
995bc3cb74SMauro Carvalho Chehab 		frameperiod->numerator = 1001;
1005bc3cb74SMauro Carvalho Chehab 		frameperiod->denominator = 30000;
1015bc3cb74SMauro Carvalho Chehab 	} else {
1025bc3cb74SMauro Carvalho Chehab 		frameperiod->numerator = 1;
1035bc3cb74SMauro Carvalho Chehab 		frameperiod->denominator = 25;
1045bc3cb74SMauro Carvalho Chehab 	}
1055bc3cb74SMauro Carvalho Chehab }
1065bc3cb74SMauro Carvalho Chehab EXPORT_SYMBOL(v4l2_video_std_frame_period);
1075bc3cb74SMauro Carvalho Chehab 
1085bc3cb74SMauro Carvalho Chehab /* Fill in the fields of a v4l2_standard structure according to the
1095bc3cb74SMauro Carvalho Chehab    'id' and 'transmission' parameters.  Returns negative on error.  */
1105bc3cb74SMauro Carvalho Chehab int v4l2_video_std_construct(struct v4l2_standard *vs,
1115bc3cb74SMauro Carvalho Chehab 			     int id, const char *name)
1125bc3cb74SMauro Carvalho Chehab {
1135bc3cb74SMauro Carvalho Chehab 	vs->id = id;
1145bc3cb74SMauro Carvalho Chehab 	v4l2_video_std_frame_period(id, &vs->frameperiod);
1155bc3cb74SMauro Carvalho Chehab 	vs->framelines = (id & V4L2_STD_525_60) ? 525 : 625;
116c0decac1SMauro Carvalho Chehab 	strscpy(vs->name, name, sizeof(vs->name));
1175bc3cb74SMauro Carvalho Chehab 	return 0;
1185bc3cb74SMauro Carvalho Chehab }
1195bc3cb74SMauro Carvalho Chehab EXPORT_SYMBOL(v4l2_video_std_construct);
1205bc3cb74SMauro Carvalho Chehab 
121aa2f8871SNiklas Söderlund /* Fill in the fields of a v4l2_standard structure according to the
122aa2f8871SNiklas Söderlund  * 'id' and 'vs->index' parameters. Returns negative on error. */
123aa2f8871SNiklas Söderlund int v4l_video_std_enumstd(struct v4l2_standard *vs, v4l2_std_id id)
124aa2f8871SNiklas Söderlund {
125aa2f8871SNiklas Söderlund 	v4l2_std_id curr_id = 0;
126aa2f8871SNiklas Söderlund 	unsigned int index = vs->index, i, j = 0;
127aa2f8871SNiklas Söderlund 	const char *descr = "";
128aa2f8871SNiklas Söderlund 
129aa2f8871SNiklas Söderlund 	/* Return -ENODATA if the id for the current input
130aa2f8871SNiklas Söderlund 	   or output is 0, meaning that it doesn't support this API. */
131aa2f8871SNiklas Söderlund 	if (id == 0)
132aa2f8871SNiklas Söderlund 		return -ENODATA;
133aa2f8871SNiklas Söderlund 
134aa2f8871SNiklas Söderlund 	/* Return norm array in a canonical way */
135aa2f8871SNiklas Söderlund 	for (i = 0; i <= index && id; i++) {
136aa2f8871SNiklas Söderlund 		/* last std value in the standards array is 0, so this
137aa2f8871SNiklas Söderlund 		   while always ends there since (id & 0) == 0. */
138aa2f8871SNiklas Söderlund 		while ((id & standards[j].std) != standards[j].std)
139aa2f8871SNiklas Söderlund 			j++;
140aa2f8871SNiklas Söderlund 		curr_id = standards[j].std;
141aa2f8871SNiklas Söderlund 		descr = standards[j].descr;
142aa2f8871SNiklas Söderlund 		j++;
143aa2f8871SNiklas Söderlund 		if (curr_id == 0)
144aa2f8871SNiklas Söderlund 			break;
145aa2f8871SNiklas Söderlund 		if (curr_id != V4L2_STD_PAL &&
146aa2f8871SNiklas Söderlund 				curr_id != V4L2_STD_SECAM &&
147aa2f8871SNiklas Söderlund 				curr_id != V4L2_STD_NTSC)
148aa2f8871SNiklas Söderlund 			id &= ~curr_id;
149aa2f8871SNiklas Söderlund 	}
150aa2f8871SNiklas Söderlund 	if (i <= index)
151aa2f8871SNiklas Söderlund 		return -EINVAL;
152aa2f8871SNiklas Söderlund 
153aa2f8871SNiklas Söderlund 	v4l2_video_std_construct(vs, curr_id, descr);
154aa2f8871SNiklas Söderlund 	return 0;
155aa2f8871SNiklas Söderlund }
156aa2f8871SNiklas Söderlund 
1575bc3cb74SMauro Carvalho Chehab /* ----------------------------------------------------------------- */
1585bc3cb74SMauro Carvalho Chehab /* some arrays for pretty-printing debug messages of enum types      */
1595bc3cb74SMauro Carvalho Chehab 
1605bc3cb74SMauro Carvalho Chehab const char *v4l2_field_names[] = {
1615bc3cb74SMauro Carvalho Chehab 	[V4L2_FIELD_ANY]        = "any",
1625bc3cb74SMauro Carvalho Chehab 	[V4L2_FIELD_NONE]       = "none",
1635bc3cb74SMauro Carvalho Chehab 	[V4L2_FIELD_TOP]        = "top",
1645bc3cb74SMauro Carvalho Chehab 	[V4L2_FIELD_BOTTOM]     = "bottom",
1655bc3cb74SMauro Carvalho Chehab 	[V4L2_FIELD_INTERLACED] = "interlaced",
1665bc3cb74SMauro Carvalho Chehab 	[V4L2_FIELD_SEQ_TB]     = "seq-tb",
1675bc3cb74SMauro Carvalho Chehab 	[V4L2_FIELD_SEQ_BT]     = "seq-bt",
1685bc3cb74SMauro Carvalho Chehab 	[V4L2_FIELD_ALTERNATE]  = "alternate",
1695bc3cb74SMauro Carvalho Chehab 	[V4L2_FIELD_INTERLACED_TB] = "interlaced-tb",
1705bc3cb74SMauro Carvalho Chehab 	[V4L2_FIELD_INTERLACED_BT] = "interlaced-bt",
1715bc3cb74SMauro Carvalho Chehab };
1725bc3cb74SMauro Carvalho Chehab EXPORT_SYMBOL(v4l2_field_names);
1735bc3cb74SMauro Carvalho Chehab 
1745bc3cb74SMauro Carvalho Chehab const char *v4l2_type_names[] = {
175839aa56dSHans Verkuil 	[0]				   = "0",
1765bc3cb74SMauro Carvalho Chehab 	[V4L2_BUF_TYPE_VIDEO_CAPTURE]      = "vid-cap",
1775bc3cb74SMauro Carvalho Chehab 	[V4L2_BUF_TYPE_VIDEO_OVERLAY]      = "vid-overlay",
1785bc3cb74SMauro Carvalho Chehab 	[V4L2_BUF_TYPE_VIDEO_OUTPUT]       = "vid-out",
1795bc3cb74SMauro Carvalho Chehab 	[V4L2_BUF_TYPE_VBI_CAPTURE]        = "vbi-cap",
1805bc3cb74SMauro Carvalho Chehab 	[V4L2_BUF_TYPE_VBI_OUTPUT]         = "vbi-out",
1815bc3cb74SMauro Carvalho Chehab 	[V4L2_BUF_TYPE_SLICED_VBI_CAPTURE] = "sliced-vbi-cap",
1825bc3cb74SMauro Carvalho Chehab 	[V4L2_BUF_TYPE_SLICED_VBI_OUTPUT]  = "sliced-vbi-out",
1835bc3cb74SMauro Carvalho Chehab 	[V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY] = "vid-out-overlay",
1845bc3cb74SMauro Carvalho Chehab 	[V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE] = "vid-cap-mplane",
1855bc3cb74SMauro Carvalho Chehab 	[V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE] = "vid-out-mplane",
1866f3073b8SAntti Palosaari 	[V4L2_BUF_TYPE_SDR_CAPTURE]        = "sdr-cap",
1879effc72fSAntti Palosaari 	[V4L2_BUF_TYPE_SDR_OUTPUT]         = "sdr-out",
188fb9ffa6aSLaurent Pinchart 	[V4L2_BUF_TYPE_META_CAPTURE]       = "meta-cap",
18972148d1aSSakari Ailus 	[V4L2_BUF_TYPE_META_OUTPUT]	   = "meta-out",
1905bc3cb74SMauro Carvalho Chehab };
1915bc3cb74SMauro Carvalho Chehab EXPORT_SYMBOL(v4l2_type_names);
1925bc3cb74SMauro Carvalho Chehab 
1935bc3cb74SMauro Carvalho Chehab static const char *v4l2_memory_names[] = {
1945bc3cb74SMauro Carvalho Chehab 	[V4L2_MEMORY_MMAP]    = "mmap",
1955bc3cb74SMauro Carvalho Chehab 	[V4L2_MEMORY_USERPTR] = "userptr",
1965bc3cb74SMauro Carvalho Chehab 	[V4L2_MEMORY_OVERLAY] = "overlay",
197051c7788SSumit Semwal 	[V4L2_MEMORY_DMABUF] = "dmabuf",
1985bc3cb74SMauro Carvalho Chehab };
1995bc3cb74SMauro Carvalho Chehab 
200d9246240SHans Verkuil #define prt_names(a, arr) (((unsigned)(a)) < ARRAY_SIZE(arr) ? arr[a] : "unknown")
2015bc3cb74SMauro Carvalho Chehab 
2025bc3cb74SMauro Carvalho Chehab /* ------------------------------------------------------------------ */
2035bc3cb74SMauro Carvalho Chehab /* debug help functions                                               */
2045bc3cb74SMauro Carvalho Chehab 
2055bc3cb74SMauro Carvalho Chehab static void v4l_print_querycap(const void *arg, bool write_only)
2065bc3cb74SMauro Carvalho Chehab {
2075bc3cb74SMauro Carvalho Chehab 	const struct v4l2_capability *p = arg;
2085bc3cb74SMauro Carvalho Chehab 
2098720427cSMauro Carvalho Chehab 	pr_cont("driver=%.*s, card=%.*s, bus=%.*s, version=0x%08x, capabilities=0x%08x, device_caps=0x%08x\n",
21027d5a87cSHans Verkuil 		(int)sizeof(p->driver), p->driver,
21127d5a87cSHans Verkuil 		(int)sizeof(p->card), p->card,
21227d5a87cSHans Verkuil 		(int)sizeof(p->bus_info), p->bus_info,
2135bc3cb74SMauro Carvalho Chehab 		p->version, p->capabilities, p->device_caps);
2145bc3cb74SMauro Carvalho Chehab }
2155bc3cb74SMauro Carvalho Chehab 
2165bc3cb74SMauro Carvalho Chehab static void v4l_print_enuminput(const void *arg, bool write_only)
2175bc3cb74SMauro Carvalho Chehab {
2185bc3cb74SMauro Carvalho Chehab 	const struct v4l2_input *p = arg;
2195bc3cb74SMauro Carvalho Chehab 
2208720427cSMauro 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",
22127d5a87cSHans Verkuil 		p->index, (int)sizeof(p->name), p->name, p->type, p->audioset,
22227d5a87cSHans Verkuil 		p->tuner, (unsigned long long)p->std, p->status,
22327d5a87cSHans Verkuil 		p->capabilities);
2245bc3cb74SMauro Carvalho Chehab }
2255bc3cb74SMauro Carvalho Chehab 
2265bc3cb74SMauro Carvalho Chehab static void v4l_print_enumoutput(const void *arg, bool write_only)
2275bc3cb74SMauro Carvalho Chehab {
2285bc3cb74SMauro Carvalho Chehab 	const struct v4l2_output *p = arg;
2295bc3cb74SMauro Carvalho Chehab 
2308720427cSMauro Carvalho Chehab 	pr_cont("index=%u, name=%.*s, type=%u, audioset=0x%x, modulator=%u, std=0x%08Lx, capabilities=0x%x\n",
23127d5a87cSHans Verkuil 		p->index, (int)sizeof(p->name), p->name, p->type, p->audioset,
23227d5a87cSHans Verkuil 		p->modulator, (unsigned long long)p->std, p->capabilities);
2335bc3cb74SMauro Carvalho Chehab }
2345bc3cb74SMauro Carvalho Chehab 
2355bc3cb74SMauro Carvalho Chehab static void v4l_print_audio(const void *arg, bool write_only)
2365bc3cb74SMauro Carvalho Chehab {
2375bc3cb74SMauro Carvalho Chehab 	const struct v4l2_audio *p = arg;
2385bc3cb74SMauro Carvalho Chehab 
2395bc3cb74SMauro Carvalho Chehab 	if (write_only)
2405bc3cb74SMauro Carvalho Chehab 		pr_cont("index=%u, mode=0x%x\n", p->index, p->mode);
2415bc3cb74SMauro Carvalho Chehab 	else
24227d5a87cSHans Verkuil 		pr_cont("index=%u, name=%.*s, capability=0x%x, mode=0x%x\n",
24327d5a87cSHans Verkuil 			p->index, (int)sizeof(p->name), p->name,
24427d5a87cSHans Verkuil 			p->capability, p->mode);
2455bc3cb74SMauro Carvalho Chehab }
2465bc3cb74SMauro Carvalho Chehab 
2475bc3cb74SMauro Carvalho Chehab static void v4l_print_audioout(const void *arg, bool write_only)
2485bc3cb74SMauro Carvalho Chehab {
2495bc3cb74SMauro Carvalho Chehab 	const struct v4l2_audioout *p = arg;
2505bc3cb74SMauro Carvalho Chehab 
2515bc3cb74SMauro Carvalho Chehab 	if (write_only)
2525bc3cb74SMauro Carvalho Chehab 		pr_cont("index=%u\n", p->index);
2535bc3cb74SMauro Carvalho Chehab 	else
25427d5a87cSHans Verkuil 		pr_cont("index=%u, name=%.*s, capability=0x%x, mode=0x%x\n",
25527d5a87cSHans Verkuil 			p->index, (int)sizeof(p->name), p->name,
25627d5a87cSHans Verkuil 			p->capability, p->mode);
2575bc3cb74SMauro Carvalho Chehab }
2585bc3cb74SMauro Carvalho Chehab 
2595bc3cb74SMauro Carvalho Chehab static void v4l_print_fmtdesc(const void *arg, bool write_only)
2605bc3cb74SMauro Carvalho Chehab {
2615bc3cb74SMauro Carvalho Chehab 	const struct v4l2_fmtdesc *p = arg;
2625bc3cb74SMauro Carvalho Chehab 
263e927e1e0SSakari Ailus 	pr_cont("index=%u, type=%s, flags=0x%x, pixelformat=%p4cc, mbus_code=0x%04x, description='%.*s'\n",
2645bc3cb74SMauro Carvalho Chehab 		p->index, prt_names(p->type, v4l2_type_names),
265e927e1e0SSakari Ailus 		p->flags, &p->pixelformat, p->mbus_code,
26627d5a87cSHans Verkuil 		(int)sizeof(p->description), p->description);
2675bc3cb74SMauro Carvalho Chehab }
2685bc3cb74SMauro Carvalho Chehab 
2695bc3cb74SMauro Carvalho Chehab static void v4l_print_format(const void *arg, bool write_only)
2705bc3cb74SMauro Carvalho Chehab {
2715bc3cb74SMauro Carvalho Chehab 	const struct v4l2_format *p = arg;
2725bc3cb74SMauro Carvalho Chehab 	const struct v4l2_pix_format *pix;
2735bc3cb74SMauro Carvalho Chehab 	const struct v4l2_pix_format_mplane *mp;
2745bc3cb74SMauro Carvalho Chehab 	const struct v4l2_vbi_format *vbi;
2755bc3cb74SMauro Carvalho Chehab 	const struct v4l2_sliced_vbi_format *sliced;
2765bc3cb74SMauro Carvalho Chehab 	const struct v4l2_window *win;
277fb9ffa6aSLaurent Pinchart 	const struct v4l2_meta_format *meta;
27824bb30c8SSakari Ailus 	u32 pixelformat;
2797fe9f01cSSakari Ailus 	u32 planes;
2805bc3cb74SMauro Carvalho Chehab 	unsigned i;
2815bc3cb74SMauro Carvalho Chehab 
2825bc3cb74SMauro Carvalho Chehab 	pr_cont("type=%s", prt_names(p->type, v4l2_type_names));
2835bc3cb74SMauro Carvalho Chehab 	switch (p->type) {
2845bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_CAPTURE:
2855bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_OUTPUT:
2865bc3cb74SMauro Carvalho Chehab 		pix = &p->fmt.pix;
287e927e1e0SSakari 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",
288e927e1e0SSakari Ailus 			pix->width, pix->height, &pix->pixelformat,
2895bc3cb74SMauro Carvalho Chehab 			prt_names(pix->field, v4l2_field_names),
2905bc3cb74SMauro Carvalho Chehab 			pix->bytesperline, pix->sizeimage,
291736d96b5SHans Verkuil 			pix->colorspace, pix->flags, pix->ycbcr_enc,
29274fdcb2eSHans Verkuil 			pix->quantization, pix->xfer_func);
2935bc3cb74SMauro Carvalho Chehab 		break;
2945bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
2955bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
2965bc3cb74SMauro Carvalho Chehab 		mp = &p->fmt.pix_mp;
29724bb30c8SSakari Ailus 		pixelformat = mp->pixelformat;
298e927e1e0SSakari 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",
29924bb30c8SSakari Ailus 			mp->width, mp->height, &pixelformat,
3005bc3cb74SMauro Carvalho Chehab 			prt_names(mp->field, v4l2_field_names),
301736d96b5SHans Verkuil 			mp->colorspace, mp->num_planes, mp->flags,
30274fdcb2eSHans Verkuil 			mp->ycbcr_enc, mp->quantization, mp->xfer_func);
3037fe9f01cSSakari Ailus 		planes = min_t(u32, mp->num_planes, VIDEO_MAX_PLANES);
3047fe9f01cSSakari Ailus 		for (i = 0; i < planes; i++)
3055bc3cb74SMauro Carvalho Chehab 			printk(KERN_DEBUG "plane %u: bytesperline=%u sizeimage=%u\n", i,
3065bc3cb74SMauro Carvalho Chehab 					mp->plane_fmt[i].bytesperline,
3075bc3cb74SMauro Carvalho Chehab 					mp->plane_fmt[i].sizeimage);
3085bc3cb74SMauro Carvalho Chehab 		break;
3095bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_OVERLAY:
3105bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
3115bc3cb74SMauro Carvalho Chehab 		win = &p->fmt.win;
312560dde24SHans Verkuil 		/* Note: we can't print the clip list here since the clips
313560dde24SHans Verkuil 		 * pointer is a userspace pointer, not a kernelspace
314560dde24SHans Verkuil 		 * pointer. */
315560dde24SHans 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",
316560dde24SHans Verkuil 			win->w.width, win->w.height, win->w.left, win->w.top,
3175bc3cb74SMauro Carvalho Chehab 			prt_names(win->field, v4l2_field_names),
318560dde24SHans Verkuil 			win->chromakey, win->clipcount, win->clips,
319560dde24SHans Verkuil 			win->bitmap, win->global_alpha);
3205bc3cb74SMauro Carvalho Chehab 		break;
3215bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VBI_CAPTURE:
3225bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VBI_OUTPUT:
3235bc3cb74SMauro Carvalho Chehab 		vbi = &p->fmt.vbi;
324e927e1e0SSakari Ailus 		pr_cont(", sampling_rate=%u, offset=%u, samples_per_line=%u, sample_format=%p4cc, start=%u,%u, count=%u,%u\n",
3255bc3cb74SMauro Carvalho Chehab 			vbi->sampling_rate, vbi->offset,
326e927e1e0SSakari Ailus 			vbi->samples_per_line, &vbi->sample_format,
3275bc3cb74SMauro Carvalho Chehab 			vbi->start[0], vbi->start[1],
3285bc3cb74SMauro Carvalho Chehab 			vbi->count[0], vbi->count[1]);
3295bc3cb74SMauro Carvalho Chehab 		break;
3305bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
3315bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
3325bc3cb74SMauro Carvalho Chehab 		sliced = &p->fmt.sliced;
3335bc3cb74SMauro Carvalho Chehab 		pr_cont(", service_set=0x%08x, io_size=%d\n",
3345bc3cb74SMauro Carvalho Chehab 				sliced->service_set, sliced->io_size);
3355bc3cb74SMauro Carvalho Chehab 		for (i = 0; i < 24; i++)
3365bc3cb74SMauro Carvalho Chehab 			printk(KERN_DEBUG "line[%02u]=0x%04x, 0x%04x\n", i,
3375bc3cb74SMauro Carvalho Chehab 				sliced->service_lines[0][i],
3385bc3cb74SMauro Carvalho Chehab 				sliced->service_lines[1][i]);
3395bc3cb74SMauro Carvalho Chehab 		break;
340582c52cbSAntti Palosaari 	case V4L2_BUF_TYPE_SDR_CAPTURE:
3419effc72fSAntti Palosaari 	case V4L2_BUF_TYPE_SDR_OUTPUT:
34224bb30c8SSakari Ailus 		pixelformat = p->fmt.sdr.pixelformat;
34324bb30c8SSakari Ailus 		pr_cont(", pixelformat=%p4cc\n", &pixelformat);
344582c52cbSAntti Palosaari 		break;
345fb9ffa6aSLaurent Pinchart 	case V4L2_BUF_TYPE_META_CAPTURE:
34672148d1aSSakari Ailus 	case V4L2_BUF_TYPE_META_OUTPUT:
347fb9ffa6aSLaurent Pinchart 		meta = &p->fmt.meta;
34824bb30c8SSakari Ailus 		pixelformat = meta->dataformat;
349e927e1e0SSakari Ailus 		pr_cont(", dataformat=%p4cc, buffersize=%u\n",
35024bb30c8SSakari Ailus 			&pixelformat, meta->buffersize);
351fb9ffa6aSLaurent Pinchart 		break;
3525bc3cb74SMauro Carvalho Chehab 	}
3535bc3cb74SMauro Carvalho Chehab }
3545bc3cb74SMauro Carvalho Chehab 
3555bc3cb74SMauro Carvalho Chehab static void v4l_print_framebuffer(const void *arg, bool write_only)
3565bc3cb74SMauro Carvalho Chehab {
3575bc3cb74SMauro Carvalho Chehab 	const struct v4l2_framebuffer *p = arg;
3585bc3cb74SMauro Carvalho Chehab 
359e927e1e0SSakari 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",
360e927e1e0SSakari Ailus 		p->capability, p->flags, p->base, p->fmt.width, p->fmt.height,
361e927e1e0SSakari Ailus 		&p->fmt.pixelformat, p->fmt.bytesperline, p->fmt.sizeimage,
3625bc3cb74SMauro Carvalho Chehab 		p->fmt.colorspace);
3635bc3cb74SMauro Carvalho Chehab }
3645bc3cb74SMauro Carvalho Chehab 
3655bc3cb74SMauro Carvalho Chehab static void v4l_print_buftype(const void *arg, bool write_only)
3665bc3cb74SMauro Carvalho Chehab {
3675bc3cb74SMauro Carvalho Chehab 	pr_cont("type=%s\n", prt_names(*(u32 *)arg, v4l2_type_names));
3685bc3cb74SMauro Carvalho Chehab }
3695bc3cb74SMauro Carvalho Chehab 
3705bc3cb74SMauro Carvalho Chehab static void v4l_print_modulator(const void *arg, bool write_only)
3715bc3cb74SMauro Carvalho Chehab {
3725bc3cb74SMauro Carvalho Chehab 	const struct v4l2_modulator *p = arg;
3735bc3cb74SMauro Carvalho Chehab 
3745bc3cb74SMauro Carvalho Chehab 	if (write_only)
375560dde24SHans Verkuil 		pr_cont("index=%u, txsubchans=0x%x\n", p->index, p->txsubchans);
3765bc3cb74SMauro Carvalho Chehab 	else
3778720427cSMauro Carvalho Chehab 		pr_cont("index=%u, name=%.*s, capability=0x%x, rangelow=%u, rangehigh=%u, txsubchans=0x%x\n",
37827d5a87cSHans Verkuil 			p->index, (int)sizeof(p->name), p->name, p->capability,
3795bc3cb74SMauro Carvalho Chehab 			p->rangelow, p->rangehigh, p->txsubchans);
3805bc3cb74SMauro Carvalho Chehab }
3815bc3cb74SMauro Carvalho Chehab 
3825bc3cb74SMauro Carvalho Chehab static void v4l_print_tuner(const void *arg, bool write_only)
3835bc3cb74SMauro Carvalho Chehab {
3845bc3cb74SMauro Carvalho Chehab 	const struct v4l2_tuner *p = arg;
3855bc3cb74SMauro Carvalho Chehab 
3865bc3cb74SMauro Carvalho Chehab 	if (write_only)
3875bc3cb74SMauro Carvalho Chehab 		pr_cont("index=%u, audmode=%u\n", p->index, p->audmode);
3885bc3cb74SMauro Carvalho Chehab 	else
3898720427cSMauro 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",
39027d5a87cSHans Verkuil 			p->index, (int)sizeof(p->name), p->name, p->type,
3915bc3cb74SMauro Carvalho Chehab 			p->capability, p->rangelow,
3925bc3cb74SMauro Carvalho Chehab 			p->rangehigh, p->signal, p->afc,
3935bc3cb74SMauro Carvalho Chehab 			p->rxsubchans, p->audmode);
3945bc3cb74SMauro Carvalho Chehab }
3955bc3cb74SMauro Carvalho Chehab 
3965bc3cb74SMauro Carvalho Chehab static void v4l_print_frequency(const void *arg, bool write_only)
3975bc3cb74SMauro Carvalho Chehab {
3985bc3cb74SMauro Carvalho Chehab 	const struct v4l2_frequency *p = arg;
3995bc3cb74SMauro Carvalho Chehab 
4005bc3cb74SMauro Carvalho Chehab 	pr_cont("tuner=%u, type=%u, frequency=%u\n",
4015bc3cb74SMauro Carvalho Chehab 				p->tuner, p->type, p->frequency);
4025bc3cb74SMauro Carvalho Chehab }
4035bc3cb74SMauro Carvalho Chehab 
4045bc3cb74SMauro Carvalho Chehab static void v4l_print_standard(const void *arg, bool write_only)
4055bc3cb74SMauro Carvalho Chehab {
4065bc3cb74SMauro Carvalho Chehab 	const struct v4l2_standard *p = arg;
4075bc3cb74SMauro Carvalho Chehab 
4088720427cSMauro Carvalho Chehab 	pr_cont("index=%u, id=0x%Lx, name=%.*s, fps=%u/%u, framelines=%u\n",
4098720427cSMauro Carvalho Chehab 		p->index,
41027d5a87cSHans Verkuil 		(unsigned long long)p->id, (int)sizeof(p->name), p->name,
4115bc3cb74SMauro Carvalho Chehab 		p->frameperiod.numerator,
4125bc3cb74SMauro Carvalho Chehab 		p->frameperiod.denominator,
4135bc3cb74SMauro Carvalho Chehab 		p->framelines);
4145bc3cb74SMauro Carvalho Chehab }
4155bc3cb74SMauro Carvalho Chehab 
4165bc3cb74SMauro Carvalho Chehab static void v4l_print_std(const void *arg, bool write_only)
4175bc3cb74SMauro Carvalho Chehab {
4185bc3cb74SMauro Carvalho Chehab 	pr_cont("std=0x%08Lx\n", *(const long long unsigned *)arg);
4195bc3cb74SMauro Carvalho Chehab }
4205bc3cb74SMauro Carvalho Chehab 
4215bc3cb74SMauro Carvalho Chehab static void v4l_print_hw_freq_seek(const void *arg, bool write_only)
4225bc3cb74SMauro Carvalho Chehab {
4235bc3cb74SMauro Carvalho Chehab 	const struct v4l2_hw_freq_seek *p = arg;
4245bc3cb74SMauro Carvalho Chehab 
4258720427cSMauro Carvalho Chehab 	pr_cont("tuner=%u, type=%u, seek_upward=%u, wrap_around=%u, spacing=%u, rangelow=%u, rangehigh=%u\n",
42679e8c7beSMauro Carvalho Chehab 		p->tuner, p->type, p->seek_upward, p->wrap_around, p->spacing,
42779e8c7beSMauro Carvalho Chehab 		p->rangelow, p->rangehigh);
4285bc3cb74SMauro Carvalho Chehab }
4295bc3cb74SMauro Carvalho Chehab 
4305bc3cb74SMauro Carvalho Chehab static void v4l_print_requestbuffers(const void *arg, bool write_only)
4315bc3cb74SMauro Carvalho Chehab {
4325bc3cb74SMauro Carvalho Chehab 	const struct v4l2_requestbuffers *p = arg;
4335bc3cb74SMauro Carvalho Chehab 
4345bc3cb74SMauro Carvalho Chehab 	pr_cont("count=%d, type=%s, memory=%s\n",
4355bc3cb74SMauro Carvalho Chehab 		p->count,
4365bc3cb74SMauro Carvalho Chehab 		prt_names(p->type, v4l2_type_names),
4375bc3cb74SMauro Carvalho Chehab 		prt_names(p->memory, v4l2_memory_names));
4385bc3cb74SMauro Carvalho Chehab }
4395bc3cb74SMauro Carvalho Chehab 
4405bc3cb74SMauro Carvalho Chehab static void v4l_print_buffer(const void *arg, bool write_only)
4415bc3cb74SMauro Carvalho Chehab {
4425bc3cb74SMauro Carvalho Chehab 	const struct v4l2_buffer *p = arg;
4435bc3cb74SMauro Carvalho Chehab 	const struct v4l2_timecode *tc = &p->timecode;
4445bc3cb74SMauro Carvalho Chehab 	const struct v4l2_plane *plane;
4455bc3cb74SMauro Carvalho Chehab 	int i;
4465bc3cb74SMauro Carvalho Chehab 
44748e15418SHans Verkuil 	pr_cont("%02d:%02d:%02d.%06ld index=%d, type=%s, request_fd=%d, flags=0x%08x, field=%s, sequence=%d, memory=%s",
448577c89b0SArnd Bergmann 			(int)p->timestamp.tv_sec / 3600,
449577c89b0SArnd Bergmann 			((int)p->timestamp.tv_sec / 60) % 60,
450577c89b0SArnd Bergmann 			((int)p->timestamp.tv_sec % 60),
4515bc3cb74SMauro Carvalho Chehab 			(long)p->timestamp.tv_usec,
4525bc3cb74SMauro Carvalho Chehab 			p->index,
45362fed26fSHans Verkuil 			prt_names(p->type, v4l2_type_names), p->request_fd,
4545bc3cb74SMauro Carvalho Chehab 			p->flags, prt_names(p->field, v4l2_field_names),
4555bc3cb74SMauro Carvalho Chehab 			p->sequence, prt_names(p->memory, v4l2_memory_names));
4565bc3cb74SMauro Carvalho Chehab 
4575bc3cb74SMauro Carvalho Chehab 	if (V4L2_TYPE_IS_MULTIPLANAR(p->type) && p->m.planes) {
4585bc3cb74SMauro Carvalho Chehab 		pr_cont("\n");
4595bc3cb74SMauro Carvalho Chehab 		for (i = 0; i < p->length; ++i) {
4605bc3cb74SMauro Carvalho Chehab 			plane = &p->m.planes[i];
4615bc3cb74SMauro Carvalho Chehab 			printk(KERN_DEBUG
4628720427cSMauro Carvalho Chehab 				"plane %d: bytesused=%d, data_offset=0x%08x, offset/userptr=0x%lx, length=%d\n",
4635bc3cb74SMauro Carvalho Chehab 				i, plane->bytesused, plane->data_offset,
4645bc3cb74SMauro Carvalho Chehab 				plane->m.userptr, plane->length);
4655bc3cb74SMauro Carvalho Chehab 		}
4665bc3cb74SMauro Carvalho Chehab 	} else {
467560dde24SHans Verkuil 		pr_cont(", bytesused=%d, offset/userptr=0x%lx, length=%d\n",
4685bc3cb74SMauro Carvalho Chehab 			p->bytesused, p->m.userptr, p->length);
4695bc3cb74SMauro Carvalho Chehab 	}
4705bc3cb74SMauro Carvalho Chehab 
4718720427cSMauro Carvalho Chehab 	printk(KERN_DEBUG "timecode=%02d:%02d:%02d type=%d, flags=0x%08x, frames=%d, userbits=0x%08x\n",
4725bc3cb74SMauro Carvalho Chehab 			tc->hours, tc->minutes, tc->seconds,
4735bc3cb74SMauro Carvalho Chehab 			tc->type, tc->flags, tc->frames, *(__u32 *)tc->userbits);
4745bc3cb74SMauro Carvalho Chehab }
4755bc3cb74SMauro Carvalho Chehab 
476b799d09aSTomasz Stanislawski static void v4l_print_exportbuffer(const void *arg, bool write_only)
477b799d09aSTomasz Stanislawski {
478b799d09aSTomasz Stanislawski 	const struct v4l2_exportbuffer *p = arg;
479b799d09aSTomasz Stanislawski 
480b799d09aSTomasz Stanislawski 	pr_cont("fd=%d, type=%s, index=%u, plane=%u, flags=0x%08x\n",
481b799d09aSTomasz Stanislawski 		p->fd, prt_names(p->type, v4l2_type_names),
482b799d09aSTomasz Stanislawski 		p->index, p->plane, p->flags);
483b799d09aSTomasz Stanislawski }
484b799d09aSTomasz Stanislawski 
4855bc3cb74SMauro Carvalho Chehab static void v4l_print_create_buffers(const void *arg, bool write_only)
4865bc3cb74SMauro Carvalho Chehab {
4875bc3cb74SMauro Carvalho Chehab 	const struct v4l2_create_buffers *p = arg;
4885bc3cb74SMauro Carvalho Chehab 
489319c4bd4SHelen Koike 	pr_cont("index=%d, count=%d, memory=%s, capabilities=0x%08x, ",
490319c4bd4SHelen Koike 		p->index, p->count, prt_names(p->memory, v4l2_memory_names),
491319c4bd4SHelen Koike 		p->capabilities);
4925bc3cb74SMauro Carvalho Chehab 	v4l_print_format(&p->format, write_only);
4935bc3cb74SMauro Carvalho Chehab }
4945bc3cb74SMauro Carvalho Chehab 
4955bc3cb74SMauro Carvalho Chehab static void v4l_print_streamparm(const void *arg, bool write_only)
4965bc3cb74SMauro Carvalho Chehab {
4975bc3cb74SMauro Carvalho Chehab 	const struct v4l2_streamparm *p = arg;
4985bc3cb74SMauro Carvalho Chehab 
4995bc3cb74SMauro Carvalho Chehab 	pr_cont("type=%s", prt_names(p->type, v4l2_type_names));
5005bc3cb74SMauro Carvalho Chehab 
5015bc3cb74SMauro Carvalho Chehab 	if (p->type == V4L2_BUF_TYPE_VIDEO_CAPTURE ||
5025bc3cb74SMauro Carvalho Chehab 	    p->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
5035bc3cb74SMauro Carvalho Chehab 		const struct v4l2_captureparm *c = &p->parm.capture;
5045bc3cb74SMauro Carvalho Chehab 
5058720427cSMauro Carvalho Chehab 		pr_cont(", capability=0x%x, capturemode=0x%x, timeperframe=%d/%d, extendedmode=%d, readbuffers=%d\n",
5065bc3cb74SMauro Carvalho Chehab 			c->capability, c->capturemode,
5075bc3cb74SMauro Carvalho Chehab 			c->timeperframe.numerator, c->timeperframe.denominator,
5085bc3cb74SMauro Carvalho Chehab 			c->extendedmode, c->readbuffers);
5095bc3cb74SMauro Carvalho Chehab 	} else if (p->type == V4L2_BUF_TYPE_VIDEO_OUTPUT ||
5105bc3cb74SMauro Carvalho Chehab 		   p->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
5115bc3cb74SMauro Carvalho Chehab 		const struct v4l2_outputparm *c = &p->parm.output;
5125bc3cb74SMauro Carvalho Chehab 
5138720427cSMauro Carvalho Chehab 		pr_cont(", capability=0x%x, outputmode=0x%x, timeperframe=%d/%d, extendedmode=%d, writebuffers=%d\n",
5145bc3cb74SMauro Carvalho Chehab 			c->capability, c->outputmode,
5155bc3cb74SMauro Carvalho Chehab 			c->timeperframe.numerator, c->timeperframe.denominator,
5165bc3cb74SMauro Carvalho Chehab 			c->extendedmode, c->writebuffers);
517560dde24SHans Verkuil 	} else {
518560dde24SHans Verkuil 		pr_cont("\n");
5195bc3cb74SMauro Carvalho Chehab 	}
5205bc3cb74SMauro Carvalho Chehab }
5215bc3cb74SMauro Carvalho Chehab 
5225bc3cb74SMauro Carvalho Chehab static void v4l_print_queryctrl(const void *arg, bool write_only)
5235bc3cb74SMauro Carvalho Chehab {
5245bc3cb74SMauro Carvalho Chehab 	const struct v4l2_queryctrl *p = arg;
5255bc3cb74SMauro Carvalho Chehab 
5268720427cSMauro Carvalho Chehab 	pr_cont("id=0x%x, type=%d, name=%.*s, min/max=%d/%d, step=%d, default=%d, flags=0x%08x\n",
52727d5a87cSHans Verkuil 			p->id, p->type, (int)sizeof(p->name), p->name,
5285bc3cb74SMauro Carvalho Chehab 			p->minimum, p->maximum,
5295bc3cb74SMauro Carvalho Chehab 			p->step, p->default_value, p->flags);
5305bc3cb74SMauro Carvalho Chehab }
5315bc3cb74SMauro Carvalho Chehab 
532e6bee368SHans Verkuil static void v4l_print_query_ext_ctrl(const void *arg, bool write_only)
533e6bee368SHans Verkuil {
534e6bee368SHans Verkuil 	const struct v4l2_query_ext_ctrl *p = arg;
535e6bee368SHans Verkuil 
5368720427cSMauro 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",
537e6bee368SHans Verkuil 			p->id, p->type, (int)sizeof(p->name), p->name,
538e6bee368SHans Verkuil 			p->minimum, p->maximum,
539e6bee368SHans Verkuil 			p->step, p->default_value, p->flags,
540e6bee368SHans Verkuil 			p->elem_size, p->elems, p->nr_of_dims,
5410176077aSHans Verkuil 			p->dims[0], p->dims[1], p->dims[2], p->dims[3]);
542e6bee368SHans Verkuil }
543e6bee368SHans Verkuil 
5445bc3cb74SMauro Carvalho Chehab static void v4l_print_querymenu(const void *arg, bool write_only)
5455bc3cb74SMauro Carvalho Chehab {
5465bc3cb74SMauro Carvalho Chehab 	const struct v4l2_querymenu *p = arg;
5475bc3cb74SMauro Carvalho Chehab 
5485bc3cb74SMauro Carvalho Chehab 	pr_cont("id=0x%x, index=%d\n", p->id, p->index);
5495bc3cb74SMauro Carvalho Chehab }
5505bc3cb74SMauro Carvalho Chehab 
5515bc3cb74SMauro Carvalho Chehab static void v4l_print_control(const void *arg, bool write_only)
5525bc3cb74SMauro Carvalho Chehab {
5535bc3cb74SMauro Carvalho Chehab 	const struct v4l2_control *p = arg;
554a69a7a33SEzequiel Garcia 	const char *name = v4l2_ctrl_get_name(p->id);
5555bc3cb74SMauro Carvalho Chehab 
556a69a7a33SEzequiel Garcia 	if (name)
557a69a7a33SEzequiel Garcia 		pr_cont("name=%s, ", name);
5585bc3cb74SMauro Carvalho Chehab 	pr_cont("id=0x%x, value=%d\n", p->id, p->value);
5595bc3cb74SMauro Carvalho Chehab }
5605bc3cb74SMauro Carvalho Chehab 
5615bc3cb74SMauro Carvalho Chehab static void v4l_print_ext_controls(const void *arg, bool write_only)
5625bc3cb74SMauro Carvalho Chehab {
5635bc3cb74SMauro Carvalho Chehab 	const struct v4l2_ext_controls *p = arg;
5645bc3cb74SMauro Carvalho Chehab 	int i;
5655bc3cb74SMauro Carvalho Chehab 
566f23317adSAlexandre Courbot 	pr_cont("which=0x%x, count=%d, error_idx=%d, request_fd=%d",
567f23317adSAlexandre Courbot 			p->which, p->count, p->error_idx, p->request_fd);
5685bc3cb74SMauro Carvalho Chehab 	for (i = 0; i < p->count; i++) {
569a69a7a33SEzequiel Garcia 		unsigned int id = p->controls[i].id;
570a69a7a33SEzequiel Garcia 		const char *name = v4l2_ctrl_get_name(id);
571a69a7a33SEzequiel Garcia 
572a69a7a33SEzequiel Garcia 		if (name)
573a69a7a33SEzequiel Garcia 			pr_cont(", name=%s", name);
574017ab36aSHans Verkuil 		if (!p->controls[i].size)
575a69a7a33SEzequiel Garcia 			pr_cont(", id/val=0x%x/0x%x", id, p->controls[i].value);
5765bc3cb74SMauro Carvalho Chehab 		else
577a69a7a33SEzequiel Garcia 			pr_cont(", id/size=0x%x/%u", id, p->controls[i].size);
5785bc3cb74SMauro Carvalho Chehab 	}
5795bc3cb74SMauro Carvalho Chehab 	pr_cont("\n");
5805bc3cb74SMauro Carvalho Chehab }
5815bc3cb74SMauro Carvalho Chehab 
5825bc3cb74SMauro Carvalho Chehab static void v4l_print_cropcap(const void *arg, bool write_only)
5835bc3cb74SMauro Carvalho Chehab {
5845bc3cb74SMauro Carvalho Chehab 	const struct v4l2_cropcap *p = arg;
5855bc3cb74SMauro Carvalho Chehab 
5868720427cSMauro 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",
5875bc3cb74SMauro Carvalho Chehab 		prt_names(p->type, v4l2_type_names),
5885bc3cb74SMauro Carvalho Chehab 		p->bounds.width, p->bounds.height,
5895bc3cb74SMauro Carvalho Chehab 		p->bounds.left, p->bounds.top,
5905bc3cb74SMauro Carvalho Chehab 		p->defrect.width, p->defrect.height,
5915bc3cb74SMauro Carvalho Chehab 		p->defrect.left, p->defrect.top,
5925bc3cb74SMauro Carvalho Chehab 		p->pixelaspect.numerator, p->pixelaspect.denominator);
5935bc3cb74SMauro Carvalho Chehab }
5945bc3cb74SMauro Carvalho Chehab 
5955bc3cb74SMauro Carvalho Chehab static void v4l_print_crop(const void *arg, bool write_only)
5965bc3cb74SMauro Carvalho Chehab {
5975bc3cb74SMauro Carvalho Chehab 	const struct v4l2_crop *p = arg;
5985bc3cb74SMauro Carvalho Chehab 
5995bc3cb74SMauro Carvalho Chehab 	pr_cont("type=%s, wxh=%dx%d, x,y=%d,%d\n",
6005bc3cb74SMauro Carvalho Chehab 		prt_names(p->type, v4l2_type_names),
6015bc3cb74SMauro Carvalho Chehab 		p->c.width, p->c.height,
6025bc3cb74SMauro Carvalho Chehab 		p->c.left, p->c.top);
6035bc3cb74SMauro Carvalho Chehab }
6045bc3cb74SMauro Carvalho Chehab 
6055bc3cb74SMauro Carvalho Chehab static void v4l_print_selection(const void *arg, bool write_only)
6065bc3cb74SMauro Carvalho Chehab {
6075bc3cb74SMauro Carvalho Chehab 	const struct v4l2_selection *p = arg;
6085bc3cb74SMauro Carvalho Chehab 
6095bc3cb74SMauro Carvalho Chehab 	pr_cont("type=%s, target=%d, flags=0x%x, wxh=%dx%d, x,y=%d,%d\n",
6105bc3cb74SMauro Carvalho Chehab 		prt_names(p->type, v4l2_type_names),
6115bc3cb74SMauro Carvalho Chehab 		p->target, p->flags,
6125bc3cb74SMauro Carvalho Chehab 		p->r.width, p->r.height, p->r.left, p->r.top);
6135bc3cb74SMauro Carvalho Chehab }
6145bc3cb74SMauro Carvalho Chehab 
6155bc3cb74SMauro Carvalho Chehab static void v4l_print_jpegcompression(const void *arg, bool write_only)
6165bc3cb74SMauro Carvalho Chehab {
6175bc3cb74SMauro Carvalho Chehab 	const struct v4l2_jpegcompression *p = arg;
6185bc3cb74SMauro Carvalho Chehab 
6198720427cSMauro Carvalho Chehab 	pr_cont("quality=%d, APPn=%d, APP_len=%d, COM_len=%d, jpeg_markers=0x%x\n",
6205bc3cb74SMauro Carvalho Chehab 		p->quality, p->APPn, p->APP_len,
6215bc3cb74SMauro Carvalho Chehab 		p->COM_len, p->jpeg_markers);
6225bc3cb74SMauro Carvalho Chehab }
6235bc3cb74SMauro Carvalho Chehab 
6245bc3cb74SMauro Carvalho Chehab static void v4l_print_enc_idx(const void *arg, bool write_only)
6255bc3cb74SMauro Carvalho Chehab {
6265bc3cb74SMauro Carvalho Chehab 	const struct v4l2_enc_idx *p = arg;
6275bc3cb74SMauro Carvalho Chehab 
6285bc3cb74SMauro Carvalho Chehab 	pr_cont("entries=%d, entries_cap=%d\n",
6295bc3cb74SMauro Carvalho Chehab 			p->entries, p->entries_cap);
6305bc3cb74SMauro Carvalho Chehab }
6315bc3cb74SMauro Carvalho Chehab 
6325bc3cb74SMauro Carvalho Chehab static void v4l_print_encoder_cmd(const void *arg, bool write_only)
6335bc3cb74SMauro Carvalho Chehab {
6345bc3cb74SMauro Carvalho Chehab 	const struct v4l2_encoder_cmd *p = arg;
6355bc3cb74SMauro Carvalho Chehab 
6365bc3cb74SMauro Carvalho Chehab 	pr_cont("cmd=%d, flags=0x%x\n",
6375bc3cb74SMauro Carvalho Chehab 			p->cmd, p->flags);
6385bc3cb74SMauro Carvalho Chehab }
6395bc3cb74SMauro Carvalho Chehab 
6405bc3cb74SMauro Carvalho Chehab static void v4l_print_decoder_cmd(const void *arg, bool write_only)
6415bc3cb74SMauro Carvalho Chehab {
6425bc3cb74SMauro Carvalho Chehab 	const struct v4l2_decoder_cmd *p = arg;
6435bc3cb74SMauro Carvalho Chehab 
6445bc3cb74SMauro Carvalho Chehab 	pr_cont("cmd=%d, flags=0x%x\n", p->cmd, p->flags);
6455bc3cb74SMauro Carvalho Chehab 
6465bc3cb74SMauro Carvalho Chehab 	if (p->cmd == V4L2_DEC_CMD_START)
6475bc3cb74SMauro Carvalho Chehab 		pr_info("speed=%d, format=%u\n",
6485bc3cb74SMauro Carvalho Chehab 				p->start.speed, p->start.format);
6495bc3cb74SMauro Carvalho Chehab 	else if (p->cmd == V4L2_DEC_CMD_STOP)
6505bc3cb74SMauro Carvalho Chehab 		pr_info("pts=%llu\n", p->stop.pts);
6515bc3cb74SMauro Carvalho Chehab }
6525bc3cb74SMauro Carvalho Chehab 
65396b03d2aSHans Verkuil static void v4l_print_dbg_chip_info(const void *arg, bool write_only)
65479b0c640SHans Verkuil {
65596b03d2aSHans Verkuil 	const struct v4l2_dbg_chip_info *p = arg;
65679b0c640SHans Verkuil 
65779b0c640SHans Verkuil 	pr_cont("type=%u, ", p->match.type);
6583eef2510SHans Verkuil 	if (p->match.type == V4L2_CHIP_MATCH_I2C_DRIVER)
65979b0c640SHans Verkuil 		pr_cont("name=%.*s, ",
66079b0c640SHans Verkuil 				(int)sizeof(p->match.name), p->match.name);
66179b0c640SHans Verkuil 	else
66279b0c640SHans Verkuil 		pr_cont("addr=%u, ", p->match.addr);
66379b0c640SHans Verkuil 	pr_cont("name=%.*s\n", (int)sizeof(p->name), p->name);
66479b0c640SHans Verkuil }
66579b0c640SHans Verkuil 
6665bc3cb74SMauro Carvalho Chehab static void v4l_print_dbg_register(const void *arg, bool write_only)
6675bc3cb74SMauro Carvalho Chehab {
6685bc3cb74SMauro Carvalho Chehab 	const struct v4l2_dbg_register *p = arg;
6695bc3cb74SMauro Carvalho Chehab 
6705bc3cb74SMauro Carvalho Chehab 	pr_cont("type=%u, ", p->match.type);
6713eef2510SHans Verkuil 	if (p->match.type == V4L2_CHIP_MATCH_I2C_DRIVER)
67227d5a87cSHans Verkuil 		pr_cont("name=%.*s, ",
67327d5a87cSHans Verkuil 				(int)sizeof(p->match.name), p->match.name);
6745bc3cb74SMauro Carvalho Chehab 	else
6755bc3cb74SMauro Carvalho Chehab 		pr_cont("addr=%u, ", p->match.addr);
6765bc3cb74SMauro Carvalho Chehab 	pr_cont("reg=0x%llx, val=0x%llx\n",
6775bc3cb74SMauro Carvalho Chehab 			p->reg, p->val);
6785bc3cb74SMauro Carvalho Chehab }
6795bc3cb74SMauro Carvalho Chehab 
6805bc3cb74SMauro Carvalho Chehab static void v4l_print_dv_timings(const void *arg, bool write_only)
6815bc3cb74SMauro Carvalho Chehab {
6825bc3cb74SMauro Carvalho Chehab 	const struct v4l2_dv_timings *p = arg;
6835bc3cb74SMauro Carvalho Chehab 
6845bc3cb74SMauro Carvalho Chehab 	switch (p->type) {
6855bc3cb74SMauro Carvalho Chehab 	case V4L2_DV_BT_656_1120:
6868720427cSMauro 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",
6875bc3cb74SMauro Carvalho Chehab 				p->bt.interlaced, p->bt.pixelclock,
6885bc3cb74SMauro Carvalho Chehab 				p->bt.width, p->bt.height,
6895bc3cb74SMauro Carvalho Chehab 				p->bt.polarities, p->bt.hfrontporch,
6905bc3cb74SMauro Carvalho Chehab 				p->bt.hsync, p->bt.hbackporch,
6915bc3cb74SMauro Carvalho Chehab 				p->bt.vfrontporch, p->bt.vsync,
6925bc3cb74SMauro Carvalho Chehab 				p->bt.vbackporch, p->bt.il_vfrontporch,
6935bc3cb74SMauro Carvalho Chehab 				p->bt.il_vsync, p->bt.il_vbackporch,
6945bc3cb74SMauro Carvalho Chehab 				p->bt.standards, p->bt.flags);
6955bc3cb74SMauro Carvalho Chehab 		break;
6965bc3cb74SMauro Carvalho Chehab 	default:
6975bc3cb74SMauro Carvalho Chehab 		pr_cont("type=%d\n", p->type);
6985bc3cb74SMauro Carvalho Chehab 		break;
6995bc3cb74SMauro Carvalho Chehab 	}
7005bc3cb74SMauro Carvalho Chehab }
7015bc3cb74SMauro Carvalho Chehab 
7025bc3cb74SMauro Carvalho Chehab static void v4l_print_enum_dv_timings(const void *arg, bool write_only)
7035bc3cb74SMauro Carvalho Chehab {
7045bc3cb74SMauro Carvalho Chehab 	const struct v4l2_enum_dv_timings *p = arg;
7055bc3cb74SMauro Carvalho Chehab 
7065bc3cb74SMauro Carvalho Chehab 	pr_cont("index=%u, ", p->index);
7075bc3cb74SMauro Carvalho Chehab 	v4l_print_dv_timings(&p->timings, write_only);
7085bc3cb74SMauro Carvalho Chehab }
7095bc3cb74SMauro Carvalho Chehab 
7105bc3cb74SMauro Carvalho Chehab static void v4l_print_dv_timings_cap(const void *arg, bool write_only)
7115bc3cb74SMauro Carvalho Chehab {
7125bc3cb74SMauro Carvalho Chehab 	const struct v4l2_dv_timings_cap *p = arg;
7135bc3cb74SMauro Carvalho Chehab 
7145bc3cb74SMauro Carvalho Chehab 	switch (p->type) {
7155bc3cb74SMauro Carvalho Chehab 	case V4L2_DV_BT_656_1120:
7168720427cSMauro Carvalho Chehab 		pr_cont("type=bt-656/1120, width=%u-%u, height=%u-%u, pixelclock=%llu-%llu, standards=0x%x, capabilities=0x%x\n",
7175bc3cb74SMauro Carvalho Chehab 			p->bt.min_width, p->bt.max_width,
7185bc3cb74SMauro Carvalho Chehab 			p->bt.min_height, p->bt.max_height,
7195bc3cb74SMauro Carvalho Chehab 			p->bt.min_pixelclock, p->bt.max_pixelclock,
7205bc3cb74SMauro Carvalho Chehab 			p->bt.standards, p->bt.capabilities);
7215bc3cb74SMauro Carvalho Chehab 		break;
7225bc3cb74SMauro Carvalho Chehab 	default:
7235bc3cb74SMauro Carvalho Chehab 		pr_cont("type=%u\n", p->type);
7245bc3cb74SMauro Carvalho Chehab 		break;
7255bc3cb74SMauro Carvalho Chehab 	}
7265bc3cb74SMauro Carvalho Chehab }
7275bc3cb74SMauro Carvalho Chehab 
7285bc3cb74SMauro Carvalho Chehab static void v4l_print_frmsizeenum(const void *arg, bool write_only)
7295bc3cb74SMauro Carvalho Chehab {
7305bc3cb74SMauro Carvalho Chehab 	const struct v4l2_frmsizeenum *p = arg;
7315bc3cb74SMauro Carvalho Chehab 
732e927e1e0SSakari Ailus 	pr_cont("index=%u, pixelformat=%p4cc, type=%u",
733e927e1e0SSakari Ailus 		p->index, &p->pixel_format, p->type);
7345bc3cb74SMauro Carvalho Chehab 	switch (p->type) {
7355bc3cb74SMauro Carvalho Chehab 	case V4L2_FRMSIZE_TYPE_DISCRETE:
736560dde24SHans Verkuil 		pr_cont(", wxh=%ux%u\n",
7375bc3cb74SMauro Carvalho Chehab 			p->discrete.width, p->discrete.height);
7385bc3cb74SMauro Carvalho Chehab 		break;
7395bc3cb74SMauro Carvalho Chehab 	case V4L2_FRMSIZE_TYPE_STEPWISE:
740560dde24SHans Verkuil 		pr_cont(", min=%ux%u, max=%ux%u, step=%ux%u\n",
7412489477eSRicardo Ribalda 				p->stepwise.min_width,
7422489477eSRicardo Ribalda 				p->stepwise.min_height,
7432489477eSRicardo Ribalda 				p->stepwise.max_width,
7442489477eSRicardo Ribalda 				p->stepwise.max_height,
7452489477eSRicardo Ribalda 				p->stepwise.step_width,
7462489477eSRicardo Ribalda 				p->stepwise.step_height);
7475bc3cb74SMauro Carvalho Chehab 		break;
7485bc3cb74SMauro Carvalho Chehab 	case V4L2_FRMSIZE_TYPE_CONTINUOUS:
7495bc3cb74SMauro Carvalho Chehab 	default:
7505bc3cb74SMauro Carvalho Chehab 		pr_cont("\n");
7515bc3cb74SMauro Carvalho Chehab 		break;
7525bc3cb74SMauro Carvalho Chehab 	}
7535bc3cb74SMauro Carvalho Chehab }
7545bc3cb74SMauro Carvalho Chehab 
7555bc3cb74SMauro Carvalho Chehab static void v4l_print_frmivalenum(const void *arg, bool write_only)
7565bc3cb74SMauro Carvalho Chehab {
7575bc3cb74SMauro Carvalho Chehab 	const struct v4l2_frmivalenum *p = arg;
7585bc3cb74SMauro Carvalho Chehab 
759e927e1e0SSakari Ailus 	pr_cont("index=%u, pixelformat=%p4cc, wxh=%ux%u, type=%u",
760e927e1e0SSakari Ailus 		p->index, &p->pixel_format, p->width, p->height, p->type);
7615bc3cb74SMauro Carvalho Chehab 	switch (p->type) {
7625bc3cb74SMauro Carvalho Chehab 	case V4L2_FRMIVAL_TYPE_DISCRETE:
763560dde24SHans Verkuil 		pr_cont(", fps=%d/%d\n",
7645bc3cb74SMauro Carvalho Chehab 				p->discrete.numerator,
7655bc3cb74SMauro Carvalho Chehab 				p->discrete.denominator);
7665bc3cb74SMauro Carvalho Chehab 		break;
7675bc3cb74SMauro Carvalho Chehab 	case V4L2_FRMIVAL_TYPE_STEPWISE:
768560dde24SHans Verkuil 		pr_cont(", min=%d/%d, max=%d/%d, step=%d/%d\n",
7695bc3cb74SMauro Carvalho Chehab 				p->stepwise.min.numerator,
7705bc3cb74SMauro Carvalho Chehab 				p->stepwise.min.denominator,
7715bc3cb74SMauro Carvalho Chehab 				p->stepwise.max.numerator,
7725bc3cb74SMauro Carvalho Chehab 				p->stepwise.max.denominator,
7735bc3cb74SMauro Carvalho Chehab 				p->stepwise.step.numerator,
7745bc3cb74SMauro Carvalho Chehab 				p->stepwise.step.denominator);
7755bc3cb74SMauro Carvalho Chehab 		break;
7765bc3cb74SMauro Carvalho Chehab 	case V4L2_FRMIVAL_TYPE_CONTINUOUS:
7775bc3cb74SMauro Carvalho Chehab 	default:
7785bc3cb74SMauro Carvalho Chehab 		pr_cont("\n");
7795bc3cb74SMauro Carvalho Chehab 		break;
7805bc3cb74SMauro Carvalho Chehab 	}
7815bc3cb74SMauro Carvalho Chehab }
7825bc3cb74SMauro Carvalho Chehab 
7835bc3cb74SMauro Carvalho Chehab static void v4l_print_event(const void *arg, bool write_only)
7845bc3cb74SMauro Carvalho Chehab {
7855bc3cb74SMauro Carvalho Chehab 	const struct v4l2_event *p = arg;
7865bc3cb74SMauro Carvalho Chehab 	const struct v4l2_event_ctrl *c;
7875bc3cb74SMauro Carvalho Chehab 
7881a6c0b36SArnd Bergmann 	pr_cont("type=0x%x, pending=%u, sequence=%u, id=%u, timestamp=%llu.%9.9llu\n",
7895bc3cb74SMauro Carvalho Chehab 			p->type, p->pending, p->sequence, p->id,
7905bc3cb74SMauro Carvalho Chehab 			p->timestamp.tv_sec, p->timestamp.tv_nsec);
7915bc3cb74SMauro Carvalho Chehab 	switch (p->type) {
7925bc3cb74SMauro Carvalho Chehab 	case V4L2_EVENT_VSYNC:
7935bc3cb74SMauro Carvalho Chehab 		printk(KERN_DEBUG "field=%s\n",
7945bc3cb74SMauro Carvalho Chehab 			prt_names(p->u.vsync.field, v4l2_field_names));
7955bc3cb74SMauro Carvalho Chehab 		break;
7965bc3cb74SMauro Carvalho Chehab 	case V4L2_EVENT_CTRL:
7975bc3cb74SMauro Carvalho Chehab 		c = &p->u.ctrl;
7985bc3cb74SMauro Carvalho Chehab 		printk(KERN_DEBUG "changes=0x%x, type=%u, ",
7995bc3cb74SMauro Carvalho Chehab 			c->changes, c->type);
8005bc3cb74SMauro Carvalho Chehab 		if (c->type == V4L2_CTRL_TYPE_INTEGER64)
8015bc3cb74SMauro Carvalho Chehab 			pr_cont("value64=%lld, ", c->value64);
8025bc3cb74SMauro Carvalho Chehab 		else
8035bc3cb74SMauro Carvalho Chehab 			pr_cont("value=%d, ", c->value);
8048720427cSMauro Carvalho Chehab 		pr_cont("flags=0x%x, minimum=%d, maximum=%d, step=%d, default_value=%d\n",
8055bc3cb74SMauro Carvalho Chehab 			c->flags, c->minimum, c->maximum,
8065bc3cb74SMauro Carvalho Chehab 			c->step, c->default_value);
8075bc3cb74SMauro Carvalho Chehab 		break;
8085bc3cb74SMauro Carvalho Chehab 	case V4L2_EVENT_FRAME_SYNC:
8095bc3cb74SMauro Carvalho Chehab 		pr_cont("frame_sequence=%u\n",
8105bc3cb74SMauro Carvalho Chehab 			p->u.frame_sync.frame_sequence);
8115bc3cb74SMauro Carvalho Chehab 		break;
8125bc3cb74SMauro Carvalho Chehab 	}
8135bc3cb74SMauro Carvalho Chehab }
8145bc3cb74SMauro Carvalho Chehab 
8155bc3cb74SMauro Carvalho Chehab static void v4l_print_event_subscription(const void *arg, bool write_only)
8165bc3cb74SMauro Carvalho Chehab {
8175bc3cb74SMauro Carvalho Chehab 	const struct v4l2_event_subscription *p = arg;
8185bc3cb74SMauro Carvalho Chehab 
8195bc3cb74SMauro Carvalho Chehab 	pr_cont("type=0x%x, id=0x%x, flags=0x%x\n",
8205bc3cb74SMauro Carvalho Chehab 			p->type, p->id, p->flags);
8215bc3cb74SMauro Carvalho Chehab }
8225bc3cb74SMauro Carvalho Chehab 
8235bc3cb74SMauro Carvalho Chehab static void v4l_print_sliced_vbi_cap(const void *arg, bool write_only)
8245bc3cb74SMauro Carvalho Chehab {
8255bc3cb74SMauro Carvalho Chehab 	const struct v4l2_sliced_vbi_cap *p = arg;
8265bc3cb74SMauro Carvalho Chehab 	int i;
8275bc3cb74SMauro Carvalho Chehab 
8285bc3cb74SMauro Carvalho Chehab 	pr_cont("type=%s, service_set=0x%08x\n",
8295bc3cb74SMauro Carvalho Chehab 			prt_names(p->type, v4l2_type_names), p->service_set);
8305bc3cb74SMauro Carvalho Chehab 	for (i = 0; i < 24; i++)
8315bc3cb74SMauro Carvalho Chehab 		printk(KERN_DEBUG "line[%02u]=0x%04x, 0x%04x\n", i,
8325bc3cb74SMauro Carvalho Chehab 				p->service_lines[0][i],
8335bc3cb74SMauro Carvalho Chehab 				p->service_lines[1][i]);
8345bc3cb74SMauro Carvalho Chehab }
8355bc3cb74SMauro Carvalho Chehab 
8365bc3cb74SMauro Carvalho Chehab static void v4l_print_freq_band(const void *arg, bool write_only)
8375bc3cb74SMauro Carvalho Chehab {
8385bc3cb74SMauro Carvalho Chehab 	const struct v4l2_frequency_band *p = arg;
8395bc3cb74SMauro Carvalho Chehab 
8408720427cSMauro Carvalho Chehab 	pr_cont("tuner=%u, type=%u, index=%u, capability=0x%x, rangelow=%u, rangehigh=%u, modulation=0x%x\n",
8415bc3cb74SMauro Carvalho Chehab 			p->tuner, p->type, p->index,
8425bc3cb74SMauro Carvalho Chehab 			p->capability, p->rangelow,
8435bc3cb74SMauro Carvalho Chehab 			p->rangehigh, p->modulation);
8445bc3cb74SMauro Carvalho Chehab }
8455bc3cb74SMauro Carvalho Chehab 
846dd519bb3SHans Verkuil static void v4l_print_edid(const void *arg, bool write_only)
847dd519bb3SHans Verkuil {
848dd519bb3SHans Verkuil 	const struct v4l2_edid *p = arg;
849dd519bb3SHans Verkuil 
850dd519bb3SHans Verkuil 	pr_cont("pad=%u, start_block=%u, blocks=%u\n",
851dd519bb3SHans Verkuil 		p->pad, p->start_block, p->blocks);
852dd519bb3SHans Verkuil }
853dd519bb3SHans Verkuil 
8545bc3cb74SMauro Carvalho Chehab static void v4l_print_u32(const void *arg, bool write_only)
8555bc3cb74SMauro Carvalho Chehab {
8565bc3cb74SMauro Carvalho Chehab 	pr_cont("value=%u\n", *(const u32 *)arg);
8575bc3cb74SMauro Carvalho Chehab }
8585bc3cb74SMauro Carvalho Chehab 
8595bc3cb74SMauro Carvalho Chehab static void v4l_print_newline(const void *arg, bool write_only)
8605bc3cb74SMauro Carvalho Chehab {
8615bc3cb74SMauro Carvalho Chehab 	pr_cont("\n");
8625bc3cb74SMauro Carvalho Chehab }
8635bc3cb74SMauro Carvalho Chehab 
8645bc3cb74SMauro Carvalho Chehab static void v4l_print_default(const void *arg, bool write_only)
8655bc3cb74SMauro Carvalho Chehab {
8665bc3cb74SMauro Carvalho Chehab 	pr_cont("driver-specific ioctl\n");
8675bc3cb74SMauro Carvalho Chehab }
8685bc3cb74SMauro Carvalho Chehab 
869861f92cbSRicardo Ribalda static bool check_ext_ctrls(struct v4l2_ext_controls *c, unsigned long ioctl)
8705bc3cb74SMauro Carvalho Chehab {
8715bc3cb74SMauro Carvalho Chehab 	__u32 i;
8725bc3cb74SMauro Carvalho Chehab 
8735bc3cb74SMauro Carvalho Chehab 	/* zero the reserved fields */
874f23317adSAlexandre Courbot 	c->reserved[0] = 0;
8755bc3cb74SMauro Carvalho Chehab 	for (i = 0; i < c->count; i++)
8765bc3cb74SMauro Carvalho Chehab 		c->controls[i].reserved2[0] = 0;
8775bc3cb74SMauro Carvalho Chehab 
878861f92cbSRicardo Ribalda 	switch (c->which) {
879861f92cbSRicardo Ribalda 	case V4L2_CID_PRIVATE_BASE:
880861f92cbSRicardo Ribalda 		/*
881861f92cbSRicardo Ribalda 		 * V4L2_CID_PRIVATE_BASE cannot be used as control class
882861f92cbSRicardo Ribalda 		 * when using extended controls.
883861f92cbSRicardo Ribalda 		 * Only when passed in through VIDIOC_G_CTRL and VIDIOC_S_CTRL
884861f92cbSRicardo Ribalda 		 * is it allowed for backwards compatibility.
8855bc3cb74SMauro Carvalho Chehab 		 */
886861f92cbSRicardo Ribalda 		if (ioctl == VIDIOC_G_CTRL || ioctl == VIDIOC_S_CTRL)
887861f92cbSRicardo Ribalda 			return false;
888861f92cbSRicardo Ribalda 		break;
889861f92cbSRicardo Ribalda 	case V4L2_CTRL_WHICH_DEF_VAL:
890861f92cbSRicardo Ribalda 		/* Default value cannot be changed */
891861f92cbSRicardo Ribalda 		if (ioctl == VIDIOC_S_EXT_CTRLS ||
892861f92cbSRicardo Ribalda 		    ioctl == VIDIOC_TRY_EXT_CTRLS) {
893861f92cbSRicardo Ribalda 			c->error_idx = c->count;
894861f92cbSRicardo Ribalda 			return false;
895861f92cbSRicardo Ribalda 		}
896861f92cbSRicardo Ribalda 		return true;
897861f92cbSRicardo Ribalda 	case V4L2_CTRL_WHICH_CUR_VAL:
898861f92cbSRicardo Ribalda 		return true;
899861f92cbSRicardo Ribalda 	case V4L2_CTRL_WHICH_REQUEST_VAL:
900861f92cbSRicardo Ribalda 		c->error_idx = c->count;
901861f92cbSRicardo Ribalda 		return false;
902861f92cbSRicardo Ribalda 	}
903861f92cbSRicardo Ribalda 
9045bc3cb74SMauro Carvalho Chehab 	/* Check that all controls are from the same control class. */
9055bc3cb74SMauro Carvalho Chehab 	for (i = 0; i < c->count; i++) {
9060f8017beSRicardo Ribalda 		if (V4L2_CTRL_ID2WHICH(c->controls[i].id) != c->which) {
907861f92cbSRicardo Ribalda 			c->error_idx = ioctl == VIDIOC_TRY_EXT_CTRLS ? i :
908861f92cbSRicardo Ribalda 								      c->count;
909861f92cbSRicardo Ribalda 			return false;
9105bc3cb74SMauro Carvalho Chehab 		}
9115bc3cb74SMauro Carvalho Chehab 	}
912861f92cbSRicardo Ribalda 	return true;
9135bc3cb74SMauro Carvalho Chehab }
9145bc3cb74SMauro Carvalho Chehab 
9154b20259fSHans Verkuil static int check_fmt(struct file *file, enum v4l2_buf_type type)
9165bc3cb74SMauro Carvalho Chehab {
91796f49c1aSVandana BN 	const u32 vid_caps = V4L2_CAP_VIDEO_CAPTURE |
91896f49c1aSVandana BN 			     V4L2_CAP_VIDEO_CAPTURE_MPLANE |
91996f49c1aSVandana BN 			     V4L2_CAP_VIDEO_OUTPUT |
92096f49c1aSVandana BN 			     V4L2_CAP_VIDEO_OUTPUT_MPLANE |
92196f49c1aSVandana BN 			     V4L2_CAP_VIDEO_M2M | V4L2_CAP_VIDEO_M2M_MPLANE;
92296f49c1aSVandana BN 	const u32 meta_caps = V4L2_CAP_META_CAPTURE |
92396f49c1aSVandana BN 			      V4L2_CAP_META_OUTPUT;
9244b20259fSHans Verkuil 	struct video_device *vfd = video_devdata(file);
9254b20259fSHans Verkuil 	const struct v4l2_ioctl_ops *ops = vfd->ioctl_ops;
926238e4a5bSHans Verkuil 	bool is_vid = vfd->vfl_type == VFL_TYPE_VIDEO &&
92796f49c1aSVandana BN 		      (vfd->device_caps & vid_caps);
9284b20259fSHans Verkuil 	bool is_vbi = vfd->vfl_type == VFL_TYPE_VBI;
929582c52cbSAntti Palosaari 	bool is_sdr = vfd->vfl_type == VFL_TYPE_SDR;
930b2fe22d0SNick Dyer 	bool is_tch = vfd->vfl_type == VFL_TYPE_TOUCH;
931238e4a5bSHans Verkuil 	bool is_meta = vfd->vfl_type == VFL_TYPE_VIDEO &&
93296f49c1aSVandana BN 		       (vfd->device_caps & meta_caps);
9334b20259fSHans Verkuil 	bool is_rx = vfd->vfl_dir != VFL_DIR_TX;
9344b20259fSHans Verkuil 	bool is_tx = vfd->vfl_dir != VFL_DIR_RX;
9354b20259fSHans Verkuil 
9365bc3cb74SMauro Carvalho Chehab 	if (ops == NULL)
9375bc3cb74SMauro Carvalho Chehab 		return -EINVAL;
9385bc3cb74SMauro Carvalho Chehab 
9395bc3cb74SMauro Carvalho Chehab 	switch (type) {
9405bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_CAPTURE:
941b2fe22d0SNick Dyer 		if ((is_vid || is_tch) && is_rx &&
9424b20259fSHans Verkuil 		    (ops->vidioc_g_fmt_vid_cap || ops->vidioc_g_fmt_vid_cap_mplane))
9435bc3cb74SMauro Carvalho Chehab 			return 0;
9445bc3cb74SMauro Carvalho Chehab 		break;
9455bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
946095c21d3SHans Verkuil 		if ((is_vid || is_tch) && is_rx && ops->vidioc_g_fmt_vid_cap_mplane)
9475bc3cb74SMauro Carvalho Chehab 			return 0;
9485bc3cb74SMauro Carvalho Chehab 		break;
9495bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_OVERLAY:
9504b20259fSHans Verkuil 		if (is_vid && is_rx && ops->vidioc_g_fmt_vid_overlay)
9515bc3cb74SMauro Carvalho Chehab 			return 0;
9525bc3cb74SMauro Carvalho Chehab 		break;
9535bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_OUTPUT:
9544b20259fSHans Verkuil 		if (is_vid && is_tx &&
9554b20259fSHans Verkuil 		    (ops->vidioc_g_fmt_vid_out || ops->vidioc_g_fmt_vid_out_mplane))
9565bc3cb74SMauro Carvalho Chehab 			return 0;
9575bc3cb74SMauro Carvalho Chehab 		break;
9585bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
9594b20259fSHans Verkuil 		if (is_vid && is_tx && ops->vidioc_g_fmt_vid_out_mplane)
9605bc3cb74SMauro Carvalho Chehab 			return 0;
9615bc3cb74SMauro Carvalho Chehab 		break;
9625bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
9634b20259fSHans Verkuil 		if (is_vid && is_tx && ops->vidioc_g_fmt_vid_out_overlay)
9645bc3cb74SMauro Carvalho Chehab 			return 0;
9655bc3cb74SMauro Carvalho Chehab 		break;
9665bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VBI_CAPTURE:
9674b20259fSHans Verkuil 		if (is_vbi && is_rx && ops->vidioc_g_fmt_vbi_cap)
9685bc3cb74SMauro Carvalho Chehab 			return 0;
9695bc3cb74SMauro Carvalho Chehab 		break;
9705bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VBI_OUTPUT:
9714b20259fSHans Verkuil 		if (is_vbi && is_tx && ops->vidioc_g_fmt_vbi_out)
9725bc3cb74SMauro Carvalho Chehab 			return 0;
9735bc3cb74SMauro Carvalho Chehab 		break;
9745bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
9754b20259fSHans Verkuil 		if (is_vbi && is_rx && ops->vidioc_g_fmt_sliced_vbi_cap)
9765bc3cb74SMauro Carvalho Chehab 			return 0;
9775bc3cb74SMauro Carvalho Chehab 		break;
9785bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
9794b20259fSHans Verkuil 		if (is_vbi && is_tx && ops->vidioc_g_fmt_sliced_vbi_out)
9805bc3cb74SMauro Carvalho Chehab 			return 0;
9815bc3cb74SMauro Carvalho Chehab 		break;
982582c52cbSAntti Palosaari 	case V4L2_BUF_TYPE_SDR_CAPTURE:
983582c52cbSAntti Palosaari 		if (is_sdr && is_rx && ops->vidioc_g_fmt_sdr_cap)
984582c52cbSAntti Palosaari 			return 0;
985582c52cbSAntti Palosaari 		break;
9869effc72fSAntti Palosaari 	case V4L2_BUF_TYPE_SDR_OUTPUT:
9879effc72fSAntti Palosaari 		if (is_sdr && is_tx && ops->vidioc_g_fmt_sdr_out)
9889effc72fSAntti Palosaari 			return 0;
9899effc72fSAntti Palosaari 		break;
990fb9ffa6aSLaurent Pinchart 	case V4L2_BUF_TYPE_META_CAPTURE:
99196f49c1aSVandana BN 		if (is_meta && is_rx && ops->vidioc_g_fmt_meta_cap)
992fb9ffa6aSLaurent Pinchart 			return 0;
993fb9ffa6aSLaurent Pinchart 		break;
99472148d1aSSakari Ailus 	case V4L2_BUF_TYPE_META_OUTPUT:
99596f49c1aSVandana BN 		if (is_meta && is_tx && ops->vidioc_g_fmt_meta_out)
99672148d1aSSakari Ailus 			return 0;
99772148d1aSSakari Ailus 		break;
998633c98e5SHans Verkuil 	default:
9995bc3cb74SMauro Carvalho Chehab 		break;
10005bc3cb74SMauro Carvalho Chehab 	}
10015bc3cb74SMauro Carvalho Chehab 	return -EINVAL;
10025bc3cb74SMauro Carvalho Chehab }
10035bc3cb74SMauro Carvalho Chehab 
100448e93b0cSLaurent Pinchart static void v4l_sanitize_colorspace(u32 pixelformat, u32 *colorspace,
100548e93b0cSLaurent Pinchart 				    u32 *encoding, u32 *quantization,
100648e93b0cSLaurent Pinchart 				    u32 *xfer_func)
100748e93b0cSLaurent Pinchart {
100848e93b0cSLaurent Pinchart 	bool is_hsv = pixelformat == V4L2_PIX_FMT_HSV24 ||
100948e93b0cSLaurent Pinchart 		      pixelformat == V4L2_PIX_FMT_HSV32;
101048e93b0cSLaurent Pinchart 
101148e93b0cSLaurent Pinchart 	if (!v4l2_is_colorspace_valid(*colorspace)) {
101248e93b0cSLaurent Pinchart 		*colorspace = V4L2_COLORSPACE_DEFAULT;
101348e93b0cSLaurent Pinchart 		*encoding = V4L2_YCBCR_ENC_DEFAULT;
101448e93b0cSLaurent Pinchart 		*quantization = V4L2_QUANTIZATION_DEFAULT;
101548e93b0cSLaurent Pinchart 		*xfer_func = V4L2_XFER_FUNC_DEFAULT;
101648e93b0cSLaurent Pinchart 	}
101748e93b0cSLaurent Pinchart 
101848e93b0cSLaurent Pinchart 	if ((!is_hsv && !v4l2_is_ycbcr_enc_valid(*encoding)) ||
101948e93b0cSLaurent Pinchart 	    (is_hsv && !v4l2_is_hsv_enc_valid(*encoding)))
102048e93b0cSLaurent Pinchart 		*encoding = V4L2_YCBCR_ENC_DEFAULT;
102148e93b0cSLaurent Pinchart 
102248e93b0cSLaurent Pinchart 	if (!v4l2_is_quant_valid(*quantization))
102348e93b0cSLaurent Pinchart 		*quantization = V4L2_QUANTIZATION_DEFAULT;
102448e93b0cSLaurent Pinchart 
102548e93b0cSLaurent Pinchart 	if (!v4l2_is_xfer_func_valid(*xfer_func))
102648e93b0cSLaurent Pinchart 		*xfer_func = V4L2_XFER_FUNC_DEFAULT;
102748e93b0cSLaurent Pinchart }
102848e93b0cSLaurent Pinchart 
1029d52e2381SLaurent Pinchart static void v4l_sanitize_format(struct v4l2_format *fmt)
1030d52e2381SLaurent Pinchart {
1031d52e2381SLaurent Pinchart 	unsigned int offset;
1032d52e2381SLaurent Pinchart 
103314c8e80eSEzequiel Garcia 	/* Make sure num_planes is not bogus */
103414c8e80eSEzequiel Garcia 	if (fmt->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE ||
103514c8e80eSEzequiel Garcia 	    fmt->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)
103614c8e80eSEzequiel Garcia 		fmt->fmt.pix_mp.num_planes = min_t(u32, fmt->fmt.pix_mp.num_planes,
103714c8e80eSEzequiel Garcia 					       VIDEO_MAX_PLANES);
103814c8e80eSEzequiel Garcia 
1039d52e2381SLaurent Pinchart 	/*
1040d52e2381SLaurent Pinchart 	 * The v4l2_pix_format structure has been extended with fields that were
1041d52e2381SLaurent Pinchart 	 * not previously required to be set to zero by applications. The priv
1042fd3ed970SSlark Xiao 	 * field, when set to a magic value, indicates that the extended fields
1043d52e2381SLaurent Pinchart 	 * are valid. Otherwise they will contain undefined values. To simplify
1044d52e2381SLaurent Pinchart 	 * the API towards drivers zero the extended fields and set the priv
1045d52e2381SLaurent Pinchart 	 * field to the magic value when the extended pixel format structure
1046d52e2381SLaurent Pinchart 	 * isn't used by applications.
1047d52e2381SLaurent Pinchart 	 */
104848e93b0cSLaurent Pinchart 	if (fmt->type == V4L2_BUF_TYPE_VIDEO_CAPTURE ||
104948e93b0cSLaurent Pinchart 	    fmt->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) {
105048e93b0cSLaurent Pinchart 		if (fmt->fmt.pix.priv != V4L2_PIX_FMT_PRIV_MAGIC) {
1051d52e2381SLaurent Pinchart 			fmt->fmt.pix.priv = V4L2_PIX_FMT_PRIV_MAGIC;
1052d52e2381SLaurent Pinchart 
1053d52e2381SLaurent Pinchart 			offset = offsetof(struct v4l2_pix_format, priv)
1054d52e2381SLaurent Pinchart 			       + sizeof(fmt->fmt.pix.priv);
1055d52e2381SLaurent Pinchart 			memset(((void *)&fmt->fmt.pix) + offset, 0,
1056d52e2381SLaurent Pinchart 			       sizeof(fmt->fmt.pix) - offset);
1057d52e2381SLaurent Pinchart 		}
105848e93b0cSLaurent Pinchart 	}
105948e93b0cSLaurent Pinchart 
106048e93b0cSLaurent Pinchart 	/* Replace invalid colorspace values with defaults. */
106148e93b0cSLaurent Pinchart 	if (fmt->type == V4L2_BUF_TYPE_VIDEO_CAPTURE ||
106248e93b0cSLaurent Pinchart 	    fmt->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) {
106348e93b0cSLaurent Pinchart 		v4l_sanitize_colorspace(fmt->fmt.pix.pixelformat,
106448e93b0cSLaurent Pinchart 					&fmt->fmt.pix.colorspace,
106548e93b0cSLaurent Pinchart 					&fmt->fmt.pix.ycbcr_enc,
106648e93b0cSLaurent Pinchart 					&fmt->fmt.pix.quantization,
106748e93b0cSLaurent Pinchart 					&fmt->fmt.pix.xfer_func);
106848e93b0cSLaurent Pinchart 	} else if (fmt->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE ||
106948e93b0cSLaurent Pinchart 		   fmt->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
107048e93b0cSLaurent Pinchart 		u32 ycbcr_enc = fmt->fmt.pix_mp.ycbcr_enc;
107148e93b0cSLaurent Pinchart 		u32 quantization = fmt->fmt.pix_mp.quantization;
107248e93b0cSLaurent Pinchart 		u32 xfer_func = fmt->fmt.pix_mp.xfer_func;
107348e93b0cSLaurent Pinchart 
107448e93b0cSLaurent Pinchart 		v4l_sanitize_colorspace(fmt->fmt.pix_mp.pixelformat,
107548e93b0cSLaurent Pinchart 					&fmt->fmt.pix_mp.colorspace, &ycbcr_enc,
107648e93b0cSLaurent Pinchart 					&quantization, &xfer_func);
107748e93b0cSLaurent Pinchart 
107848e93b0cSLaurent Pinchart 		fmt->fmt.pix_mp.ycbcr_enc = ycbcr_enc;
107948e93b0cSLaurent Pinchart 		fmt->fmt.pix_mp.quantization = quantization;
108048e93b0cSLaurent Pinchart 		fmt->fmt.pix_mp.xfer_func = xfer_func;
108148e93b0cSLaurent Pinchart 	}
108248e93b0cSLaurent Pinchart }
1083d52e2381SLaurent Pinchart 
10845bc3cb74SMauro Carvalho Chehab static int v4l_querycap(const struct v4l2_ioctl_ops *ops,
10855bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
10865bc3cb74SMauro Carvalho Chehab {
10875bc3cb74SMauro Carvalho Chehab 	struct v4l2_capability *cap = (struct v4l2_capability *)arg;
10887bbe7813SHans Verkuil 	struct video_device *vfd = video_devdata(file);
1089d52e2381SLaurent Pinchart 	int ret;
10905bc3cb74SMauro Carvalho Chehab 
10915bc3cb74SMauro Carvalho Chehab 	cap->version = LINUX_VERSION_CODE;
10927bbe7813SHans Verkuil 	cap->device_caps = vfd->device_caps;
10937bbe7813SHans Verkuil 	cap->capabilities = vfd->device_caps | V4L2_CAP_DEVICE_CAPS;
1094d52e2381SLaurent Pinchart 
1095f2d8b691SSakari Ailus 	media_set_bus_info(cap->bus_info, sizeof(cap->bus_info),
1096f2d8b691SSakari Ailus 			   vfd->dev_parent);
1097f2d8b691SSakari Ailus 
1098d52e2381SLaurent Pinchart 	ret = ops->vidioc_querycap(file, fh, cap);
1099d52e2381SLaurent Pinchart 
1100454a4e72SHans Verkuil 	/*
11013c135050SHans Verkuil 	 * Drivers must not change device_caps, so check for this and
11023c135050SHans Verkuil 	 * warn if this happened.
1103454a4e72SHans Verkuil 	 */
11043c135050SHans Verkuil 	WARN_ON(cap->device_caps != vfd->device_caps);
11053c135050SHans Verkuil 	/*
11063c135050SHans Verkuil 	 * Check that capabilities is a superset of
11073c135050SHans Verkuil 	 * vfd->device_caps | V4L2_CAP_DEVICE_CAPS
11083c135050SHans Verkuil 	 */
11093c135050SHans Verkuil 	WARN_ON((cap->capabilities &
11103c135050SHans Verkuil 		 (vfd->device_caps | V4L2_CAP_DEVICE_CAPS)) !=
11113c135050SHans Verkuil 		(vfd->device_caps | V4L2_CAP_DEVICE_CAPS));
11123c135050SHans Verkuil 	cap->capabilities |= V4L2_CAP_EXT_PIX_FORMAT;
1113796a2bd2SHans Verkuil 	cap->device_caps |= V4L2_CAP_EXT_PIX_FORMAT;
1114d52e2381SLaurent Pinchart 
1115d52e2381SLaurent Pinchart 	return ret;
11165bc3cb74SMauro Carvalho Chehab }
11175bc3cb74SMauro Carvalho Chehab 
1118f645e625SNiklas Söderlund static int v4l_g_input(const struct v4l2_ioctl_ops *ops,
1119f645e625SNiklas Söderlund 		       struct file *file, void *fh, void *arg)
1120f645e625SNiklas Söderlund {
1121f645e625SNiklas Söderlund 	struct video_device *vfd = video_devdata(file);
1122f645e625SNiklas Söderlund 
1123f645e625SNiklas Söderlund 	if (vfd->device_caps & V4L2_CAP_IO_MC) {
1124f645e625SNiklas Söderlund 		*(int *)arg = 0;
1125f645e625SNiklas Söderlund 		return 0;
1126f645e625SNiklas Söderlund 	}
1127f645e625SNiklas Söderlund 
1128f645e625SNiklas Söderlund 	return ops->vidioc_g_input(file, fh, arg);
1129f645e625SNiklas Söderlund }
1130f645e625SNiklas Söderlund 
1131f645e625SNiklas Söderlund static int v4l_g_output(const struct v4l2_ioctl_ops *ops,
1132f645e625SNiklas Söderlund 			struct file *file, void *fh, void *arg)
1133f645e625SNiklas Söderlund {
1134f645e625SNiklas Söderlund 	struct video_device *vfd = video_devdata(file);
1135f645e625SNiklas Söderlund 
1136f645e625SNiklas Söderlund 	if (vfd->device_caps & V4L2_CAP_IO_MC) {
1137f645e625SNiklas Söderlund 		*(int *)arg = 0;
1138f645e625SNiklas Söderlund 		return 0;
1139f645e625SNiklas Söderlund 	}
1140f645e625SNiklas Söderlund 
1141f645e625SNiklas Söderlund 	return ops->vidioc_g_output(file, fh, arg);
1142f645e625SNiklas Söderlund }
1143f645e625SNiklas Söderlund 
11445bc3cb74SMauro Carvalho Chehab static int v4l_s_input(const struct v4l2_ioctl_ops *ops,
11455bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
11465bc3cb74SMauro Carvalho Chehab {
114777fa4e07SShuah Khan 	struct video_device *vfd = video_devdata(file);
114877fa4e07SShuah Khan 	int ret;
114977fa4e07SShuah Khan 
115077fa4e07SShuah Khan 	ret = v4l_enable_media_source(vfd);
115177fa4e07SShuah Khan 	if (ret)
115277fa4e07SShuah Khan 		return ret;
1153f645e625SNiklas Söderlund 
1154f645e625SNiklas Söderlund 	if (vfd->device_caps & V4L2_CAP_IO_MC)
1155f645e625SNiklas Söderlund 		return  *(int *)arg ? -EINVAL : 0;
1156f645e625SNiklas Söderlund 
11575bc3cb74SMauro Carvalho Chehab 	return ops->vidioc_s_input(file, fh, *(unsigned int *)arg);
11585bc3cb74SMauro Carvalho Chehab }
11595bc3cb74SMauro Carvalho Chehab 
11605bc3cb74SMauro Carvalho Chehab static int v4l_s_output(const struct v4l2_ioctl_ops *ops,
11615bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
11625bc3cb74SMauro Carvalho Chehab {
1163f645e625SNiklas Söderlund 	struct video_device *vfd = video_devdata(file);
1164f645e625SNiklas Söderlund 
1165f645e625SNiklas Söderlund 	if (vfd->device_caps & V4L2_CAP_IO_MC)
1166f645e625SNiklas Söderlund 		return  *(int *)arg ? -EINVAL : 0;
1167f645e625SNiklas Söderlund 
11685bc3cb74SMauro Carvalho Chehab 	return ops->vidioc_s_output(file, fh, *(unsigned int *)arg);
11695bc3cb74SMauro Carvalho Chehab }
11705bc3cb74SMauro Carvalho Chehab 
11715bc3cb74SMauro Carvalho Chehab static int v4l_g_priority(const struct v4l2_ioctl_ops *ops,
11725bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
11735bc3cb74SMauro Carvalho Chehab {
11745bc3cb74SMauro Carvalho Chehab 	struct video_device *vfd;
11755bc3cb74SMauro Carvalho Chehab 	u32 *p = arg;
11765bc3cb74SMauro Carvalho Chehab 
11775bc3cb74SMauro Carvalho Chehab 	vfd = video_devdata(file);
117859b702eaSLaurent Pinchart 	*p = v4l2_prio_max(vfd->prio);
11795bc3cb74SMauro Carvalho Chehab 	return 0;
11805bc3cb74SMauro Carvalho Chehab }
11815bc3cb74SMauro Carvalho Chehab 
11825bc3cb74SMauro Carvalho Chehab static int v4l_s_priority(const struct v4l2_ioctl_ops *ops,
11835bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
11845bc3cb74SMauro Carvalho Chehab {
11855bc3cb74SMauro Carvalho Chehab 	struct video_device *vfd;
11865bc3cb74SMauro Carvalho Chehab 	struct v4l2_fh *vfh;
11875bc3cb74SMauro Carvalho Chehab 	u32 *p = arg;
11885bc3cb74SMauro Carvalho Chehab 
11895bc3cb74SMauro Carvalho Chehab 	vfd = video_devdata(file);
11902438e78aSHans Verkuil 	if (!test_bit(V4L2_FL_USES_V4L2_FH, &vfd->flags))
11912438e78aSHans Verkuil 		return -ENOTTY;
11925bc3cb74SMauro Carvalho Chehab 	vfh = file->private_data;
119359b702eaSLaurent Pinchart 	return v4l2_prio_change(vfd->prio, &vfh->prio, *p);
11945bc3cb74SMauro Carvalho Chehab }
11955bc3cb74SMauro Carvalho Chehab 
11965bc3cb74SMauro Carvalho Chehab static int v4l_enuminput(const struct v4l2_ioctl_ops *ops,
11975bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
11985bc3cb74SMauro Carvalho Chehab {
119973f35418SHans Verkuil 	struct video_device *vfd = video_devdata(file);
12005bc3cb74SMauro Carvalho Chehab 	struct v4l2_input *p = arg;
12015bc3cb74SMauro Carvalho Chehab 
12025bc3cb74SMauro Carvalho Chehab 	/*
120302fa6282SHans Verkuil 	 * We set the flags for CAP_DV_TIMINGS &
12045bc3cb74SMauro Carvalho Chehab 	 * CAP_STD here based on ioctl handler provided by the
12055bc3cb74SMauro Carvalho Chehab 	 * driver. If the driver doesn't support these
12065bc3cb74SMauro Carvalho Chehab 	 * for a specific input, it must override these flags.
12075bc3cb74SMauro Carvalho Chehab 	 */
120873f35418SHans Verkuil 	if (is_valid_ioctl(vfd, VIDIOC_S_STD))
12095bc3cb74SMauro Carvalho Chehab 		p->capabilities |= V4L2_IN_CAP_STD;
12105bc3cb74SMauro Carvalho Chehab 
1211f645e625SNiklas Söderlund 	if (vfd->device_caps & V4L2_CAP_IO_MC) {
1212f645e625SNiklas Söderlund 		if (p->index)
1213f645e625SNiklas Söderlund 			return -EINVAL;
1214f645e625SNiklas Söderlund 		strscpy(p->name, vfd->name, sizeof(p->name));
1215f645e625SNiklas Söderlund 		p->type = V4L2_INPUT_TYPE_CAMERA;
1216f645e625SNiklas Söderlund 		return 0;
1217f645e625SNiklas Söderlund 	}
1218f645e625SNiklas Söderlund 
12195bc3cb74SMauro Carvalho Chehab 	return ops->vidioc_enum_input(file, fh, p);
12205bc3cb74SMauro Carvalho Chehab }
12215bc3cb74SMauro Carvalho Chehab 
12225bc3cb74SMauro Carvalho Chehab static int v4l_enumoutput(const struct v4l2_ioctl_ops *ops,
12235bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
12245bc3cb74SMauro Carvalho Chehab {
122573f35418SHans Verkuil 	struct video_device *vfd = video_devdata(file);
12265bc3cb74SMauro Carvalho Chehab 	struct v4l2_output *p = arg;
12275bc3cb74SMauro Carvalho Chehab 
12285bc3cb74SMauro Carvalho Chehab 	/*
122902fa6282SHans Verkuil 	 * We set the flags for CAP_DV_TIMINGS &
12305bc3cb74SMauro Carvalho Chehab 	 * CAP_STD here based on ioctl handler provided by the
12315bc3cb74SMauro Carvalho Chehab 	 * driver. If the driver doesn't support these
12325bc3cb74SMauro Carvalho Chehab 	 * for a specific output, it must override these flags.
12335bc3cb74SMauro Carvalho Chehab 	 */
123473f35418SHans Verkuil 	if (is_valid_ioctl(vfd, VIDIOC_S_STD))
12355bc3cb74SMauro Carvalho Chehab 		p->capabilities |= V4L2_OUT_CAP_STD;
12365bc3cb74SMauro Carvalho Chehab 
1237f645e625SNiklas Söderlund 	if (vfd->device_caps & V4L2_CAP_IO_MC) {
1238f645e625SNiklas Söderlund 		if (p->index)
1239f645e625SNiklas Söderlund 			return -EINVAL;
1240f645e625SNiklas Söderlund 		strscpy(p->name, vfd->name, sizeof(p->name));
1241f645e625SNiklas Söderlund 		p->type = V4L2_OUTPUT_TYPE_ANALOG;
1242f645e625SNiklas Söderlund 		return 0;
1243f645e625SNiklas Söderlund 	}
1244f645e625SNiklas Söderlund 
12455bc3cb74SMauro Carvalho Chehab 	return ops->vidioc_enum_output(file, fh, p);
12465bc3cb74SMauro Carvalho Chehab }
12475bc3cb74SMauro Carvalho Chehab 
1248ba300204SHans Verkuil static void v4l_fill_fmtdesc(struct v4l2_fmtdesc *fmt)
1249ba300204SHans Verkuil {
1250ba300204SHans Verkuil 	const unsigned sz = sizeof(fmt->description);
1251ba300204SHans Verkuil 	const char *descr = NULL;
1252ba300204SHans Verkuil 	u32 flags = 0;
1253ba300204SHans Verkuil 
1254ba300204SHans Verkuil 	/*
1255ba300204SHans Verkuil 	 * We depart from the normal coding style here since the descriptions
1256ba300204SHans Verkuil 	 * should be aligned so it is easy to see which descriptions will be
1257ba300204SHans Verkuil 	 * longer than 31 characters (the max length for a description).
1258ba300204SHans Verkuil 	 * And frankly, this is easier to read anyway.
1259ba300204SHans Verkuil 	 *
1260ba300204SHans Verkuil 	 * Note that gcc will use O(log N) comparisons to find the right case.
1261ba300204SHans Verkuil 	 */
1262ba300204SHans Verkuil 	switch (fmt->pixelformat) {
1263ba300204SHans Verkuil 	/* Max description length mask:	descr = "0123456789012345678901234567890" */
1264ba300204SHans Verkuil 	case V4L2_PIX_FMT_RGB332:	descr = "8-bit RGB 3-3-2"; break;
1265ba300204SHans Verkuil 	case V4L2_PIX_FMT_RGB444:	descr = "16-bit A/XRGB 4-4-4-4"; break;
1266ba300204SHans Verkuil 	case V4L2_PIX_FMT_ARGB444:	descr = "16-bit ARGB 4-4-4-4"; break;
1267ba300204SHans Verkuil 	case V4L2_PIX_FMT_XRGB444:	descr = "16-bit XRGB 4-4-4-4"; break;
12684747bd0fSHans Verkuil 	case V4L2_PIX_FMT_RGBA444:	descr = "16-bit RGBA 4-4-4-4"; break;
12694747bd0fSHans Verkuil 	case V4L2_PIX_FMT_RGBX444:	descr = "16-bit RGBX 4-4-4-4"; break;
12704747bd0fSHans Verkuil 	case V4L2_PIX_FMT_ABGR444:	descr = "16-bit ABGR 4-4-4-4"; break;
12714747bd0fSHans Verkuil 	case V4L2_PIX_FMT_XBGR444:	descr = "16-bit XBGR 4-4-4-4"; break;
12724747bd0fSHans Verkuil 	case V4L2_PIX_FMT_BGRA444:	descr = "16-bit BGRA 4-4-4-4"; break;
12734747bd0fSHans Verkuil 	case V4L2_PIX_FMT_BGRX444:	descr = "16-bit BGRX 4-4-4-4"; break;
1274ba300204SHans Verkuil 	case V4L2_PIX_FMT_RGB555:	descr = "16-bit A/XRGB 1-5-5-5"; break;
1275ba300204SHans Verkuil 	case V4L2_PIX_FMT_ARGB555:	descr = "16-bit ARGB 1-5-5-5"; break;
1276ba300204SHans Verkuil 	case V4L2_PIX_FMT_XRGB555:	descr = "16-bit XRGB 1-5-5-5"; break;
12774747bd0fSHans Verkuil 	case V4L2_PIX_FMT_ABGR555:	descr = "16-bit ABGR 1-5-5-5"; break;
12784747bd0fSHans Verkuil 	case V4L2_PIX_FMT_XBGR555:	descr = "16-bit XBGR 1-5-5-5"; break;
12794747bd0fSHans Verkuil 	case V4L2_PIX_FMT_RGBA555:	descr = "16-bit RGBA 5-5-5-1"; break;
12804747bd0fSHans Verkuil 	case V4L2_PIX_FMT_RGBX555:	descr = "16-bit RGBX 5-5-5-1"; break;
12814747bd0fSHans Verkuil 	case V4L2_PIX_FMT_BGRA555:	descr = "16-bit BGRA 5-5-5-1"; break;
12824747bd0fSHans Verkuil 	case V4L2_PIX_FMT_BGRX555:	descr = "16-bit BGRX 5-5-5-1"; break;
1283ba300204SHans Verkuil 	case V4L2_PIX_FMT_RGB565:	descr = "16-bit RGB 5-6-5"; break;
1284ba300204SHans Verkuil 	case V4L2_PIX_FMT_RGB555X:	descr = "16-bit A/XRGB 1-5-5-5 BE"; break;
1285ba300204SHans Verkuil 	case V4L2_PIX_FMT_ARGB555X:	descr = "16-bit ARGB 1-5-5-5 BE"; break;
1286ba300204SHans Verkuil 	case V4L2_PIX_FMT_XRGB555X:	descr = "16-bit XRGB 1-5-5-5 BE"; break;
1287ba300204SHans Verkuil 	case V4L2_PIX_FMT_RGB565X:	descr = "16-bit RGB 5-6-5 BE"; break;
1288ba300204SHans Verkuil 	case V4L2_PIX_FMT_BGR666:	descr = "18-bit BGRX 6-6-6-14"; break;
1289ba300204SHans Verkuil 	case V4L2_PIX_FMT_BGR24:	descr = "24-bit BGR 8-8-8"; break;
1290ba300204SHans Verkuil 	case V4L2_PIX_FMT_RGB24:	descr = "24-bit RGB 8-8-8"; break;
1291ba300204SHans Verkuil 	case V4L2_PIX_FMT_BGR32:	descr = "32-bit BGRA/X 8-8-8-8"; break;
1292ba300204SHans Verkuil 	case V4L2_PIX_FMT_ABGR32:	descr = "32-bit BGRA 8-8-8-8"; break;
1293ba300204SHans Verkuil 	case V4L2_PIX_FMT_XBGR32:	descr = "32-bit BGRX 8-8-8-8"; break;
1294ba300204SHans Verkuil 	case V4L2_PIX_FMT_RGB32:	descr = "32-bit A/XRGB 8-8-8-8"; break;
1295ba300204SHans Verkuil 	case V4L2_PIX_FMT_ARGB32:	descr = "32-bit ARGB 8-8-8-8"; break;
1296ba300204SHans Verkuil 	case V4L2_PIX_FMT_XRGB32:	descr = "32-bit XRGB 8-8-8-8"; break;
12974747bd0fSHans Verkuil 	case V4L2_PIX_FMT_BGRA32:	descr = "32-bit ABGR 8-8-8-8"; break;
12984747bd0fSHans Verkuil 	case V4L2_PIX_FMT_BGRX32:	descr = "32-bit XBGR 8-8-8-8"; break;
12994747bd0fSHans Verkuil 	case V4L2_PIX_FMT_RGBA32:	descr = "32-bit RGBA 8-8-8-8"; break;
13004747bd0fSHans Verkuil 	case V4L2_PIX_FMT_RGBX32:	descr = "32-bit RGBX 8-8-8-8"; break;
1301*8d0e3fc6STomi Valkeinen 	case V4L2_PIX_FMT_RGBX1010102:	descr = "32-bit RGBX 10-10-10-2"; break;
1302*8d0e3fc6STomi Valkeinen 	case V4L2_PIX_FMT_RGBA1010102:	descr = "32-bit RGBA 10-10-10-2"; break;
1303*8d0e3fc6STomi Valkeinen 	case V4L2_PIX_FMT_ARGB2101010:	descr = "32-bit ARGB 2-10-10-10"; break;
1304ba300204SHans Verkuil 	case V4L2_PIX_FMT_GREY:		descr = "8-bit Greyscale"; break;
1305ba300204SHans Verkuil 	case V4L2_PIX_FMT_Y4:		descr = "4-bit Greyscale"; break;
1306ba300204SHans Verkuil 	case V4L2_PIX_FMT_Y6:		descr = "6-bit Greyscale"; break;
1307ba300204SHans Verkuil 	case V4L2_PIX_FMT_Y10:		descr = "10-bit Greyscale"; break;
1308ba300204SHans Verkuil 	case V4L2_PIX_FMT_Y12:		descr = "12-bit Greyscale"; break;
1309ae9753a0SDaniel Glöckner 	case V4L2_PIX_FMT_Y14:		descr = "14-bit Greyscale"; break;
1310ba300204SHans Verkuil 	case V4L2_PIX_FMT_Y16:		descr = "16-bit Greyscale"; break;
13112e5e435fSRicardo Ribalda 	case V4L2_PIX_FMT_Y16_BE:	descr = "16-bit Greyscale BE"; break;
1312ba300204SHans Verkuil 	case V4L2_PIX_FMT_Y10BPACK:	descr = "10-bit Greyscale (Packed)"; break;
13136e15bec4STodor Tomov 	case V4L2_PIX_FMT_Y10P:		descr = "10-bit Greyscale (MIPI Packed)"; break;
1314b87f5e25SDaniel Scally 	case V4L2_PIX_FMT_IPU3_Y10:	descr = "10-bit greyscale (IPU3 Packed)"; break;
13155b382290SLaurent Pinchart 	case V4L2_PIX_FMT_Y8I:		descr = "Interleaved 8-bit Greyscale"; break;
13165b382290SLaurent Pinchart 	case V4L2_PIX_FMT_Y12I:		descr = "Interleaved 12-bit Greyscale"; break;
13175b382290SLaurent Pinchart 	case V4L2_PIX_FMT_Z16:		descr = "16-bit Depth"; break;
13185df082e2SEvgeni Raikhel 	case V4L2_PIX_FMT_INZI:		descr = "Planar 10:16 Greyscale Depth"; break;
131992799ef7SSergey Dorodnicov 	case V4L2_PIX_FMT_CNF4:		descr = "4-bit Depth Confidence (Packed)"; break;
1320ba300204SHans Verkuil 	case V4L2_PIX_FMT_PAL8:		descr = "8-bit Palette"; break;
1321ba300204SHans Verkuil 	case V4L2_PIX_FMT_UV8:		descr = "8-bit Chrominance UV 4-4"; break;
1322ba300204SHans Verkuil 	case V4L2_PIX_FMT_YVU410:	descr = "Planar YVU 4:1:0"; break;
1323ba300204SHans Verkuil 	case V4L2_PIX_FMT_YVU420:	descr = "Planar YVU 4:2:0"; break;
1324ba300204SHans Verkuil 	case V4L2_PIX_FMT_YUYV:		descr = "YUYV 4:2:2"; break;
1325ba300204SHans Verkuil 	case V4L2_PIX_FMT_YYUV:		descr = "YYUV 4:2:2"; break;
1326ba300204SHans Verkuil 	case V4L2_PIX_FMT_YVYU:		descr = "YVYU 4:2:2"; break;
1327ba300204SHans Verkuil 	case V4L2_PIX_FMT_UYVY:		descr = "UYVY 4:2:2"; break;
1328ba300204SHans Verkuil 	case V4L2_PIX_FMT_VYUY:		descr = "VYUY 4:2:2"; break;
1329fcbafafbSPhilipp Zabel 	case V4L2_PIX_FMT_YUV422P:	descr = "Planar YUV 4:2:2"; break;
1330ba300204SHans Verkuil 	case V4L2_PIX_FMT_YUV411P:	descr = "Planar YUV 4:1:1"; break;
1331ba300204SHans Verkuil 	case V4L2_PIX_FMT_Y41P:		descr = "YUV 4:1:1 (Packed)"; break;
1332ba300204SHans Verkuil 	case V4L2_PIX_FMT_YUV444:	descr = "16-bit A/XYUV 4-4-4-4"; break;
1333ba300204SHans Verkuil 	case V4L2_PIX_FMT_YUV555:	descr = "16-bit A/XYUV 1-5-5-5"; break;
1334ba300204SHans Verkuil 	case V4L2_PIX_FMT_YUV565:	descr = "16-bit YUV 5-6-5"; break;
13350376a51fSMirela Rabulea 	case V4L2_PIX_FMT_YUV24:	descr = "24-bit YUV 4:4:4 8-8-8"; break;
1336ba300204SHans Verkuil 	case V4L2_PIX_FMT_YUV32:	descr = "32-bit A/XYUV 8-8-8-8"; break;
1337a7fe4ca7SVivek Kasireddy 	case V4L2_PIX_FMT_AYUV32:	descr = "32-bit AYUV 8-8-8-8"; break;
1338a7fe4ca7SVivek Kasireddy 	case V4L2_PIX_FMT_XYUV32:	descr = "32-bit XYUV 8-8-8-8"; break;
1339a7fe4ca7SVivek Kasireddy 	case V4L2_PIX_FMT_VUYA32:	descr = "32-bit VUYA 8-8-8-8"; break;
1340a7fe4ca7SVivek Kasireddy 	case V4L2_PIX_FMT_VUYX32:	descr = "32-bit VUYX 8-8-8-8"; break;
134100f6842eSLaurent Pinchart 	case V4L2_PIX_FMT_YUVA32:	descr = "32-bit YUVA 8-8-8-8"; break;
134200f6842eSLaurent Pinchart 	case V4L2_PIX_FMT_YUVX32:	descr = "32-bit YUVX 8-8-8-8"; break;
1343ba300204SHans Verkuil 	case V4L2_PIX_FMT_YUV410:	descr = "Planar YUV 4:1:0"; break;
1344ba300204SHans Verkuil 	case V4L2_PIX_FMT_YUV420:	descr = "Planar YUV 4:2:0"; break;
1345ba300204SHans Verkuil 	case V4L2_PIX_FMT_HI240:	descr = "8-bit Dithered RGB (BTTV)"; break;
1346ba300204SHans Verkuil 	case V4L2_PIX_FMT_M420:		descr = "YUV 4:2:0 (M420)"; break;
13476a394d56SJernej Skrabec 	case V4L2_PIX_FMT_NV12:		descr = "Y/UV 4:2:0"; break;
13486a394d56SJernej Skrabec 	case V4L2_PIX_FMT_NV21:		descr = "Y/VU 4:2:0"; break;
13496a394d56SJernej Skrabec 	case V4L2_PIX_FMT_NV16:		descr = "Y/UV 4:2:2"; break;
13506a394d56SJernej Skrabec 	case V4L2_PIX_FMT_NV61:		descr = "Y/VU 4:2:2"; break;
13516a394d56SJernej Skrabec 	case V4L2_PIX_FMT_NV24:		descr = "Y/UV 4:4:4"; break;
13526a394d56SJernej Skrabec 	case V4L2_PIX_FMT_NV42:		descr = "Y/VU 4:4:4"; break;
13536a394d56SJernej Skrabec 	case V4L2_PIX_FMT_P010:		descr = "10-bit Y/UV 4:2:0"; break;
13546a394d56SJernej Skrabec 	case V4L2_PIX_FMT_NV12_4L4:	descr = "Y/UV 4:2:0 (4x4 Linear)"; break;
13556a394d56SJernej Skrabec 	case V4L2_PIX_FMT_NV12_16L16:	descr = "Y/UV 4:2:0 (16x16 Linear)"; break;
13566a394d56SJernej Skrabec 	case V4L2_PIX_FMT_NV12_32L32:   descr = "Y/UV 4:2:0 (32x32 Linear)"; break;
13576a394d56SJernej Skrabec 	case V4L2_PIX_FMT_P010_4L4:	descr = "10-bit Y/UV 4:2:0 (4x4 Linear)"; break;
13586a394d56SJernej Skrabec 	case V4L2_PIX_FMT_NV12M:	descr = "Y/UV 4:2:0 (N-C)"; break;
13596a394d56SJernej Skrabec 	case V4L2_PIX_FMT_NV21M:	descr = "Y/VU 4:2:0 (N-C)"; break;
13606a394d56SJernej Skrabec 	case V4L2_PIX_FMT_NV16M:	descr = "Y/UV 4:2:2 (N-C)"; break;
13616a394d56SJernej Skrabec 	case V4L2_PIX_FMT_NV61M:	descr = "Y/VU 4:2:2 (N-C)"; break;
13626a394d56SJernej Skrabec 	case V4L2_PIX_FMT_NV12MT:	descr = "Y/UV 4:2:0 (64x32 MB, N-C)"; break;
13636a394d56SJernej Skrabec 	case V4L2_PIX_FMT_NV12MT_16X16:	descr = "Y/UV 4:2:0 (16x16 MB, N-C)"; break;
1364ba300204SHans Verkuil 	case V4L2_PIX_FMT_YUV420M:	descr = "Planar YUV 4:2:0 (N-C)"; break;
1365ba300204SHans Verkuil 	case V4L2_PIX_FMT_YVU420M:	descr = "Planar YVU 4:2:0 (N-C)"; break;
1366d65fae92SLaurent Pinchart 	case V4L2_PIX_FMT_YUV422M:	descr = "Planar YUV 4:2:2 (N-C)"; break;
1367d65fae92SLaurent Pinchart 	case V4L2_PIX_FMT_YVU422M:	descr = "Planar YVU 4:2:2 (N-C)"; break;
1368d65fae92SLaurent Pinchart 	case V4L2_PIX_FMT_YUV444M:	descr = "Planar YUV 4:4:4 (N-C)"; break;
1369d65fae92SLaurent Pinchart 	case V4L2_PIX_FMT_YVU444M:	descr = "Planar YVU 4:4:4 (N-C)"; break;
1370ba300204SHans Verkuil 	case V4L2_PIX_FMT_SBGGR8:	descr = "8-bit Bayer BGBG/GRGR"; break;
1371ba300204SHans Verkuil 	case V4L2_PIX_FMT_SGBRG8:	descr = "8-bit Bayer GBGB/RGRG"; break;
1372ba300204SHans Verkuil 	case V4L2_PIX_FMT_SGRBG8:	descr = "8-bit Bayer GRGR/BGBG"; break;
1373ba300204SHans Verkuil 	case V4L2_PIX_FMT_SRGGB8:	descr = "8-bit Bayer RGRG/GBGB"; break;
1374ba300204SHans Verkuil 	case V4L2_PIX_FMT_SBGGR10:	descr = "10-bit Bayer BGBG/GRGR"; break;
1375ba300204SHans Verkuil 	case V4L2_PIX_FMT_SGBRG10:	descr = "10-bit Bayer GBGB/RGRG"; break;
1376ba300204SHans Verkuil 	case V4L2_PIX_FMT_SGRBG10:	descr = "10-bit Bayer GRGR/BGBG"; break;
1377ba300204SHans Verkuil 	case V4L2_PIX_FMT_SRGGB10:	descr = "10-bit Bayer RGRG/GBGB"; break;
1378ba300204SHans Verkuil 	case V4L2_PIX_FMT_SBGGR10P:	descr = "10-bit Bayer BGBG/GRGR Packed"; break;
1379ba300204SHans Verkuil 	case V4L2_PIX_FMT_SGBRG10P:	descr = "10-bit Bayer GBGB/RGRG Packed"; break;
1380ba300204SHans Verkuil 	case V4L2_PIX_FMT_SGRBG10P:	descr = "10-bit Bayer GRGR/BGBG Packed"; break;
1381ba300204SHans Verkuil 	case V4L2_PIX_FMT_SRGGB10P:	descr = "10-bit Bayer RGRG/GBGB Packed"; break;
1382e8391b76SYong Zhi 	case V4L2_PIX_FMT_IPU3_SBGGR10: descr = "10-bit bayer BGGR IPU3 Packed"; break;
1383e8391b76SYong Zhi 	case V4L2_PIX_FMT_IPU3_SGBRG10: descr = "10-bit bayer GBRG IPU3 Packed"; break;
1384e8391b76SYong Zhi 	case V4L2_PIX_FMT_IPU3_SGRBG10: descr = "10-bit bayer GRBG IPU3 Packed"; break;
1385e8391b76SYong Zhi 	case V4L2_PIX_FMT_IPU3_SRGGB10: descr = "10-bit bayer RGGB IPU3 Packed"; break;
1386ba300204SHans Verkuil 	case V4L2_PIX_FMT_SBGGR10ALAW8:	descr = "8-bit Bayer BGBG/GRGR (A-law)"; break;
1387ba300204SHans Verkuil 	case V4L2_PIX_FMT_SGBRG10ALAW8:	descr = "8-bit Bayer GBGB/RGRG (A-law)"; break;
1388ba300204SHans Verkuil 	case V4L2_PIX_FMT_SGRBG10ALAW8:	descr = "8-bit Bayer GRGR/BGBG (A-law)"; break;
1389ba300204SHans Verkuil 	case V4L2_PIX_FMT_SRGGB10ALAW8:	descr = "8-bit Bayer RGRG/GBGB (A-law)"; break;
1390ba300204SHans Verkuil 	case V4L2_PIX_FMT_SBGGR10DPCM8:	descr = "8-bit Bayer BGBG/GRGR (DPCM)"; break;
1391ba300204SHans Verkuil 	case V4L2_PIX_FMT_SGBRG10DPCM8:	descr = "8-bit Bayer GBGB/RGRG (DPCM)"; break;
1392ba300204SHans Verkuil 	case V4L2_PIX_FMT_SGRBG10DPCM8:	descr = "8-bit Bayer GRGR/BGBG (DPCM)"; break;
1393ba300204SHans Verkuil 	case V4L2_PIX_FMT_SRGGB10DPCM8:	descr = "8-bit Bayer RGRG/GBGB (DPCM)"; break;
1394d1b3437eSSakari Ailus 	case V4L2_PIX_FMT_SBGGR12:	descr = "12-bit Bayer BGBG/GRGR"; break;
1395d1b3437eSSakari Ailus 	case V4L2_PIX_FMT_SGBRG12:	descr = "12-bit Bayer GBGB/RGRG"; break;
1396d1b3437eSSakari Ailus 	case V4L2_PIX_FMT_SGRBG12:	descr = "12-bit Bayer GRGR/BGBG"; break;
1397d1b3437eSSakari Ailus 	case V4L2_PIX_FMT_SRGGB12:	descr = "12-bit Bayer RGRG/GBGB"; break;
1398d1b3437eSSakari Ailus 	case V4L2_PIX_FMT_SBGGR12P:	descr = "12-bit Bayer BGBG/GRGR Packed"; break;
1399d1b3437eSSakari Ailus 	case V4L2_PIX_FMT_SGBRG12P:	descr = "12-bit Bayer GBGB/RGRG Packed"; break;
1400d1b3437eSSakari Ailus 	case V4L2_PIX_FMT_SGRBG12P:	descr = "12-bit Bayer GRGR/BGBG Packed"; break;
1401d1b3437eSSakari Ailus 	case V4L2_PIX_FMT_SRGGB12P:	descr = "12-bit Bayer RGRG/GBGB Packed"; break;
1402d12127edSSakari Ailus 	case V4L2_PIX_FMT_SBGGR14:	descr = "14-bit Bayer BGBG/GRGR"; break;
1403d12127edSSakari Ailus 	case V4L2_PIX_FMT_SGBRG14:	descr = "14-bit Bayer GBGB/RGRG"; break;
1404d12127edSSakari Ailus 	case V4L2_PIX_FMT_SGRBG14:	descr = "14-bit Bayer GRGR/BGBG"; break;
1405d12127edSSakari Ailus 	case V4L2_PIX_FMT_SRGGB14:	descr = "14-bit Bayer RGRG/GBGB"; break;
140683b15832SSakari Ailus 	case V4L2_PIX_FMT_SBGGR14P:	descr = "14-bit Bayer BGBG/GRGR Packed"; break;
140783b15832SSakari Ailus 	case V4L2_PIX_FMT_SGBRG14P:	descr = "14-bit Bayer GBGB/RGRG Packed"; break;
140883b15832SSakari Ailus 	case V4L2_PIX_FMT_SGRBG14P:	descr = "14-bit Bayer GRGR/BGBG Packed"; break;
140983b15832SSakari Ailus 	case V4L2_PIX_FMT_SRGGB14P:	descr = "14-bit Bayer RGRG/GBGB Packed"; break;
1410b9a4b13cSSakari Ailus 	case V4L2_PIX_FMT_SBGGR16:	descr = "16-bit Bayer BGBG/GRGR"; break;
1411b9a4b13cSSakari Ailus 	case V4L2_PIX_FMT_SGBRG16:	descr = "16-bit Bayer GBGB/RGRG"; break;
1412b9a4b13cSSakari Ailus 	case V4L2_PIX_FMT_SGRBG16:	descr = "16-bit Bayer GRGR/BGBG"; break;
1413b9a4b13cSSakari Ailus 	case V4L2_PIX_FMT_SRGGB16:	descr = "16-bit Bayer RGRG/GBGB"; break;
141499b74277SMauro Carvalho Chehab 	case V4L2_PIX_FMT_SN9C20X_I420:	descr = "GSPCA SN9C20X I420"; break;
1415ba300204SHans Verkuil 	case V4L2_PIX_FMT_SPCA501:	descr = "GSPCA SPCA501"; break;
1416ba300204SHans Verkuil 	case V4L2_PIX_FMT_SPCA505:	descr = "GSPCA SPCA505"; break;
1417ba300204SHans Verkuil 	case V4L2_PIX_FMT_SPCA508:	descr = "GSPCA SPCA508"; break;
1418ba300204SHans Verkuil 	case V4L2_PIX_FMT_STV0680:	descr = "GSPCA STV0680"; break;
1419ba300204SHans Verkuil 	case V4L2_PIX_FMT_TM6000:	descr = "A/V + VBI Mux Packet"; break;
1420ba300204SHans Verkuil 	case V4L2_PIX_FMT_CIT_YYVYUY:	descr = "GSPCA CIT YYVYUY"; break;
1421ba300204SHans Verkuil 	case V4L2_PIX_FMT_KONICA420:	descr = "GSPCA KONICA420"; break;
1422ffe5350cSAlexandre Courbot 	case V4L2_PIX_FMT_MM21:		descr = "Mediatek 8-bit Block Format"; break;
142366b2ab27SRicardo Ribalda Delgado 	case V4L2_PIX_FMT_HSV24:	descr = "24-bit HSV 8-8-8"; break;
142466b2ab27SRicardo Ribalda Delgado 	case V4L2_PIX_FMT_HSV32:	descr = "32-bit XHSV 8-8-8-8"; break;
142548fc10aaSAntti Palosaari 	case V4L2_SDR_FMT_CU8:		descr = "Complex U8"; break;
142648fc10aaSAntti Palosaari 	case V4L2_SDR_FMT_CU16LE:	descr = "Complex U16LE"; break;
1427ba300204SHans Verkuil 	case V4L2_SDR_FMT_CS8:		descr = "Complex S8"; break;
1428ba300204SHans Verkuil 	case V4L2_SDR_FMT_CS14LE:	descr = "Complex S14LE"; break;
1429ba300204SHans Verkuil 	case V4L2_SDR_FMT_RU12LE:	descr = "Real U12LE"; break;
1430c28f2118SRamesh Shanmugasundaram 	case V4L2_SDR_FMT_PCU16BE:	descr = "Planar Complex U16BE"; break;
1431c28f2118SRamesh Shanmugasundaram 	case V4L2_SDR_FMT_PCU18BE:	descr = "Planar Complex U18BE"; break;
1432c28f2118SRamesh Shanmugasundaram 	case V4L2_SDR_FMT_PCU20BE:	descr = "Planar Complex U20BE"; break;
14334747bd0fSHans Verkuil 	case V4L2_TCH_FMT_DELTA_TD16:	descr = "16-bit Signed Deltas"; break;
14344747bd0fSHans Verkuil 	case V4L2_TCH_FMT_DELTA_TD08:	descr = "8-bit Signed Deltas"; break;
14354747bd0fSHans Verkuil 	case V4L2_TCH_FMT_TU16:		descr = "16-bit Unsigned Touch Data"; break;
14364747bd0fSHans Verkuil 	case V4L2_TCH_FMT_TU08:		descr = "8-bit Unsigned Touch Data"; break;
143714d66538SLaurent Pinchart 	case V4L2_META_FMT_VSP1_HGO:	descr = "R-Car VSP1 1-D Histogram"; break;
14385deb1c04SNiklas Söderlund 	case V4L2_META_FMT_VSP1_HGT:	descr = "R-Car VSP1 2-D Histogram"; break;
14394747bd0fSHans Verkuil 	case V4L2_META_FMT_UVC:		descr = "UVC Payload Header Metadata"; break;
14404747bd0fSHans Verkuil 	case V4L2_META_FMT_D4XX:	descr = "Intel D4xx UVC Metadata"; break;
144178892b6bSVandana BN 	case V4L2_META_FMT_VIVID:       descr = "Vivid Metadata"; break;
1442df22026aSShunqian Zheng 	case V4L2_META_FMT_RK_ISP1_PARAMS:	descr = "Rockchip ISP1 3A Parameters"; break;
1443df22026aSShunqian Zheng 	case V4L2_META_FMT_RK_ISP1_STAT_3A:	descr = "Rockchip ISP1 3A Statistics"; break;
14445b8bb216SMing Qian 	case V4L2_PIX_FMT_NV12_8L128:	descr = "NV12 (8x128 Linear)"; break;
144572a74c8fSMing Qian 	case V4L2_PIX_FMT_NV12M_8L128:	descr = "NV12M (8x128 Linear)"; break;
14465b8bb216SMing Qian 	case V4L2_PIX_FMT_NV12_10BE_8L128:	descr = "10-bit NV12 (8x128 Linear, BE)"; break;
144772a74c8fSMing Qian 	case V4L2_PIX_FMT_NV12M_10BE_8L128:	descr = "10-bit NV12M (8x128 Linear, BE)"; break;
1448ba300204SHans Verkuil 
1449ba300204SHans Verkuil 	default:
1450ba300204SHans Verkuil 		/* Compressed formats */
1451ba300204SHans Verkuil 		flags = V4L2_FMT_FLAG_COMPRESSED;
1452ba300204SHans Verkuil 		switch (fmt->pixelformat) {
1453ba300204SHans Verkuil 		/* Max description length mask:	descr = "0123456789012345678901234567890" */
1454ba300204SHans Verkuil 		case V4L2_PIX_FMT_MJPEG:	descr = "Motion-JPEG"; break;
1455ba300204SHans Verkuil 		case V4L2_PIX_FMT_JPEG:		descr = "JFIF JPEG"; break;
1456ba300204SHans Verkuil 		case V4L2_PIX_FMT_DV:		descr = "1394"; break;
1457ba300204SHans Verkuil 		case V4L2_PIX_FMT_MPEG:		descr = "MPEG-1/2/4"; break;
1458ba300204SHans Verkuil 		case V4L2_PIX_FMT_H264:		descr = "H.264"; break;
1459ba300204SHans Verkuil 		case V4L2_PIX_FMT_H264_NO_SC:	descr = "H.264 (No Start Codes)"; break;
1460ba300204SHans Verkuil 		case V4L2_PIX_FMT_H264_MVC:	descr = "H.264 MVC"; break;
14617bb3c32aSEzequiel Garcia 		case V4L2_PIX_FMT_H264_SLICE:	descr = "H.264 Parsed Slice Data"; break;
1462ba300204SHans Verkuil 		case V4L2_PIX_FMT_H263:		descr = "H.263"; break;
1463ba300204SHans Verkuil 		case V4L2_PIX_FMT_MPEG1:	descr = "MPEG-1 ES"; break;
1464ba300204SHans Verkuil 		case V4L2_PIX_FMT_MPEG2:	descr = "MPEG-2 ES"; break;
1465c27bb30eSPaul Kocialkowski 		case V4L2_PIX_FMT_MPEG2_SLICE:	descr = "MPEG-2 Parsed Slice Data"; break;
14664747bd0fSHans Verkuil 		case V4L2_PIX_FMT_MPEG4:	descr = "MPEG-4 Part 2 ES"; break;
1467ba300204SHans Verkuil 		case V4L2_PIX_FMT_XVID:		descr = "Xvid"; break;
1468ba300204SHans Verkuil 		case V4L2_PIX_FMT_VC1_ANNEX_G:	descr = "VC-1 (SMPTE 412M Annex G)"; break;
1469ba300204SHans Verkuil 		case V4L2_PIX_FMT_VC1_ANNEX_L:	descr = "VC-1 (SMPTE 412M Annex L)"; break;
1470ba300204SHans Verkuil 		case V4L2_PIX_FMT_VP8:		descr = "VP8"; break;
1471a57d6acaSPawel Osciak 		case V4L2_PIX_FMT_VP8_FRAME:    descr = "VP8 Frame"; break;
1472fa14a564SWu-Cheng Li 		case V4L2_PIX_FMT_VP9:		descr = "VP9"; break;
1473b88dbe38SAndrzej Pietrasiewicz 		case V4L2_PIX_FMT_VP9_FRAME:    descr = "VP9 Frame"; break;
14741c791727SSmitha T Murthy 		case V4L2_PIX_FMT_HEVC:		descr = "HEVC"; break; /* aka H.265 */
1475256fa392SPaul Kocialkowski 		case V4L2_PIX_FMT_HEVC_SLICE:	descr = "HEVC Parsed Slice Data"; break;
147662c3fce0SHans Verkuil 		case V4L2_PIX_FMT_FWHT:		descr = "FWHT"; break; /* used in vicodec */
1477f05a51b9SHans Verkuil 		case V4L2_PIX_FMT_FWHT_STATELESS:	descr = "FWHT Stateless"; break; /* used in vicodec */
1478ba300204SHans Verkuil 		case V4L2_PIX_FMT_CPIA1:	descr = "GSPCA CPiA YUV"; break;
1479ba300204SHans Verkuil 		case V4L2_PIX_FMT_WNVA:		descr = "WNVA"; break;
1480ba300204SHans Verkuil 		case V4L2_PIX_FMT_SN9C10X:	descr = "GSPCA SN9C10X"; break;
1481ba300204SHans Verkuil 		case V4L2_PIX_FMT_PWC1:		descr = "Raw Philips Webcam Type (Old)"; break;
1482ba300204SHans Verkuil 		case V4L2_PIX_FMT_PWC2:		descr = "Raw Philips Webcam Type (New)"; break;
1483ba300204SHans Verkuil 		case V4L2_PIX_FMT_ET61X251:	descr = "GSPCA ET61X251"; break;
1484ba300204SHans Verkuil 		case V4L2_PIX_FMT_SPCA561:	descr = "GSPCA SPCA561"; break;
1485ba300204SHans Verkuil 		case V4L2_PIX_FMT_PAC207:	descr = "GSPCA PAC207"; break;
1486ba300204SHans Verkuil 		case V4L2_PIX_FMT_MR97310A:	descr = "GSPCA MR97310A"; break;
1487ba300204SHans Verkuil 		case V4L2_PIX_FMT_JL2005BCD:	descr = "GSPCA JL2005BCD"; break;
1488ba300204SHans Verkuil 		case V4L2_PIX_FMT_SN9C2028:	descr = "GSPCA SN9C2028"; break;
1489ba300204SHans Verkuil 		case V4L2_PIX_FMT_SQ905C:	descr = "GSPCA SQ905C"; break;
1490ba300204SHans Verkuil 		case V4L2_PIX_FMT_PJPG:		descr = "GSPCA PJPG"; break;
1491ba300204SHans Verkuil 		case V4L2_PIX_FMT_OV511:	descr = "GSPCA OV511"; break;
1492ba300204SHans Verkuil 		case V4L2_PIX_FMT_OV518:	descr = "GSPCA OV518"; break;
1493ba300204SHans Verkuil 		case V4L2_PIX_FMT_JPGL:		descr = "JPEG Lite"; break;
1494ba300204SHans Verkuil 		case V4L2_PIX_FMT_SE401:	descr = "GSPCA SE401"; break;
1495ba300204SHans Verkuil 		case V4L2_PIX_FMT_S5C_UYVY_JPG:	descr = "S5C73MX interleaved UYVY/JPEG"; break;
1496d4de6634STiffany Lin 		case V4L2_PIX_FMT_MT21C:	descr = "Mediatek Compressed Format"; break;
14972308d5afSStanimir Varbanov 		case V4L2_PIX_FMT_QC08C:	descr = "QCOM Compressed 8-bit Format"; break;
14982308d5afSStanimir Varbanov 		case V4L2_PIX_FMT_QC10C:	descr = "QCOM Compressed 10-bit Format"; break;
14997a4b3770SJammy Huang 		case V4L2_PIX_FMT_AJPG:		descr = "Aspeed JPEG"; break;
1500ba300204SHans Verkuil 		default:
1501ba300204SHans Verkuil 			if (fmt->description[0])
1502ba300204SHans Verkuil 				return;
1503c2286cc0SSakari Ailus 			WARN(1, "Unknown pixelformat 0x%08x\n", fmt->pixelformat);
1504ba300204SHans Verkuil 			flags = 0;
1505e927e1e0SSakari Ailus 			snprintf(fmt->description, sz, "%p4cc",
1506e927e1e0SSakari Ailus 				 &fmt->pixelformat);
1507ba300204SHans Verkuil 			break;
1508ba300204SHans Verkuil 		}
1509ba300204SHans Verkuil 	}
1510ba300204SHans Verkuil 
1511ba300204SHans Verkuil 	if (descr)
1512e7dd89ceSHans Petter Selasky 		WARN_ON(strscpy(fmt->description, descr, sz) < 0);
15137c490e25SHans Verkuil 	fmt->flags |= flags;
1514ba300204SHans Verkuil }
1515ba300204SHans Verkuil 
15165bc3cb74SMauro Carvalho Chehab static int v4l_enum_fmt(const struct v4l2_ioctl_ops *ops,
15175bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
15185bc3cb74SMauro Carvalho Chehab {
15197e98b7b5SBoris Brezillon 	struct video_device *vdev = video_devdata(file);
15205bc3cb74SMauro Carvalho Chehab 	struct v4l2_fmtdesc *p = arg;
1521b2469c81SHans Verkuil 	int ret = check_fmt(file, p->type);
1522e5b6b07aSLaurent Pinchart 	u32 mbus_code;
1523f0d2b7a8SBoris Brezillon 	u32 cap_mask;
1524b2469c81SHans Verkuil 
1525b2469c81SHans Verkuil 	if (ret)
1526b2469c81SHans Verkuil 		return ret;
1527b2469c81SHans Verkuil 	ret = -EINVAL;
15285bc3cb74SMauro Carvalho Chehab 
1529e5b6b07aSLaurent Pinchart 	if (!(vdev->device_caps & V4L2_CAP_IO_MC))
1530e5b6b07aSLaurent Pinchart 		p->mbus_code = 0;
1531e5b6b07aSLaurent Pinchart 
1532e5b6b07aSLaurent Pinchart 	mbus_code = p->mbus_code;
15330625b6b8SXiu Jianfeng 	memset_after(p, 0, type);
1534e5b6b07aSLaurent Pinchart 	p->mbus_code = mbus_code;
1535e5b6b07aSLaurent Pinchart 
15365bc3cb74SMauro Carvalho Chehab 	switch (p->type) {
15375bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_CAPTURE:
15387e98b7b5SBoris Brezillon 	case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
1539f0d2b7a8SBoris Brezillon 		cap_mask = V4L2_CAP_VIDEO_CAPTURE_MPLANE |
1540f0d2b7a8SBoris Brezillon 			   V4L2_CAP_VIDEO_M2M_MPLANE;
1541f0d2b7a8SBoris Brezillon 		if (!!(vdev->device_caps & cap_mask) !=
15427e98b7b5SBoris Brezillon 		    (p->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE))
15437e98b7b5SBoris Brezillon 			break;
15447e98b7b5SBoris Brezillon 
1545b2469c81SHans Verkuil 		if (unlikely(!ops->vidioc_enum_fmt_vid_cap))
15465bc3cb74SMauro Carvalho Chehab 			break;
1547ba300204SHans Verkuil 		ret = ops->vidioc_enum_fmt_vid_cap(file, fh, arg);
1548ba300204SHans Verkuil 		break;
15495bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_OVERLAY:
1550b2469c81SHans Verkuil 		if (unlikely(!ops->vidioc_enum_fmt_vid_overlay))
15515bc3cb74SMauro Carvalho Chehab 			break;
1552ba300204SHans Verkuil 		ret = ops->vidioc_enum_fmt_vid_overlay(file, fh, arg);
1553ba300204SHans Verkuil 		break;
15545bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_OUTPUT:
15557e98b7b5SBoris Brezillon 	case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
1556f0d2b7a8SBoris Brezillon 		cap_mask = V4L2_CAP_VIDEO_OUTPUT_MPLANE |
1557f0d2b7a8SBoris Brezillon 			   V4L2_CAP_VIDEO_M2M_MPLANE;
1558f0d2b7a8SBoris Brezillon 		if (!!(vdev->device_caps & cap_mask) !=
15597e98b7b5SBoris Brezillon 		    (p->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE))
15607e98b7b5SBoris Brezillon 			break;
15617e98b7b5SBoris Brezillon 
1562b2469c81SHans Verkuil 		if (unlikely(!ops->vidioc_enum_fmt_vid_out))
15635bc3cb74SMauro Carvalho Chehab 			break;
1564ba300204SHans Verkuil 		ret = ops->vidioc_enum_fmt_vid_out(file, fh, arg);
1565ba300204SHans Verkuil 		break;
1566582c52cbSAntti Palosaari 	case V4L2_BUF_TYPE_SDR_CAPTURE:
1567b2469c81SHans Verkuil 		if (unlikely(!ops->vidioc_enum_fmt_sdr_cap))
1568582c52cbSAntti Palosaari 			break;
1569ba300204SHans Verkuil 		ret = ops->vidioc_enum_fmt_sdr_cap(file, fh, arg);
1570ba300204SHans Verkuil 		break;
15719effc72fSAntti Palosaari 	case V4L2_BUF_TYPE_SDR_OUTPUT:
1572b2469c81SHans Verkuil 		if (unlikely(!ops->vidioc_enum_fmt_sdr_out))
15739effc72fSAntti Palosaari 			break;
15749effc72fSAntti Palosaari 		ret = ops->vidioc_enum_fmt_sdr_out(file, fh, arg);
15759effc72fSAntti Palosaari 		break;
1576fb9ffa6aSLaurent Pinchart 	case V4L2_BUF_TYPE_META_CAPTURE:
1577b2469c81SHans Verkuil 		if (unlikely(!ops->vidioc_enum_fmt_meta_cap))
1578fb9ffa6aSLaurent Pinchart 			break;
1579fb9ffa6aSLaurent Pinchart 		ret = ops->vidioc_enum_fmt_meta_cap(file, fh, arg);
1580fb9ffa6aSLaurent Pinchart 		break;
158172148d1aSSakari Ailus 	case V4L2_BUF_TYPE_META_OUTPUT:
158272148d1aSSakari Ailus 		if (unlikely(!ops->vidioc_enum_fmt_meta_out))
158372148d1aSSakari Ailus 			break;
158472148d1aSSakari Ailus 		ret = ops->vidioc_enum_fmt_meta_out(file, fh, arg);
158572148d1aSSakari Ailus 		break;
15865bc3cb74SMauro Carvalho Chehab 	}
1587ba300204SHans Verkuil 	if (ret == 0)
1588ba300204SHans Verkuil 		v4l_fill_fmtdesc(p);
1589ba300204SHans Verkuil 	return ret;
15905bc3cb74SMauro Carvalho Chehab }
15915bc3cb74SMauro Carvalho Chehab 
1592545b618cSVandana BN static void v4l_pix_format_touch(struct v4l2_pix_format *p)
1593545b618cSVandana BN {
1594545b618cSVandana BN 	/*
1595545b618cSVandana BN 	 * The v4l2_pix_format structure contains fields that make no sense for
1596545b618cSVandana BN 	 * touch. Set them to default values in this case.
1597545b618cSVandana BN 	 */
1598545b618cSVandana BN 
1599545b618cSVandana BN 	p->field = V4L2_FIELD_NONE;
1600545b618cSVandana BN 	p->colorspace = V4L2_COLORSPACE_RAW;
1601545b618cSVandana BN 	p->flags = 0;
1602545b618cSVandana BN 	p->ycbcr_enc = 0;
1603545b618cSVandana BN 	p->quantization = 0;
1604545b618cSVandana BN 	p->xfer_func = 0;
1605545b618cSVandana BN }
1606545b618cSVandana BN 
16075bc3cb74SMauro Carvalho Chehab static int v4l_g_fmt(const struct v4l2_ioctl_ops *ops,
16085bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
16095bc3cb74SMauro Carvalho Chehab {
16105bc3cb74SMauro Carvalho Chehab 	struct v4l2_format *p = arg;
1611545b618cSVandana BN 	struct video_device *vfd = video_devdata(file);
1612b2469c81SHans Verkuil 	int ret = check_fmt(file, p->type);
1613b2469c81SHans Verkuil 
1614b2469c81SHans Verkuil 	if (ret)
1615b2469c81SHans Verkuil 		return ret;
1616d52e2381SLaurent Pinchart 
1617e5ce558aSHans Verkuil 	/*
1618e5ce558aSHans Verkuil 	 * fmt can't be cleared for these overlay types due to the 'clips'
1619e5ce558aSHans Verkuil 	 * 'clipcount' and 'bitmap' pointers in struct v4l2_window.
1620e5ce558aSHans Verkuil 	 * Those are provided by the user. So handle these two overlay types
1621e5ce558aSHans Verkuil 	 * first, and then just do a simple memset for the other types.
1622e5ce558aSHans Verkuil 	 */
1623e5ce558aSHans Verkuil 	switch (p->type) {
1624e5ce558aSHans Verkuil 	case V4L2_BUF_TYPE_VIDEO_OVERLAY:
1625e5ce558aSHans Verkuil 	case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY: {
16263f65c6f6SArnd Bergmann 		struct v4l2_clip *clips = p->fmt.win.clips;
1627e5ce558aSHans Verkuil 		u32 clipcount = p->fmt.win.clipcount;
16284d1afa51SHans Verkuil 		void __user *bitmap = p->fmt.win.bitmap;
1629e5ce558aSHans Verkuil 
1630e5ce558aSHans Verkuil 		memset(&p->fmt, 0, sizeof(p->fmt));
1631e5ce558aSHans Verkuil 		p->fmt.win.clips = clips;
1632e5ce558aSHans Verkuil 		p->fmt.win.clipcount = clipcount;
1633e5ce558aSHans Verkuil 		p->fmt.win.bitmap = bitmap;
1634e5ce558aSHans Verkuil 		break;
1635e5ce558aSHans Verkuil 	}
1636e5ce558aSHans Verkuil 	default:
1637e5ce558aSHans Verkuil 		memset(&p->fmt, 0, sizeof(p->fmt));
1638e5ce558aSHans Verkuil 		break;
1639e5ce558aSHans Verkuil 	}
1640e5ce558aSHans Verkuil 
16415bc3cb74SMauro Carvalho Chehab 	switch (p->type) {
16425bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_CAPTURE:
1643b2469c81SHans Verkuil 		if (unlikely(!ops->vidioc_g_fmt_vid_cap))
16445bc3cb74SMauro Carvalho Chehab 			break;
164548f2650aSHans Verkuil 		p->fmt.pix.priv = V4L2_PIX_FMT_PRIV_MAGIC;
1646d52e2381SLaurent Pinchart 		ret = ops->vidioc_g_fmt_vid_cap(file, fh, arg);
164748f2650aSHans Verkuil 		/* just in case the driver zeroed it again */
1648d52e2381SLaurent Pinchart 		p->fmt.pix.priv = V4L2_PIX_FMT_PRIV_MAGIC;
1649545b618cSVandana BN 		if (vfd->vfl_type == VFL_TYPE_TOUCH)
1650545b618cSVandana BN 			v4l_pix_format_touch(&p->fmt.pix);
1651d52e2381SLaurent Pinchart 		return ret;
16525bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
16535bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_g_fmt_vid_cap_mplane(file, fh, arg);
16545bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_OVERLAY:
16555bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_g_fmt_vid_overlay(file, fh, arg);
16564b20259fSHans Verkuil 	case V4L2_BUF_TYPE_VBI_CAPTURE:
16574b20259fSHans Verkuil 		return ops->vidioc_g_fmt_vbi_cap(file, fh, arg);
16584b20259fSHans Verkuil 	case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
16594b20259fSHans Verkuil 		return ops->vidioc_g_fmt_sliced_vbi_cap(file, fh, arg);
16605bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_OUTPUT:
1661b2469c81SHans Verkuil 		if (unlikely(!ops->vidioc_g_fmt_vid_out))
16625bc3cb74SMauro Carvalho Chehab 			break;
166348f2650aSHans Verkuil 		p->fmt.pix.priv = V4L2_PIX_FMT_PRIV_MAGIC;
1664d52e2381SLaurent Pinchart 		ret = ops->vidioc_g_fmt_vid_out(file, fh, arg);
166548f2650aSHans Verkuil 		/* just in case the driver zeroed it again */
1666d52e2381SLaurent Pinchart 		p->fmt.pix.priv = V4L2_PIX_FMT_PRIV_MAGIC;
1667d52e2381SLaurent Pinchart 		return ret;
16685bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
16695bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_g_fmt_vid_out_mplane(file, fh, arg);
16705bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
16715bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_g_fmt_vid_out_overlay(file, fh, arg);
16725bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VBI_OUTPUT:
16735bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_g_fmt_vbi_out(file, fh, arg);
16745bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
16755bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_g_fmt_sliced_vbi_out(file, fh, arg);
1676582c52cbSAntti Palosaari 	case V4L2_BUF_TYPE_SDR_CAPTURE:
1677582c52cbSAntti Palosaari 		return ops->vidioc_g_fmt_sdr_cap(file, fh, arg);
16789effc72fSAntti Palosaari 	case V4L2_BUF_TYPE_SDR_OUTPUT:
16799effc72fSAntti Palosaari 		return ops->vidioc_g_fmt_sdr_out(file, fh, arg);
1680fb9ffa6aSLaurent Pinchart 	case V4L2_BUF_TYPE_META_CAPTURE:
1681fb9ffa6aSLaurent Pinchart 		return ops->vidioc_g_fmt_meta_cap(file, fh, arg);
168272148d1aSSakari Ailus 	case V4L2_BUF_TYPE_META_OUTPUT:
168372148d1aSSakari Ailus 		return ops->vidioc_g_fmt_meta_out(file, fh, arg);
16845bc3cb74SMauro Carvalho Chehab 	}
16855bc3cb74SMauro Carvalho Chehab 	return -EINVAL;
16865bc3cb74SMauro Carvalho Chehab }
16875bc3cb74SMauro Carvalho Chehab 
16885bc3cb74SMauro Carvalho Chehab static int v4l_s_fmt(const struct v4l2_ioctl_ops *ops,
16895bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
16905bc3cb74SMauro Carvalho Chehab {
16915bc3cb74SMauro Carvalho Chehab 	struct v4l2_format *p = arg;
16924b20259fSHans Verkuil 	struct video_device *vfd = video_devdata(file);
1693b2469c81SHans Verkuil 	int ret = check_fmt(file, p->type);
16944e1e0eb0SEzequiel Garcia 	unsigned int i;
1695b2469c81SHans Verkuil 
1696b2469c81SHans Verkuil 	if (ret)
1697b2469c81SHans Verkuil 		return ret;
16985bc3cb74SMauro Carvalho Chehab 
169977fa4e07SShuah Khan 	ret = v4l_enable_media_source(vfd);
170077fa4e07SShuah Khan 	if (ret)
170177fa4e07SShuah Khan 		return ret;
1702d52e2381SLaurent Pinchart 	v4l_sanitize_format(p);
1703d52e2381SLaurent Pinchart 
17045bc3cb74SMauro Carvalho Chehab 	switch (p->type) {
17055bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_CAPTURE:
1706b2469c81SHans Verkuil 		if (unlikely(!ops->vidioc_s_fmt_vid_cap))
17075bc3cb74SMauro Carvalho Chehab 			break;
17080625b6b8SXiu Jianfeng 		memset_after(p, 0, fmt.pix);
170948f2650aSHans Verkuil 		ret = ops->vidioc_s_fmt_vid_cap(file, fh, arg);
171048f2650aSHans Verkuil 		/* just in case the driver zeroed it again */
171148f2650aSHans Verkuil 		p->fmt.pix.priv = V4L2_PIX_FMT_PRIV_MAGIC;
1712b2469c81SHans Verkuil 		if (vfd->vfl_type == VFL_TYPE_TOUCH)
1713b2fe22d0SNick Dyer 			v4l_pix_format_touch(&p->fmt.pix);
171448f2650aSHans Verkuil 		return ret;
17155bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
1716b2469c81SHans Verkuil 		if (unlikely(!ops->vidioc_s_fmt_vid_cap_mplane))
17175bc3cb74SMauro Carvalho Chehab 			break;
17180625b6b8SXiu Jianfeng 		memset_after(p, 0, fmt.pix_mp.xfer_func);
17194e1e0eb0SEzequiel Garcia 		for (i = 0; i < p->fmt.pix_mp.num_planes; i++)
17200625b6b8SXiu Jianfeng 			memset_after(&p->fmt.pix_mp.plane_fmt[i],
17210625b6b8SXiu Jianfeng 				     0, bytesperline);
17225bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_s_fmt_vid_cap_mplane(file, fh, arg);
17235bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_OVERLAY:
1724b2469c81SHans Verkuil 		if (unlikely(!ops->vidioc_s_fmt_vid_overlay))
17255bc3cb74SMauro Carvalho Chehab 			break;
17260625b6b8SXiu Jianfeng 		memset_after(p, 0, fmt.win);
17275bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_s_fmt_vid_overlay(file, fh, arg);
17284b20259fSHans Verkuil 	case V4L2_BUF_TYPE_VBI_CAPTURE:
1729b2469c81SHans Verkuil 		if (unlikely(!ops->vidioc_s_fmt_vbi_cap))
17304b20259fSHans Verkuil 			break;
17310625b6b8SXiu Jianfeng 		memset_after(p, 0, fmt.vbi.flags);
17324b20259fSHans Verkuil 		return ops->vidioc_s_fmt_vbi_cap(file, fh, arg);
17334b20259fSHans Verkuil 	case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
1734b2469c81SHans Verkuil 		if (unlikely(!ops->vidioc_s_fmt_sliced_vbi_cap))
17354b20259fSHans Verkuil 			break;
17360625b6b8SXiu Jianfeng 		memset_after(p, 0, fmt.sliced.io_size);
17374b20259fSHans Verkuil 		return ops->vidioc_s_fmt_sliced_vbi_cap(file, fh, arg);
17385bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_OUTPUT:
1739b2469c81SHans Verkuil 		if (unlikely(!ops->vidioc_s_fmt_vid_out))
17405bc3cb74SMauro Carvalho Chehab 			break;
17410625b6b8SXiu Jianfeng 		memset_after(p, 0, fmt.pix);
174248f2650aSHans Verkuil 		ret = ops->vidioc_s_fmt_vid_out(file, fh, arg);
174348f2650aSHans Verkuil 		/* just in case the driver zeroed it again */
174448f2650aSHans Verkuil 		p->fmt.pix.priv = V4L2_PIX_FMT_PRIV_MAGIC;
174548f2650aSHans Verkuil 		return ret;
17465bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
1747b2469c81SHans Verkuil 		if (unlikely(!ops->vidioc_s_fmt_vid_out_mplane))
17485bc3cb74SMauro Carvalho Chehab 			break;
17490625b6b8SXiu Jianfeng 		memset_after(p, 0, fmt.pix_mp.xfer_func);
17504e1e0eb0SEzequiel Garcia 		for (i = 0; i < p->fmt.pix_mp.num_planes; i++)
17510625b6b8SXiu Jianfeng 			memset_after(&p->fmt.pix_mp.plane_fmt[i],
17520625b6b8SXiu Jianfeng 				     0, bytesperline);
17535bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_s_fmt_vid_out_mplane(file, fh, arg);
17545bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
1755b2469c81SHans Verkuil 		if (unlikely(!ops->vidioc_s_fmt_vid_out_overlay))
17565bc3cb74SMauro Carvalho Chehab 			break;
17570625b6b8SXiu Jianfeng 		memset_after(p, 0, fmt.win);
17585bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_s_fmt_vid_out_overlay(file, fh, arg);
17595bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VBI_OUTPUT:
1760b2469c81SHans Verkuil 		if (unlikely(!ops->vidioc_s_fmt_vbi_out))
17615bc3cb74SMauro Carvalho Chehab 			break;
17620625b6b8SXiu Jianfeng 		memset_after(p, 0, fmt.vbi.flags);
17635bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_s_fmt_vbi_out(file, fh, arg);
17645bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
1765b2469c81SHans Verkuil 		if (unlikely(!ops->vidioc_s_fmt_sliced_vbi_out))
17665bc3cb74SMauro Carvalho Chehab 			break;
17670625b6b8SXiu Jianfeng 		memset_after(p, 0, fmt.sliced.io_size);
17685bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_s_fmt_sliced_vbi_out(file, fh, arg);
1769582c52cbSAntti Palosaari 	case V4L2_BUF_TYPE_SDR_CAPTURE:
1770b2469c81SHans Verkuil 		if (unlikely(!ops->vidioc_s_fmt_sdr_cap))
1771582c52cbSAntti Palosaari 			break;
17720625b6b8SXiu Jianfeng 		memset_after(p, 0, fmt.sdr.buffersize);
1773582c52cbSAntti Palosaari 		return ops->vidioc_s_fmt_sdr_cap(file, fh, arg);
17749effc72fSAntti Palosaari 	case V4L2_BUF_TYPE_SDR_OUTPUT:
1775b2469c81SHans Verkuil 		if (unlikely(!ops->vidioc_s_fmt_sdr_out))
17769effc72fSAntti Palosaari 			break;
17770625b6b8SXiu Jianfeng 		memset_after(p, 0, fmt.sdr.buffersize);
17789effc72fSAntti Palosaari 		return ops->vidioc_s_fmt_sdr_out(file, fh, arg);
1779fb9ffa6aSLaurent Pinchart 	case V4L2_BUF_TYPE_META_CAPTURE:
1780b2469c81SHans Verkuil 		if (unlikely(!ops->vidioc_s_fmt_meta_cap))
1781fb9ffa6aSLaurent Pinchart 			break;
17820625b6b8SXiu Jianfeng 		memset_after(p, 0, fmt.meta);
1783fb9ffa6aSLaurent Pinchart 		return ops->vidioc_s_fmt_meta_cap(file, fh, arg);
178472148d1aSSakari Ailus 	case V4L2_BUF_TYPE_META_OUTPUT:
178572148d1aSSakari Ailus 		if (unlikely(!ops->vidioc_s_fmt_meta_out))
178672148d1aSSakari Ailus 			break;
17870625b6b8SXiu Jianfeng 		memset_after(p, 0, fmt.meta);
178872148d1aSSakari Ailus 		return ops->vidioc_s_fmt_meta_out(file, fh, arg);
17895bc3cb74SMauro Carvalho Chehab 	}
17905bc3cb74SMauro Carvalho Chehab 	return -EINVAL;
17915bc3cb74SMauro Carvalho Chehab }
17925bc3cb74SMauro Carvalho Chehab 
17935bc3cb74SMauro Carvalho Chehab static int v4l_try_fmt(const struct v4l2_ioctl_ops *ops,
17945bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
17955bc3cb74SMauro Carvalho Chehab {
17965bc3cb74SMauro Carvalho Chehab 	struct v4l2_format *p = arg;
1797999a4312SHans Verkuil 	struct video_device *vfd = video_devdata(file);
1798b2469c81SHans Verkuil 	int ret = check_fmt(file, p->type);
17994e1e0eb0SEzequiel Garcia 	unsigned int i;
1800b2469c81SHans Verkuil 
1801b2469c81SHans Verkuil 	if (ret)
1802b2469c81SHans Verkuil 		return ret;
18035bc3cb74SMauro Carvalho Chehab 
1804d52e2381SLaurent Pinchart 	v4l_sanitize_format(p);
1805d52e2381SLaurent Pinchart 
18065bc3cb74SMauro Carvalho Chehab 	switch (p->type) {
18075bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_CAPTURE:
1808b2469c81SHans Verkuil 		if (unlikely(!ops->vidioc_try_fmt_vid_cap))
18095bc3cb74SMauro Carvalho Chehab 			break;
18100625b6b8SXiu Jianfeng 		memset_after(p, 0, fmt.pix);
181148f2650aSHans Verkuil 		ret = ops->vidioc_try_fmt_vid_cap(file, fh, arg);
181248f2650aSHans Verkuil 		/* just in case the driver zeroed it again */
181348f2650aSHans Verkuil 		p->fmt.pix.priv = V4L2_PIX_FMT_PRIV_MAGIC;
1814999a4312SHans Verkuil 		if (vfd->vfl_type == VFL_TYPE_TOUCH)
1815999a4312SHans Verkuil 			v4l_pix_format_touch(&p->fmt.pix);
181648f2650aSHans Verkuil 		return ret;
18175bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
1818b2469c81SHans Verkuil 		if (unlikely(!ops->vidioc_try_fmt_vid_cap_mplane))
18195bc3cb74SMauro Carvalho Chehab 			break;
18200625b6b8SXiu Jianfeng 		memset_after(p, 0, fmt.pix_mp.xfer_func);
18214e1e0eb0SEzequiel Garcia 		for (i = 0; i < p->fmt.pix_mp.num_planes; i++)
18220625b6b8SXiu Jianfeng 			memset_after(&p->fmt.pix_mp.plane_fmt[i],
18230625b6b8SXiu Jianfeng 				     0, bytesperline);
18245bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_try_fmt_vid_cap_mplane(file, fh, arg);
18255bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_OVERLAY:
1826b2469c81SHans Verkuil 		if (unlikely(!ops->vidioc_try_fmt_vid_overlay))
18275bc3cb74SMauro Carvalho Chehab 			break;
18280625b6b8SXiu Jianfeng 		memset_after(p, 0, fmt.win);
18295bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_try_fmt_vid_overlay(file, fh, arg);
18304b20259fSHans Verkuil 	case V4L2_BUF_TYPE_VBI_CAPTURE:
1831b2469c81SHans Verkuil 		if (unlikely(!ops->vidioc_try_fmt_vbi_cap))
18324b20259fSHans Verkuil 			break;
18330625b6b8SXiu Jianfeng 		memset_after(p, 0, fmt.vbi.flags);
18344b20259fSHans Verkuil 		return ops->vidioc_try_fmt_vbi_cap(file, fh, arg);
18354b20259fSHans Verkuil 	case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
1836b2469c81SHans Verkuil 		if (unlikely(!ops->vidioc_try_fmt_sliced_vbi_cap))
18374b20259fSHans Verkuil 			break;
18380625b6b8SXiu Jianfeng 		memset_after(p, 0, fmt.sliced.io_size);
18394b20259fSHans Verkuil 		return ops->vidioc_try_fmt_sliced_vbi_cap(file, fh, arg);
18405bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_OUTPUT:
1841b2469c81SHans Verkuil 		if (unlikely(!ops->vidioc_try_fmt_vid_out))
18425bc3cb74SMauro Carvalho Chehab 			break;
18430625b6b8SXiu Jianfeng 		memset_after(p, 0, fmt.pix);
184448f2650aSHans Verkuil 		ret = ops->vidioc_try_fmt_vid_out(file, fh, arg);
184548f2650aSHans Verkuil 		/* just in case the driver zeroed it again */
184648f2650aSHans Verkuil 		p->fmt.pix.priv = V4L2_PIX_FMT_PRIV_MAGIC;
184748f2650aSHans Verkuil 		return ret;
18485bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
1849b2469c81SHans Verkuil 		if (unlikely(!ops->vidioc_try_fmt_vid_out_mplane))
18505bc3cb74SMauro Carvalho Chehab 			break;
18510625b6b8SXiu Jianfeng 		memset_after(p, 0, fmt.pix_mp.xfer_func);
18524e1e0eb0SEzequiel Garcia 		for (i = 0; i < p->fmt.pix_mp.num_planes; i++)
18530625b6b8SXiu Jianfeng 			memset_after(&p->fmt.pix_mp.plane_fmt[i],
18540625b6b8SXiu Jianfeng 				     0, bytesperline);
18555bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_try_fmt_vid_out_mplane(file, fh, arg);
18565bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
1857b2469c81SHans Verkuil 		if (unlikely(!ops->vidioc_try_fmt_vid_out_overlay))
18585bc3cb74SMauro Carvalho Chehab 			break;
18590625b6b8SXiu Jianfeng 		memset_after(p, 0, fmt.win);
18605bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_try_fmt_vid_out_overlay(file, fh, arg);
18615bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VBI_OUTPUT:
1862b2469c81SHans Verkuil 		if (unlikely(!ops->vidioc_try_fmt_vbi_out))
18635bc3cb74SMauro Carvalho Chehab 			break;
18640625b6b8SXiu Jianfeng 		memset_after(p, 0, fmt.vbi.flags);
18655bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_try_fmt_vbi_out(file, fh, arg);
18665bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
1867b2469c81SHans Verkuil 		if (unlikely(!ops->vidioc_try_fmt_sliced_vbi_out))
18685bc3cb74SMauro Carvalho Chehab 			break;
18690625b6b8SXiu Jianfeng 		memset_after(p, 0, fmt.sliced.io_size);
18705bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_try_fmt_sliced_vbi_out(file, fh, arg);
1871582c52cbSAntti Palosaari 	case V4L2_BUF_TYPE_SDR_CAPTURE:
1872b2469c81SHans Verkuil 		if (unlikely(!ops->vidioc_try_fmt_sdr_cap))
1873582c52cbSAntti Palosaari 			break;
18740625b6b8SXiu Jianfeng 		memset_after(p, 0, fmt.sdr.buffersize);
1875582c52cbSAntti Palosaari 		return ops->vidioc_try_fmt_sdr_cap(file, fh, arg);
18769effc72fSAntti Palosaari 	case V4L2_BUF_TYPE_SDR_OUTPUT:
1877b2469c81SHans Verkuil 		if (unlikely(!ops->vidioc_try_fmt_sdr_out))
18789effc72fSAntti Palosaari 			break;
18790625b6b8SXiu Jianfeng 		memset_after(p, 0, fmt.sdr.buffersize);
18809effc72fSAntti Palosaari 		return ops->vidioc_try_fmt_sdr_out(file, fh, arg);
1881fb9ffa6aSLaurent Pinchart 	case V4L2_BUF_TYPE_META_CAPTURE:
1882b2469c81SHans Verkuil 		if (unlikely(!ops->vidioc_try_fmt_meta_cap))
1883fb9ffa6aSLaurent Pinchart 			break;
18840625b6b8SXiu Jianfeng 		memset_after(p, 0, fmt.meta);
1885fb9ffa6aSLaurent Pinchart 		return ops->vidioc_try_fmt_meta_cap(file, fh, arg);
188672148d1aSSakari Ailus 	case V4L2_BUF_TYPE_META_OUTPUT:
188772148d1aSSakari Ailus 		if (unlikely(!ops->vidioc_try_fmt_meta_out))
188872148d1aSSakari Ailus 			break;
18890625b6b8SXiu Jianfeng 		memset_after(p, 0, fmt.meta);
189072148d1aSSakari Ailus 		return ops->vidioc_try_fmt_meta_out(file, fh, arg);
18915bc3cb74SMauro Carvalho Chehab 	}
18925bc3cb74SMauro Carvalho Chehab 	return -EINVAL;
18935bc3cb74SMauro Carvalho Chehab }
18945bc3cb74SMauro Carvalho Chehab 
18955bc3cb74SMauro Carvalho Chehab static int v4l_streamon(const struct v4l2_ioctl_ops *ops,
18965bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
18975bc3cb74SMauro Carvalho Chehab {
18985bc3cb74SMauro Carvalho Chehab 	return ops->vidioc_streamon(file, fh, *(unsigned int *)arg);
18995bc3cb74SMauro Carvalho Chehab }
19005bc3cb74SMauro Carvalho Chehab 
19015bc3cb74SMauro Carvalho Chehab static int v4l_streamoff(const struct v4l2_ioctl_ops *ops,
19025bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
19035bc3cb74SMauro Carvalho Chehab {
19045bc3cb74SMauro Carvalho Chehab 	return ops->vidioc_streamoff(file, fh, *(unsigned int *)arg);
19055bc3cb74SMauro Carvalho Chehab }
19065bc3cb74SMauro Carvalho Chehab 
19075bc3cb74SMauro Carvalho Chehab static int v4l_g_tuner(const struct v4l2_ioctl_ops *ops,
19085bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
19095bc3cb74SMauro Carvalho Chehab {
19105bc3cb74SMauro Carvalho Chehab 	struct video_device *vfd = video_devdata(file);
19115bc3cb74SMauro Carvalho Chehab 	struct v4l2_tuner *p = arg;
19125bc3cb74SMauro Carvalho Chehab 	int err;
19135bc3cb74SMauro Carvalho Chehab 
19145bc3cb74SMauro Carvalho Chehab 	p->type = (vfd->vfl_type == VFL_TYPE_RADIO) ?
19155bc3cb74SMauro Carvalho Chehab 			V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV;
19165bc3cb74SMauro Carvalho Chehab 	err = ops->vidioc_g_tuner(file, fh, p);
19175bc3cb74SMauro Carvalho Chehab 	if (!err)
19185bc3cb74SMauro Carvalho Chehab 		p->capability |= V4L2_TUNER_CAP_FREQ_BANDS;
19195bc3cb74SMauro Carvalho Chehab 	return err;
19205bc3cb74SMauro Carvalho Chehab }
19215bc3cb74SMauro Carvalho Chehab 
19225bc3cb74SMauro Carvalho Chehab static int v4l_s_tuner(const struct v4l2_ioctl_ops *ops,
19235bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
19245bc3cb74SMauro Carvalho Chehab {
19255bc3cb74SMauro Carvalho Chehab 	struct video_device *vfd = video_devdata(file);
19265bc3cb74SMauro Carvalho Chehab 	struct v4l2_tuner *p = arg;
192777fa4e07SShuah Khan 	int ret;
19285bc3cb74SMauro Carvalho Chehab 
192977fa4e07SShuah Khan 	ret = v4l_enable_media_source(vfd);
193077fa4e07SShuah Khan 	if (ret)
193177fa4e07SShuah Khan 		return ret;
19325bc3cb74SMauro Carvalho Chehab 	p->type = (vfd->vfl_type == VFL_TYPE_RADIO) ?
19335bc3cb74SMauro Carvalho Chehab 			V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV;
19345bc3cb74SMauro Carvalho Chehab 	return ops->vidioc_s_tuner(file, fh, p);
19355bc3cb74SMauro Carvalho Chehab }
19365bc3cb74SMauro Carvalho Chehab 
19375bc3cb74SMauro Carvalho Chehab static int v4l_g_modulator(const struct v4l2_ioctl_ops *ops,
19385bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
19395bc3cb74SMauro Carvalho Chehab {
19404124a3c4SAntti Palosaari 	struct video_device *vfd = video_devdata(file);
19415bc3cb74SMauro Carvalho Chehab 	struct v4l2_modulator *p = arg;
19425bc3cb74SMauro Carvalho Chehab 	int err;
19435bc3cb74SMauro Carvalho Chehab 
19444124a3c4SAntti Palosaari 	if (vfd->vfl_type == VFL_TYPE_RADIO)
19454124a3c4SAntti Palosaari 		p->type = V4L2_TUNER_RADIO;
19464124a3c4SAntti Palosaari 
19475bc3cb74SMauro Carvalho Chehab 	err = ops->vidioc_g_modulator(file, fh, p);
19485bc3cb74SMauro Carvalho Chehab 	if (!err)
19495bc3cb74SMauro Carvalho Chehab 		p->capability |= V4L2_TUNER_CAP_FREQ_BANDS;
19505bc3cb74SMauro Carvalho Chehab 	return err;
19515bc3cb74SMauro Carvalho Chehab }
19525bc3cb74SMauro Carvalho Chehab 
19534124a3c4SAntti Palosaari static int v4l_s_modulator(const struct v4l2_ioctl_ops *ops,
19544124a3c4SAntti Palosaari 				struct file *file, void *fh, void *arg)
19554124a3c4SAntti Palosaari {
19564124a3c4SAntti Palosaari 	struct video_device *vfd = video_devdata(file);
19574124a3c4SAntti Palosaari 	struct v4l2_modulator *p = arg;
19584124a3c4SAntti Palosaari 
19594124a3c4SAntti Palosaari 	if (vfd->vfl_type == VFL_TYPE_RADIO)
19604124a3c4SAntti Palosaari 		p->type = V4L2_TUNER_RADIO;
19614124a3c4SAntti Palosaari 
19624124a3c4SAntti Palosaari 	return ops->vidioc_s_modulator(file, fh, p);
19634124a3c4SAntti Palosaari }
19644124a3c4SAntti Palosaari 
19655bc3cb74SMauro Carvalho Chehab static int v4l_g_frequency(const struct v4l2_ioctl_ops *ops,
19665bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
19675bc3cb74SMauro Carvalho Chehab {
19685bc3cb74SMauro Carvalho Chehab 	struct video_device *vfd = video_devdata(file);
19695bc3cb74SMauro Carvalho Chehab 	struct v4l2_frequency *p = arg;
19705bc3cb74SMauro Carvalho Chehab 
197184099a28SAntti Palosaari 	if (vfd->vfl_type == VFL_TYPE_SDR)
1972f3c3ececSAntti Palosaari 		p->type = V4L2_TUNER_SDR;
197384099a28SAntti Palosaari 	else
19745bc3cb74SMauro Carvalho Chehab 		p->type = (vfd->vfl_type == VFL_TYPE_RADIO) ?
19755bc3cb74SMauro Carvalho Chehab 				V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV;
19765bc3cb74SMauro Carvalho Chehab 	return ops->vidioc_g_frequency(file, fh, p);
19775bc3cb74SMauro Carvalho Chehab }
19785bc3cb74SMauro Carvalho Chehab 
19795bc3cb74SMauro Carvalho Chehab static int v4l_s_frequency(const struct v4l2_ioctl_ops *ops,
19805bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
19815bc3cb74SMauro Carvalho Chehab {
19825bc3cb74SMauro Carvalho Chehab 	struct video_device *vfd = video_devdata(file);
1983b530a447SHans Verkuil 	const struct v4l2_frequency *p = arg;
19845bc3cb74SMauro Carvalho Chehab 	enum v4l2_tuner_type type;
198577fa4e07SShuah Khan 	int ret;
19865bc3cb74SMauro Carvalho Chehab 
198777fa4e07SShuah Khan 	ret = v4l_enable_media_source(vfd);
198877fa4e07SShuah Khan 	if (ret)
198977fa4e07SShuah Khan 		return ret;
199084099a28SAntti Palosaari 	if (vfd->vfl_type == VFL_TYPE_SDR) {
1991f3c3ececSAntti Palosaari 		if (p->type != V4L2_TUNER_SDR && p->type != V4L2_TUNER_RF)
199284099a28SAntti Palosaari 			return -EINVAL;
199384099a28SAntti Palosaari 	} else {
19945bc3cb74SMauro Carvalho Chehab 		type = (vfd->vfl_type == VFL_TYPE_RADIO) ?
19955bc3cb74SMauro Carvalho Chehab 				V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV;
199684099a28SAntti Palosaari 		if (type != p->type)
19975bc3cb74SMauro Carvalho Chehab 			return -EINVAL;
199884099a28SAntti Palosaari 	}
19995bc3cb74SMauro Carvalho Chehab 	return ops->vidioc_s_frequency(file, fh, p);
20005bc3cb74SMauro Carvalho Chehab }
20015bc3cb74SMauro Carvalho Chehab 
20025bc3cb74SMauro Carvalho Chehab static int v4l_enumstd(const struct v4l2_ioctl_ops *ops,
20035bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
20045bc3cb74SMauro Carvalho Chehab {
20055bc3cb74SMauro Carvalho Chehab 	struct video_device *vfd = video_devdata(file);
20065bc3cb74SMauro Carvalho Chehab 	struct v4l2_standard *p = arg;
20075bc3cb74SMauro Carvalho Chehab 
2008aa2f8871SNiklas Söderlund 	return v4l_video_std_enumstd(p, vfd->tvnorms);
20095bc3cb74SMauro Carvalho Chehab }
20105bc3cb74SMauro Carvalho Chehab 
20115bc3cb74SMauro Carvalho Chehab static int v4l_s_std(const struct v4l2_ioctl_ops *ops,
20125bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
20135bc3cb74SMauro Carvalho Chehab {
20145bc3cb74SMauro Carvalho Chehab 	struct video_device *vfd = video_devdata(file);
2015314527acSHans Verkuil 	v4l2_std_id id = *(v4l2_std_id *)arg, norm;
201677fa4e07SShuah Khan 	int ret;
20175bc3cb74SMauro Carvalho Chehab 
201877fa4e07SShuah Khan 	ret = v4l_enable_media_source(vfd);
201977fa4e07SShuah Khan 	if (ret)
202077fa4e07SShuah Khan 		return ret;
2021314527acSHans Verkuil 	norm = id & vfd->tvnorms;
20225bc3cb74SMauro Carvalho Chehab 	if (vfd->tvnorms && !norm)	/* Check if std is supported */
20235bc3cb74SMauro Carvalho Chehab 		return -EINVAL;
20245bc3cb74SMauro Carvalho Chehab 
20255bc3cb74SMauro Carvalho Chehab 	/* Calls the specific handler */
2026ca371575SHans Verkuil 	return ops->vidioc_s_std(file, fh, norm);
20275bc3cb74SMauro Carvalho Chehab }
20285bc3cb74SMauro Carvalho Chehab 
20295bc3cb74SMauro Carvalho Chehab static int v4l_querystd(const struct v4l2_ioctl_ops *ops,
20305bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
20315bc3cb74SMauro Carvalho Chehab {
20325bc3cb74SMauro Carvalho Chehab 	struct video_device *vfd = video_devdata(file);
20335bc3cb74SMauro Carvalho Chehab 	v4l2_std_id *p = arg;
203477fa4e07SShuah Khan 	int ret;
20355bc3cb74SMauro Carvalho Chehab 
203677fa4e07SShuah Khan 	ret = v4l_enable_media_source(vfd);
203777fa4e07SShuah Khan 	if (ret)
203877fa4e07SShuah Khan 		return ret;
20395bc3cb74SMauro Carvalho Chehab 	/*
20401a2c6866SHans Verkuil 	 * If no signal is detected, then the driver should return
20411a2c6866SHans Verkuil 	 * V4L2_STD_UNKNOWN. Otherwise it should return tvnorms with
20421a2c6866SHans Verkuil 	 * any standards that do not apply removed.
20431a2c6866SHans Verkuil 	 *
20445bc3cb74SMauro Carvalho Chehab 	 * This means that tuners, audio and video decoders can join
20455bc3cb74SMauro Carvalho Chehab 	 * their efforts to improve the standards detection.
20465bc3cb74SMauro Carvalho Chehab 	 */
20475bc3cb74SMauro Carvalho Chehab 	*p = vfd->tvnorms;
20485bc3cb74SMauro Carvalho Chehab 	return ops->vidioc_querystd(file, fh, arg);
20495bc3cb74SMauro Carvalho Chehab }
20505bc3cb74SMauro Carvalho Chehab 
20515bc3cb74SMauro Carvalho Chehab static int v4l_s_hw_freq_seek(const struct v4l2_ioctl_ops *ops,
20525bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
20535bc3cb74SMauro Carvalho Chehab {
20545bc3cb74SMauro Carvalho Chehab 	struct video_device *vfd = video_devdata(file);
20555bc3cb74SMauro Carvalho Chehab 	struct v4l2_hw_freq_seek *p = arg;
20565bc3cb74SMauro Carvalho Chehab 	enum v4l2_tuner_type type;
205777fa4e07SShuah Khan 	int ret;
20585bc3cb74SMauro Carvalho Chehab 
205977fa4e07SShuah Khan 	ret = v4l_enable_media_source(vfd);
206077fa4e07SShuah Khan 	if (ret)
206177fa4e07SShuah Khan 		return ret;
206284099a28SAntti Palosaari 	/* s_hw_freq_seek is not supported for SDR for now */
206384099a28SAntti Palosaari 	if (vfd->vfl_type == VFL_TYPE_SDR)
206484099a28SAntti Palosaari 		return -EINVAL;
206584099a28SAntti Palosaari 
20665bc3cb74SMauro Carvalho Chehab 	type = (vfd->vfl_type == VFL_TYPE_RADIO) ?
20675bc3cb74SMauro Carvalho Chehab 		V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV;
20685bc3cb74SMauro Carvalho Chehab 	if (p->type != type)
20695bc3cb74SMauro Carvalho Chehab 		return -EINVAL;
20705bc3cb74SMauro Carvalho Chehab 	return ops->vidioc_s_hw_freq_seek(file, fh, p);
20715bc3cb74SMauro Carvalho Chehab }
20725bc3cb74SMauro Carvalho Chehab 
2073737c097bSHans Verkuil static int v4l_overlay(const struct v4l2_ioctl_ops *ops,
2074737c097bSHans Verkuil 				struct file *file, void *fh, void *arg)
2075737c097bSHans Verkuil {
2076737c097bSHans Verkuil 	return ops->vidioc_overlay(file, fh, *(unsigned int *)arg);
2077737c097bSHans Verkuil }
2078737c097bSHans Verkuil 
20795bc3cb74SMauro Carvalho Chehab static int v4l_reqbufs(const struct v4l2_ioctl_ops *ops,
20805bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
20815bc3cb74SMauro Carvalho Chehab {
20825bc3cb74SMauro Carvalho Chehab 	struct v4l2_requestbuffers *p = arg;
20834b20259fSHans Verkuil 	int ret = check_fmt(file, p->type);
20845bc3cb74SMauro Carvalho Chehab 
20855bc3cb74SMauro Carvalho Chehab 	if (ret)
20865bc3cb74SMauro Carvalho Chehab 		return ret;
2087129134e5SSergey Senozhatsky 
20880625b6b8SXiu Jianfeng 	memset_after(p, 0, flags);
2089129134e5SSergey Senozhatsky 
20905bc3cb74SMauro Carvalho Chehab 	return ops->vidioc_reqbufs(file, fh, p);
20915bc3cb74SMauro Carvalho Chehab }
20925bc3cb74SMauro Carvalho Chehab 
20935bc3cb74SMauro Carvalho Chehab static int v4l_querybuf(const struct v4l2_ioctl_ops *ops,
20945bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
20955bc3cb74SMauro Carvalho Chehab {
20965bc3cb74SMauro Carvalho Chehab 	struct v4l2_buffer *p = arg;
20974b20259fSHans Verkuil 	int ret = check_fmt(file, p->type);
20985bc3cb74SMauro Carvalho Chehab 
20995bc3cb74SMauro Carvalho Chehab 	return ret ? ret : ops->vidioc_querybuf(file, fh, p);
21005bc3cb74SMauro Carvalho Chehab }
21015bc3cb74SMauro Carvalho Chehab 
21025bc3cb74SMauro Carvalho Chehab static int v4l_qbuf(const struct v4l2_ioctl_ops *ops,
21035bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
21045bc3cb74SMauro Carvalho Chehab {
21055bc3cb74SMauro Carvalho Chehab 	struct v4l2_buffer *p = arg;
21064b20259fSHans Verkuil 	int ret = check_fmt(file, p->type);
21075bc3cb74SMauro Carvalho Chehab 
21085bc3cb74SMauro Carvalho Chehab 	return ret ? ret : ops->vidioc_qbuf(file, fh, p);
21095bc3cb74SMauro Carvalho Chehab }
21105bc3cb74SMauro Carvalho Chehab 
21115bc3cb74SMauro Carvalho Chehab static int v4l_dqbuf(const struct v4l2_ioctl_ops *ops,
21125bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
21135bc3cb74SMauro Carvalho Chehab {
21145bc3cb74SMauro Carvalho Chehab 	struct v4l2_buffer *p = arg;
21154b20259fSHans Verkuil 	int ret = check_fmt(file, p->type);
21165bc3cb74SMauro Carvalho Chehab 
21175bc3cb74SMauro Carvalho Chehab 	return ret ? ret : ops->vidioc_dqbuf(file, fh, p);
21185bc3cb74SMauro Carvalho Chehab }
21195bc3cb74SMauro Carvalho Chehab 
21205bc3cb74SMauro Carvalho Chehab static int v4l_create_bufs(const struct v4l2_ioctl_ops *ops,
21215bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
21225bc3cb74SMauro Carvalho Chehab {
21235bc3cb74SMauro Carvalho Chehab 	struct v4l2_create_buffers *create = arg;
21244b20259fSHans Verkuil 	int ret = check_fmt(file, create->format.type);
21255bc3cb74SMauro Carvalho Chehab 
2126d52e2381SLaurent Pinchart 	if (ret)
2127d52e2381SLaurent Pinchart 		return ret;
2128d52e2381SLaurent Pinchart 
21290625b6b8SXiu Jianfeng 	memset_after(create, 0, flags);
21305d351251SHans Verkuil 
2131d52e2381SLaurent Pinchart 	v4l_sanitize_format(&create->format);
2132d52e2381SLaurent Pinchart 
2133d52e2381SLaurent Pinchart 	ret = ops->vidioc_create_bufs(file, fh, create);
2134d52e2381SLaurent Pinchart 
2135d52e2381SLaurent Pinchart 	if (create->format.type == V4L2_BUF_TYPE_VIDEO_CAPTURE ||
2136d52e2381SLaurent Pinchart 	    create->format.type == V4L2_BUF_TYPE_VIDEO_OUTPUT)
2137d52e2381SLaurent Pinchart 		create->format.fmt.pix.priv = V4L2_PIX_FMT_PRIV_MAGIC;
2138d52e2381SLaurent Pinchart 
2139d52e2381SLaurent Pinchart 	return ret;
21405bc3cb74SMauro Carvalho Chehab }
21415bc3cb74SMauro Carvalho Chehab 
21425bc3cb74SMauro Carvalho Chehab static int v4l_prepare_buf(const struct v4l2_ioctl_ops *ops,
21435bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
21445bc3cb74SMauro Carvalho Chehab {
21455bc3cb74SMauro Carvalho Chehab 	struct v4l2_buffer *b = arg;
21464b20259fSHans Verkuil 	int ret = check_fmt(file, b->type);
21475bc3cb74SMauro Carvalho Chehab 
21485bc3cb74SMauro Carvalho Chehab 	return ret ? ret : ops->vidioc_prepare_buf(file, fh, b);
21495bc3cb74SMauro Carvalho Chehab }
21505bc3cb74SMauro Carvalho Chehab 
21515bc3cb74SMauro Carvalho Chehab static int v4l_g_parm(const struct v4l2_ioctl_ops *ops,
21525bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
21535bc3cb74SMauro Carvalho Chehab {
2154cd9d9377SHans Verkuil 	struct video_device *vfd = video_devdata(file);
21555bc3cb74SMauro Carvalho Chehab 	struct v4l2_streamparm *p = arg;
21565bc3cb74SMauro Carvalho Chehab 	v4l2_std_id std;
21574b20259fSHans Verkuil 	int ret = check_fmt(file, p->type);
21585bc3cb74SMauro Carvalho Chehab 
21595bc3cb74SMauro Carvalho Chehab 	if (ret)
21605bc3cb74SMauro Carvalho Chehab 		return ret;
21615bc3cb74SMauro Carvalho Chehab 	if (ops->vidioc_g_parm)
21625bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_g_parm(file, fh, p);
21635bc3cb74SMauro Carvalho Chehab 	if (p->type != V4L2_BUF_TYPE_VIDEO_CAPTURE &&
21645bc3cb74SMauro Carvalho Chehab 	    p->type != V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
21655bc3cb74SMauro Carvalho Chehab 		return -EINVAL;
2166cd9d9377SHans Verkuil 	if (vfd->device_caps & V4L2_CAP_READWRITE)
21675bc3cb74SMauro Carvalho Chehab 		p->parm.capture.readbuffers = 2;
21685bc3cb74SMauro Carvalho Chehab 	ret = ops->vidioc_g_std(file, fh, &std);
21695bc3cb74SMauro Carvalho Chehab 	if (ret == 0)
2170ca371575SHans Verkuil 		v4l2_video_std_frame_period(std, &p->parm.capture.timeperframe);
21715bc3cb74SMauro Carvalho Chehab 	return ret;
21725bc3cb74SMauro Carvalho Chehab }
21735bc3cb74SMauro Carvalho Chehab 
21745bc3cb74SMauro Carvalho Chehab static int v4l_s_parm(const struct v4l2_ioctl_ops *ops,
21755bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
21765bc3cb74SMauro Carvalho Chehab {
21775bc3cb74SMauro Carvalho Chehab 	struct v4l2_streamparm *p = arg;
21784b20259fSHans Verkuil 	int ret = check_fmt(file, p->type);
21795bc3cb74SMauro Carvalho Chehab 
21808a7c5594SHans Verkuil 	if (ret)
21818a7c5594SHans Verkuil 		return ret;
21828a7c5594SHans Verkuil 
21834f62e840SHans Verkuil 	/* Note: extendedmode is never used in drivers */
21848a7c5594SHans Verkuil 	if (V4L2_TYPE_IS_OUTPUT(p->type)) {
21858a7c5594SHans Verkuil 		memset(p->parm.output.reserved, 0,
21868a7c5594SHans Verkuil 		       sizeof(p->parm.output.reserved));
21878a7c5594SHans Verkuil 		p->parm.output.extendedmode = 0;
21888a7c5594SHans Verkuil 		p->parm.output.outputmode &= V4L2_MODE_HIGHQUALITY;
21898a7c5594SHans Verkuil 	} else {
21908a7c5594SHans Verkuil 		memset(p->parm.capture.reserved, 0,
21918a7c5594SHans Verkuil 		       sizeof(p->parm.capture.reserved));
21924f62e840SHans Verkuil 		p->parm.capture.extendedmode = 0;
21938a7c5594SHans Verkuil 		p->parm.capture.capturemode &= V4L2_MODE_HIGHQUALITY;
21948a7c5594SHans Verkuil 	}
21958a7c5594SHans Verkuil 	return ops->vidioc_s_parm(file, fh, p);
21965bc3cb74SMauro Carvalho Chehab }
21975bc3cb74SMauro Carvalho Chehab 
21985bc3cb74SMauro Carvalho Chehab static int v4l_queryctrl(const struct v4l2_ioctl_ops *ops,
21995bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
22005bc3cb74SMauro Carvalho Chehab {
22015bc3cb74SMauro Carvalho Chehab 	struct video_device *vfd = video_devdata(file);
22025bc3cb74SMauro Carvalho Chehab 	struct v4l2_queryctrl *p = arg;
22035bc3cb74SMauro Carvalho Chehab 	struct v4l2_fh *vfh =
22045bc3cb74SMauro Carvalho Chehab 		test_bit(V4L2_FL_USES_V4L2_FH, &vfd->flags) ? fh : NULL;
22055bc3cb74SMauro Carvalho Chehab 
22065bc3cb74SMauro Carvalho Chehab 	if (vfh && vfh->ctrl_handler)
22075bc3cb74SMauro Carvalho Chehab 		return v4l2_queryctrl(vfh->ctrl_handler, p);
22085bc3cb74SMauro Carvalho Chehab 	if (vfd->ctrl_handler)
22095bc3cb74SMauro Carvalho Chehab 		return v4l2_queryctrl(vfd->ctrl_handler, p);
22105bc3cb74SMauro Carvalho Chehab 	if (ops->vidioc_queryctrl)
22115bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_queryctrl(file, fh, p);
22125bc3cb74SMauro Carvalho Chehab 	return -ENOTTY;
22135bc3cb74SMauro Carvalho Chehab }
22145bc3cb74SMauro Carvalho Chehab 
2215e6bee368SHans Verkuil static int v4l_query_ext_ctrl(const struct v4l2_ioctl_ops *ops,
2216e6bee368SHans Verkuil 				struct file *file, void *fh, void *arg)
2217e6bee368SHans Verkuil {
2218e6bee368SHans Verkuil 	struct video_device *vfd = video_devdata(file);
2219e6bee368SHans Verkuil 	struct v4l2_query_ext_ctrl *p = arg;
2220e6bee368SHans Verkuil 	struct v4l2_fh *vfh =
2221e6bee368SHans Verkuil 		test_bit(V4L2_FL_USES_V4L2_FH, &vfd->flags) ? fh : NULL;
2222e6bee368SHans Verkuil 
2223e6bee368SHans Verkuil 	if (vfh && vfh->ctrl_handler)
2224e6bee368SHans Verkuil 		return v4l2_query_ext_ctrl(vfh->ctrl_handler, p);
2225e6bee368SHans Verkuil 	if (vfd->ctrl_handler)
2226e6bee368SHans Verkuil 		return v4l2_query_ext_ctrl(vfd->ctrl_handler, p);
2227e6bee368SHans Verkuil 	if (ops->vidioc_query_ext_ctrl)
2228e6bee368SHans Verkuil 		return ops->vidioc_query_ext_ctrl(file, fh, p);
2229e6bee368SHans Verkuil 	return -ENOTTY;
2230e6bee368SHans Verkuil }
2231e6bee368SHans Verkuil 
22325bc3cb74SMauro Carvalho Chehab static int v4l_querymenu(const struct v4l2_ioctl_ops *ops,
22335bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
22345bc3cb74SMauro Carvalho Chehab {
22355bc3cb74SMauro Carvalho Chehab 	struct video_device *vfd = video_devdata(file);
22365bc3cb74SMauro Carvalho Chehab 	struct v4l2_querymenu *p = arg;
22375bc3cb74SMauro Carvalho Chehab 	struct v4l2_fh *vfh =
22385bc3cb74SMauro Carvalho Chehab 		test_bit(V4L2_FL_USES_V4L2_FH, &vfd->flags) ? fh : NULL;
22395bc3cb74SMauro Carvalho Chehab 
22405bc3cb74SMauro Carvalho Chehab 	if (vfh && vfh->ctrl_handler)
22415bc3cb74SMauro Carvalho Chehab 		return v4l2_querymenu(vfh->ctrl_handler, p);
22425bc3cb74SMauro Carvalho Chehab 	if (vfd->ctrl_handler)
22435bc3cb74SMauro Carvalho Chehab 		return v4l2_querymenu(vfd->ctrl_handler, p);
22445bc3cb74SMauro Carvalho Chehab 	if (ops->vidioc_querymenu)
22455bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_querymenu(file, fh, p);
22465bc3cb74SMauro Carvalho Chehab 	return -ENOTTY;
22475bc3cb74SMauro Carvalho Chehab }
22485bc3cb74SMauro Carvalho Chehab 
22495bc3cb74SMauro Carvalho Chehab static int v4l_g_ctrl(const struct v4l2_ioctl_ops *ops,
22505bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
22515bc3cb74SMauro Carvalho Chehab {
22525bc3cb74SMauro Carvalho Chehab 	struct video_device *vfd = video_devdata(file);
22535bc3cb74SMauro Carvalho Chehab 	struct v4l2_control *p = arg;
22545bc3cb74SMauro Carvalho Chehab 	struct v4l2_fh *vfh =
22555bc3cb74SMauro Carvalho Chehab 		test_bit(V4L2_FL_USES_V4L2_FH, &vfd->flags) ? fh : NULL;
22565bc3cb74SMauro Carvalho Chehab 	struct v4l2_ext_controls ctrls;
22575bc3cb74SMauro Carvalho Chehab 	struct v4l2_ext_control ctrl;
22585bc3cb74SMauro Carvalho Chehab 
22595bc3cb74SMauro Carvalho Chehab 	if (vfh && vfh->ctrl_handler)
22605bc3cb74SMauro Carvalho Chehab 		return v4l2_g_ctrl(vfh->ctrl_handler, p);
22615bc3cb74SMauro Carvalho Chehab 	if (vfd->ctrl_handler)
22625bc3cb74SMauro Carvalho Chehab 		return v4l2_g_ctrl(vfd->ctrl_handler, p);
22635bc3cb74SMauro Carvalho Chehab 	if (ops->vidioc_g_ctrl)
22645bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_g_ctrl(file, fh, p);
22655bc3cb74SMauro Carvalho Chehab 	if (ops->vidioc_g_ext_ctrls == NULL)
22665bc3cb74SMauro Carvalho Chehab 		return -ENOTTY;
22675bc3cb74SMauro Carvalho Chehab 
22680f8017beSRicardo Ribalda 	ctrls.which = V4L2_CTRL_ID2WHICH(p->id);
22695bc3cb74SMauro Carvalho Chehab 	ctrls.count = 1;
22705bc3cb74SMauro Carvalho Chehab 	ctrls.controls = &ctrl;
22715bc3cb74SMauro Carvalho Chehab 	ctrl.id = p->id;
22725bc3cb74SMauro Carvalho Chehab 	ctrl.value = p->value;
2273861f92cbSRicardo Ribalda 	if (check_ext_ctrls(&ctrls, VIDIOC_G_CTRL)) {
22745bc3cb74SMauro Carvalho Chehab 		int ret = ops->vidioc_g_ext_ctrls(file, fh, &ctrls);
22755bc3cb74SMauro Carvalho Chehab 
22765bc3cb74SMauro Carvalho Chehab 		if (ret == 0)
22775bc3cb74SMauro Carvalho Chehab 			p->value = ctrl.value;
22785bc3cb74SMauro Carvalho Chehab 		return ret;
22795bc3cb74SMauro Carvalho Chehab 	}
22805bc3cb74SMauro Carvalho Chehab 	return -EINVAL;
22815bc3cb74SMauro Carvalho Chehab }
22825bc3cb74SMauro Carvalho Chehab 
22835bc3cb74SMauro Carvalho Chehab static int v4l_s_ctrl(const struct v4l2_ioctl_ops *ops,
22845bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
22855bc3cb74SMauro Carvalho Chehab {
22865bc3cb74SMauro Carvalho Chehab 	struct video_device *vfd = video_devdata(file);
22875bc3cb74SMauro Carvalho Chehab 	struct v4l2_control *p = arg;
22885bc3cb74SMauro Carvalho Chehab 	struct v4l2_fh *vfh =
22895bc3cb74SMauro Carvalho Chehab 		test_bit(V4L2_FL_USES_V4L2_FH, &vfd->flags) ? fh : NULL;
22905bc3cb74SMauro Carvalho Chehab 	struct v4l2_ext_controls ctrls;
22915bc3cb74SMauro Carvalho Chehab 	struct v4l2_ext_control ctrl;
2292c87ed935SRicardo Ribalda 	int ret;
22935bc3cb74SMauro Carvalho Chehab 
22945bc3cb74SMauro Carvalho Chehab 	if (vfh && vfh->ctrl_handler)
22955bc3cb74SMauro Carvalho Chehab 		return v4l2_s_ctrl(vfh, vfh->ctrl_handler, p);
22965bc3cb74SMauro Carvalho Chehab 	if (vfd->ctrl_handler)
22975bc3cb74SMauro Carvalho Chehab 		return v4l2_s_ctrl(NULL, vfd->ctrl_handler, p);
22985bc3cb74SMauro Carvalho Chehab 	if (ops->vidioc_s_ctrl)
22995bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_s_ctrl(file, fh, p);
23005bc3cb74SMauro Carvalho Chehab 	if (ops->vidioc_s_ext_ctrls == NULL)
23015bc3cb74SMauro Carvalho Chehab 		return -ENOTTY;
23025bc3cb74SMauro Carvalho Chehab 
23030f8017beSRicardo Ribalda 	ctrls.which = V4L2_CTRL_ID2WHICH(p->id);
23045bc3cb74SMauro Carvalho Chehab 	ctrls.count = 1;
23055bc3cb74SMauro Carvalho Chehab 	ctrls.controls = &ctrl;
23065bc3cb74SMauro Carvalho Chehab 	ctrl.id = p->id;
23075bc3cb74SMauro Carvalho Chehab 	ctrl.value = p->value;
2308c87ed935SRicardo Ribalda 	if (!check_ext_ctrls(&ctrls, VIDIOC_S_CTRL))
23095bc3cb74SMauro Carvalho Chehab 		return -EINVAL;
2310c87ed935SRicardo Ribalda 	ret = ops->vidioc_s_ext_ctrls(file, fh, &ctrls);
2311c87ed935SRicardo Ribalda 	p->value = ctrl.value;
2312c87ed935SRicardo Ribalda 	return ret;
23135bc3cb74SMauro Carvalho Chehab }
23145bc3cb74SMauro Carvalho Chehab 
23155bc3cb74SMauro Carvalho Chehab static int v4l_g_ext_ctrls(const struct v4l2_ioctl_ops *ops,
23165bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
23175bc3cb74SMauro Carvalho Chehab {
23185bc3cb74SMauro Carvalho Chehab 	struct video_device *vfd = video_devdata(file);
23195bc3cb74SMauro Carvalho Chehab 	struct v4l2_ext_controls *p = arg;
23205bc3cb74SMauro Carvalho Chehab 	struct v4l2_fh *vfh =
23215bc3cb74SMauro Carvalho Chehab 		test_bit(V4L2_FL_USES_V4L2_FH, &vfd->flags) ? fh : NULL;
23225bc3cb74SMauro Carvalho Chehab 
23235bc3cb74SMauro Carvalho Chehab 	p->error_idx = p->count;
23245bc3cb74SMauro Carvalho Chehab 	if (vfh && vfh->ctrl_handler)
2325173f6eacSEzequiel Garcia 		return v4l2_g_ext_ctrls(vfh->ctrl_handler,
2326173f6eacSEzequiel Garcia 					vfd, vfd->v4l2_dev->mdev, p);
23275bc3cb74SMauro Carvalho Chehab 	if (vfd->ctrl_handler)
2328173f6eacSEzequiel Garcia 		return v4l2_g_ext_ctrls(vfd->ctrl_handler,
2329173f6eacSEzequiel Garcia 					vfd, vfd->v4l2_dev->mdev, p);
23305bc3cb74SMauro Carvalho Chehab 	if (ops->vidioc_g_ext_ctrls == NULL)
23315bc3cb74SMauro Carvalho Chehab 		return -ENOTTY;
2332861f92cbSRicardo Ribalda 	return check_ext_ctrls(p, VIDIOC_G_EXT_CTRLS) ?
2333861f92cbSRicardo Ribalda 				ops->vidioc_g_ext_ctrls(file, fh, p) : -EINVAL;
23345bc3cb74SMauro Carvalho Chehab }
23355bc3cb74SMauro Carvalho Chehab 
23365bc3cb74SMauro Carvalho Chehab static int v4l_s_ext_ctrls(const struct v4l2_ioctl_ops *ops,
23375bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
23385bc3cb74SMauro Carvalho Chehab {
23395bc3cb74SMauro Carvalho Chehab 	struct video_device *vfd = video_devdata(file);
23405bc3cb74SMauro Carvalho Chehab 	struct v4l2_ext_controls *p = arg;
23415bc3cb74SMauro Carvalho Chehab 	struct v4l2_fh *vfh =
23425bc3cb74SMauro Carvalho Chehab 		test_bit(V4L2_FL_USES_V4L2_FH, &vfd->flags) ? fh : NULL;
23435bc3cb74SMauro Carvalho Chehab 
23445bc3cb74SMauro Carvalho Chehab 	p->error_idx = p->count;
23455bc3cb74SMauro Carvalho Chehab 	if (vfh && vfh->ctrl_handler)
2346173f6eacSEzequiel Garcia 		return v4l2_s_ext_ctrls(vfh, vfh->ctrl_handler,
2347173f6eacSEzequiel Garcia 					vfd, vfd->v4l2_dev->mdev, p);
23485bc3cb74SMauro Carvalho Chehab 	if (vfd->ctrl_handler)
2349173f6eacSEzequiel Garcia 		return v4l2_s_ext_ctrls(NULL, vfd->ctrl_handler,
2350173f6eacSEzequiel Garcia 					vfd, vfd->v4l2_dev->mdev, p);
23515bc3cb74SMauro Carvalho Chehab 	if (ops->vidioc_s_ext_ctrls == NULL)
23525bc3cb74SMauro Carvalho Chehab 		return -ENOTTY;
2353861f92cbSRicardo Ribalda 	return check_ext_ctrls(p, VIDIOC_S_EXT_CTRLS) ?
2354861f92cbSRicardo Ribalda 				ops->vidioc_s_ext_ctrls(file, fh, p) : -EINVAL;
23555bc3cb74SMauro Carvalho Chehab }
23565bc3cb74SMauro Carvalho Chehab 
23575bc3cb74SMauro Carvalho Chehab static int v4l_try_ext_ctrls(const struct v4l2_ioctl_ops *ops,
23585bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
23595bc3cb74SMauro Carvalho Chehab {
23605bc3cb74SMauro Carvalho Chehab 	struct video_device *vfd = video_devdata(file);
23615bc3cb74SMauro Carvalho Chehab 	struct v4l2_ext_controls *p = arg;
23625bc3cb74SMauro Carvalho Chehab 	struct v4l2_fh *vfh =
23635bc3cb74SMauro Carvalho Chehab 		test_bit(V4L2_FL_USES_V4L2_FH, &vfd->flags) ? fh : NULL;
23645bc3cb74SMauro Carvalho Chehab 
23655bc3cb74SMauro Carvalho Chehab 	p->error_idx = p->count;
23665bc3cb74SMauro Carvalho Chehab 	if (vfh && vfh->ctrl_handler)
2367173f6eacSEzequiel Garcia 		return v4l2_try_ext_ctrls(vfh->ctrl_handler,
2368173f6eacSEzequiel Garcia 					  vfd, vfd->v4l2_dev->mdev, p);
23695bc3cb74SMauro Carvalho Chehab 	if (vfd->ctrl_handler)
2370173f6eacSEzequiel Garcia 		return v4l2_try_ext_ctrls(vfd->ctrl_handler,
2371173f6eacSEzequiel Garcia 					  vfd, vfd->v4l2_dev->mdev, p);
23725bc3cb74SMauro Carvalho Chehab 	if (ops->vidioc_try_ext_ctrls == NULL)
23735bc3cb74SMauro Carvalho Chehab 		return -ENOTTY;
2374861f92cbSRicardo Ribalda 	return check_ext_ctrls(p, VIDIOC_TRY_EXT_CTRLS) ?
2375861f92cbSRicardo Ribalda 			ops->vidioc_try_ext_ctrls(file, fh, p) : -EINVAL;
23765bc3cb74SMauro Carvalho Chehab }
23775bc3cb74SMauro Carvalho Chehab 
2378eaec420fSHans Verkuil /*
2379eaec420fSHans Verkuil  * The selection API specified originally that the _MPLANE buffer types
2380eaec420fSHans Verkuil  * shouldn't be used. The reasons for this are lost in the mists of time
2381eaec420fSHans Verkuil  * (or just really crappy memories). Regardless, this is really annoying
2382eaec420fSHans Verkuil  * for userspace. So to keep things simple we map _MPLANE buffer types
2383eaec420fSHans Verkuil  * to their 'regular' counterparts before calling the driver. And we
2384eaec420fSHans Verkuil  * restore it afterwards. This way applications can use either buffer
2385eaec420fSHans Verkuil  * type and drivers don't need to check for both.
2386eaec420fSHans Verkuil  */
2387eaec420fSHans Verkuil static int v4l_g_selection(const struct v4l2_ioctl_ops *ops,
2388eaec420fSHans Verkuil 			   struct file *file, void *fh, void *arg)
2389eaec420fSHans Verkuil {
2390eaec420fSHans Verkuil 	struct v4l2_selection *p = arg;
2391eaec420fSHans Verkuil 	u32 old_type = p->type;
2392eaec420fSHans Verkuil 	int ret;
2393eaec420fSHans Verkuil 
2394eaec420fSHans Verkuil 	if (p->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
2395eaec420fSHans Verkuil 		p->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
2396eaec420fSHans Verkuil 	else if (p->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)
2397eaec420fSHans Verkuil 		p->type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
2398eaec420fSHans Verkuil 	ret = ops->vidioc_g_selection(file, fh, p);
2399eaec420fSHans Verkuil 	p->type = old_type;
2400eaec420fSHans Verkuil 	return ret;
2401eaec420fSHans Verkuil }
2402eaec420fSHans Verkuil 
2403eaec420fSHans Verkuil static int v4l_s_selection(const struct v4l2_ioctl_ops *ops,
2404eaec420fSHans Verkuil 			   struct file *file, void *fh, void *arg)
2405eaec420fSHans Verkuil {
2406eaec420fSHans Verkuil 	struct v4l2_selection *p = arg;
2407eaec420fSHans Verkuil 	u32 old_type = p->type;
2408eaec420fSHans Verkuil 	int ret;
2409eaec420fSHans Verkuil 
2410eaec420fSHans Verkuil 	if (p->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
2411eaec420fSHans Verkuil 		p->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
2412eaec420fSHans Verkuil 	else if (p->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)
2413eaec420fSHans Verkuil 		p->type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
2414eaec420fSHans Verkuil 	ret = ops->vidioc_s_selection(file, fh, p);
2415eaec420fSHans Verkuil 	p->type = old_type;
2416eaec420fSHans Verkuil 	return ret;
2417eaec420fSHans Verkuil }
2418eaec420fSHans Verkuil 
24195bc3cb74SMauro Carvalho Chehab static int v4l_g_crop(const struct v4l2_ioctl_ops *ops,
24205bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
24215bc3cb74SMauro Carvalho Chehab {
24228cbd94bdSHans Verkuil 	struct video_device *vfd = video_devdata(file);
24235bc3cb74SMauro Carvalho Chehab 	struct v4l2_crop *p = arg;
24245bc3cb74SMauro Carvalho Chehab 	struct v4l2_selection s = {
24255bc3cb74SMauro Carvalho Chehab 		.type = p->type,
24265bc3cb74SMauro Carvalho Chehab 	};
24275bc3cb74SMauro Carvalho Chehab 	int ret;
24285bc3cb74SMauro Carvalho Chehab 
24295bc3cb74SMauro Carvalho Chehab 	/* simulate capture crop using selection api */
24305bc3cb74SMauro Carvalho Chehab 
24315bc3cb74SMauro Carvalho Chehab 	/* crop means compose for output devices */
24325bc3cb74SMauro Carvalho Chehab 	if (V4L2_TYPE_IS_OUTPUT(p->type))
24335b79da06SHans Verkuil 		s.target = V4L2_SEL_TGT_COMPOSE;
24345bc3cb74SMauro Carvalho Chehab 	else
24355b79da06SHans Verkuil 		s.target = V4L2_SEL_TGT_CROP;
24365bc3cb74SMauro Carvalho Chehab 
24378cbd94bdSHans Verkuil 	if (test_bit(V4L2_FL_QUIRK_INVERTED_CROP, &vfd->flags))
24388cbd94bdSHans Verkuil 		s.target = s.target == V4L2_SEL_TGT_COMPOSE ?
24398cbd94bdSHans Verkuil 			V4L2_SEL_TGT_CROP : V4L2_SEL_TGT_COMPOSE;
24408cbd94bdSHans Verkuil 
2441eaec420fSHans Verkuil 	ret = v4l_g_selection(ops, file, fh, &s);
24425bc3cb74SMauro Carvalho Chehab 
24435bc3cb74SMauro Carvalho Chehab 	/* copying results to old structure on success */
24445bc3cb74SMauro Carvalho Chehab 	if (!ret)
24455bc3cb74SMauro Carvalho Chehab 		p->c = s.r;
24465bc3cb74SMauro Carvalho Chehab 	return ret;
24475bc3cb74SMauro Carvalho Chehab }
24485bc3cb74SMauro Carvalho Chehab 
24495bc3cb74SMauro Carvalho Chehab static int v4l_s_crop(const struct v4l2_ioctl_ops *ops,
24505bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
24515bc3cb74SMauro Carvalho Chehab {
24528cbd94bdSHans Verkuil 	struct video_device *vfd = video_devdata(file);
24535bc3cb74SMauro Carvalho Chehab 	struct v4l2_crop *p = arg;
24545bc3cb74SMauro Carvalho Chehab 	struct v4l2_selection s = {
24555bc3cb74SMauro Carvalho Chehab 		.type = p->type,
24565bc3cb74SMauro Carvalho Chehab 		.r = p->c,
24575bc3cb74SMauro Carvalho Chehab 	};
24585bc3cb74SMauro Carvalho Chehab 
24595bc3cb74SMauro Carvalho Chehab 	/* simulate capture crop using selection api */
24605bc3cb74SMauro Carvalho Chehab 
24615bc3cb74SMauro Carvalho Chehab 	/* crop means compose for output devices */
24625bc3cb74SMauro Carvalho Chehab 	if (V4L2_TYPE_IS_OUTPUT(p->type))
24635b79da06SHans Verkuil 		s.target = V4L2_SEL_TGT_COMPOSE;
24645bc3cb74SMauro Carvalho Chehab 	else
24655b79da06SHans Verkuil 		s.target = V4L2_SEL_TGT_CROP;
24665bc3cb74SMauro Carvalho Chehab 
24678cbd94bdSHans Verkuil 	if (test_bit(V4L2_FL_QUIRK_INVERTED_CROP, &vfd->flags))
24688cbd94bdSHans Verkuil 		s.target = s.target == V4L2_SEL_TGT_COMPOSE ?
24698cbd94bdSHans Verkuil 			V4L2_SEL_TGT_CROP : V4L2_SEL_TGT_COMPOSE;
24708cbd94bdSHans Verkuil 
2471eaec420fSHans Verkuil 	return v4l_s_selection(ops, file, fh, &s);
24725bc3cb74SMauro Carvalho Chehab }
24735bc3cb74SMauro Carvalho Chehab 
24745bc3cb74SMauro Carvalho Chehab static int v4l_cropcap(const struct v4l2_ioctl_ops *ops,
24755bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
24765bc3cb74SMauro Carvalho Chehab {
24778cbd94bdSHans Verkuil 	struct video_device *vfd = video_devdata(file);
24785bc3cb74SMauro Carvalho Chehab 	struct v4l2_cropcap *p = arg;
24795bc3cb74SMauro Carvalho Chehab 	struct v4l2_selection s = { .type = p->type };
248095dd7b7eSHans Verkuil 	int ret = 0;
248195dd7b7eSHans Verkuil 
248295dd7b7eSHans Verkuil 	/* setting trivial pixelaspect */
248395dd7b7eSHans Verkuil 	p->pixelaspect.numerator = 1;
248495dd7b7eSHans Verkuil 	p->pixelaspect.denominator = 1;
248595dd7b7eSHans Verkuil 
24865200ab6aSHans Verkuil 	if (s.type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
24875200ab6aSHans Verkuil 		s.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
24885200ab6aSHans Verkuil 	else if (s.type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)
24895200ab6aSHans Verkuil 		s.type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
24905200ab6aSHans Verkuil 
249195dd7b7eSHans Verkuil 	/*
249295dd7b7eSHans Verkuil 	 * The determine_valid_ioctls() call already should ensure
249395dd7b7eSHans Verkuil 	 * that this can never happen, but just in case...
249495dd7b7eSHans Verkuil 	 */
24955200ab6aSHans Verkuil 	if (WARN_ON(!ops->vidioc_g_selection))
249695dd7b7eSHans Verkuil 		return -ENOTTY;
249795dd7b7eSHans Verkuil 
24985200ab6aSHans Verkuil 	if (ops->vidioc_g_pixelaspect)
24995200ab6aSHans Verkuil 		ret = ops->vidioc_g_pixelaspect(file, fh, s.type,
25005200ab6aSHans Verkuil 						&p->pixelaspect);
250195dd7b7eSHans Verkuil 
250295dd7b7eSHans Verkuil 	/*
250395dd7b7eSHans Verkuil 	 * Ignore ENOTTY or ENOIOCTLCMD error returns, just use the
250495dd7b7eSHans Verkuil 	 * square pixel aspect ratio in that case.
250595dd7b7eSHans Verkuil 	 */
250695dd7b7eSHans Verkuil 	if (ret && ret != -ENOTTY && ret != -ENOIOCTLCMD)
250795dd7b7eSHans Verkuil 		return ret;
250895dd7b7eSHans Verkuil 
250995dd7b7eSHans Verkuil 	/* Use g_selection() to fill in the bounds and defrect rectangles */
25105bc3cb74SMauro Carvalho Chehab 
25115bc3cb74SMauro Carvalho Chehab 	/* obtaining bounds */
25125bc3cb74SMauro Carvalho Chehab 	if (V4L2_TYPE_IS_OUTPUT(p->type))
25135bc3cb74SMauro Carvalho Chehab 		s.target = V4L2_SEL_TGT_COMPOSE_BOUNDS;
25145bc3cb74SMauro Carvalho Chehab 	else
25155bc3cb74SMauro Carvalho Chehab 		s.target = V4L2_SEL_TGT_CROP_BOUNDS;
25165bc3cb74SMauro Carvalho Chehab 
25178cbd94bdSHans Verkuil 	if (test_bit(V4L2_FL_QUIRK_INVERTED_CROP, &vfd->flags))
25188cbd94bdSHans Verkuil 		s.target = s.target == V4L2_SEL_TGT_COMPOSE_BOUNDS ?
25198cbd94bdSHans Verkuil 			V4L2_SEL_TGT_CROP_BOUNDS : V4L2_SEL_TGT_COMPOSE_BOUNDS;
25208cbd94bdSHans Verkuil 
2521eaec420fSHans Verkuil 	ret = v4l_g_selection(ops, file, fh, &s);
25225bc3cb74SMauro Carvalho Chehab 	if (ret)
25235bc3cb74SMauro Carvalho Chehab 		return ret;
25245bc3cb74SMauro Carvalho Chehab 	p->bounds = s.r;
25255bc3cb74SMauro Carvalho Chehab 
25265bc3cb74SMauro Carvalho Chehab 	/* obtaining defrect */
25278cbd94bdSHans Verkuil 	if (s.target == V4L2_SEL_TGT_COMPOSE_BOUNDS)
25285bc3cb74SMauro Carvalho Chehab 		s.target = V4L2_SEL_TGT_COMPOSE_DEFAULT;
25295bc3cb74SMauro Carvalho Chehab 	else
25305bc3cb74SMauro Carvalho Chehab 		s.target = V4L2_SEL_TGT_CROP_DEFAULT;
25315bc3cb74SMauro Carvalho Chehab 
2532eaec420fSHans Verkuil 	ret = v4l_g_selection(ops, file, fh, &s);
25335bc3cb74SMauro Carvalho Chehab 	if (ret)
25345bc3cb74SMauro Carvalho Chehab 		return ret;
25355bc3cb74SMauro Carvalho Chehab 	p->defrect = s.r;
25369409945cSHans Verkuil 
25375bc3cb74SMauro Carvalho Chehab 	return 0;
25385bc3cb74SMauro Carvalho Chehab }
25395bc3cb74SMauro Carvalho Chehab 
25405bc3cb74SMauro Carvalho Chehab static int v4l_log_status(const struct v4l2_ioctl_ops *ops,
25415bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
25425bc3cb74SMauro Carvalho Chehab {
25435bc3cb74SMauro Carvalho Chehab 	struct video_device *vfd = video_devdata(file);
25445bc3cb74SMauro Carvalho Chehab 	int ret;
25455bc3cb74SMauro Carvalho Chehab 
25465bc3cb74SMauro Carvalho Chehab 	if (vfd->v4l2_dev)
25475bc3cb74SMauro Carvalho Chehab 		pr_info("%s: =================  START STATUS  =================\n",
25485bc3cb74SMauro Carvalho Chehab 			vfd->v4l2_dev->name);
25495bc3cb74SMauro Carvalho Chehab 	ret = ops->vidioc_log_status(file, fh);
25505bc3cb74SMauro Carvalho Chehab 	if (vfd->v4l2_dev)
25515bc3cb74SMauro Carvalho Chehab 		pr_info("%s: ==================  END STATUS  ==================\n",
25525bc3cb74SMauro Carvalho Chehab 			vfd->v4l2_dev->name);
25535bc3cb74SMauro Carvalho Chehab 	return ret;
25545bc3cb74SMauro Carvalho Chehab }
25555bc3cb74SMauro Carvalho Chehab 
25565bc3cb74SMauro Carvalho Chehab static int v4l_dbg_g_register(const struct v4l2_ioctl_ops *ops,
25575bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
25585bc3cb74SMauro Carvalho Chehab {
25595bc3cb74SMauro Carvalho Chehab #ifdef CONFIG_VIDEO_ADV_DEBUG
25605bc3cb74SMauro Carvalho Chehab 	struct v4l2_dbg_register *p = arg;
256179b0c640SHans Verkuil 	struct video_device *vfd = video_devdata(file);
256279b0c640SHans Verkuil 	struct v4l2_subdev *sd;
256379b0c640SHans Verkuil 	int idx = 0;
25645bc3cb74SMauro Carvalho Chehab 
25655bc3cb74SMauro Carvalho Chehab 	if (!capable(CAP_SYS_ADMIN))
25665bc3cb74SMauro Carvalho Chehab 		return -EPERM;
25673eef2510SHans Verkuil 	if (p->match.type == V4L2_CHIP_MATCH_SUBDEV) {
256879b0c640SHans Verkuil 		if (vfd->v4l2_dev == NULL)
256979b0c640SHans Verkuil 			return -EINVAL;
25703eef2510SHans Verkuil 		v4l2_device_for_each_subdev(sd, vfd->v4l2_dev)
25713eef2510SHans Verkuil 			if (p->match.addr == idx++)
257279b0c640SHans Verkuil 				return v4l2_subdev_call(sd, core, g_register, p);
257379b0c640SHans Verkuil 		return -EINVAL;
257479b0c640SHans Verkuil 	}
2575191b79b0SHans Verkuil 	if (ops->vidioc_g_register && p->match.type == V4L2_CHIP_MATCH_BRIDGE &&
2576191b79b0SHans Verkuil 	    (ops->vidioc_g_chip_info || p->match.addr == 0))
25775bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_g_register(file, fh, p);
257879b0c640SHans Verkuil 	return -EINVAL;
25795bc3cb74SMauro Carvalho Chehab #else
25805bc3cb74SMauro Carvalho Chehab 	return -ENOTTY;
25815bc3cb74SMauro Carvalho Chehab #endif
25825bc3cb74SMauro Carvalho Chehab }
25835bc3cb74SMauro Carvalho Chehab 
25845bc3cb74SMauro Carvalho Chehab static int v4l_dbg_s_register(const struct v4l2_ioctl_ops *ops,
25855bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
25865bc3cb74SMauro Carvalho Chehab {
25875bc3cb74SMauro Carvalho Chehab #ifdef CONFIG_VIDEO_ADV_DEBUG
2588977ba3b1SHans Verkuil 	const struct v4l2_dbg_register *p = arg;
258979b0c640SHans Verkuil 	struct video_device *vfd = video_devdata(file);
259079b0c640SHans Verkuil 	struct v4l2_subdev *sd;
259179b0c640SHans Verkuil 	int idx = 0;
25925bc3cb74SMauro Carvalho Chehab 
25935bc3cb74SMauro Carvalho Chehab 	if (!capable(CAP_SYS_ADMIN))
25945bc3cb74SMauro Carvalho Chehab 		return -EPERM;
25953eef2510SHans Verkuil 	if (p->match.type == V4L2_CHIP_MATCH_SUBDEV) {
259679b0c640SHans Verkuil 		if (vfd->v4l2_dev == NULL)
259779b0c640SHans Verkuil 			return -EINVAL;
25983eef2510SHans Verkuil 		v4l2_device_for_each_subdev(sd, vfd->v4l2_dev)
25993eef2510SHans Verkuil 			if (p->match.addr == idx++)
260079b0c640SHans Verkuil 				return v4l2_subdev_call(sd, core, s_register, p);
260179b0c640SHans Verkuil 		return -EINVAL;
260279b0c640SHans Verkuil 	}
2603191b79b0SHans Verkuil 	if (ops->vidioc_s_register && p->match.type == V4L2_CHIP_MATCH_BRIDGE &&
2604191b79b0SHans Verkuil 	    (ops->vidioc_g_chip_info || p->match.addr == 0))
26055bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_s_register(file, fh, p);
260679b0c640SHans Verkuil 	return -EINVAL;
26075bc3cb74SMauro Carvalho Chehab #else
26085bc3cb74SMauro Carvalho Chehab 	return -ENOTTY;
26095bc3cb74SMauro Carvalho Chehab #endif
26105bc3cb74SMauro Carvalho Chehab }
26115bc3cb74SMauro Carvalho Chehab 
261296b03d2aSHans Verkuil static int v4l_dbg_g_chip_info(const struct v4l2_ioctl_ops *ops,
261379b0c640SHans Verkuil 				struct file *file, void *fh, void *arg)
261479b0c640SHans Verkuil {
2615cd634f1bSHans Verkuil #ifdef CONFIG_VIDEO_ADV_DEBUG
261679b0c640SHans Verkuil 	struct video_device *vfd = video_devdata(file);
261796b03d2aSHans Verkuil 	struct v4l2_dbg_chip_info *p = arg;
261879b0c640SHans Verkuil 	struct v4l2_subdev *sd;
261979b0c640SHans Verkuil 	int idx = 0;
262079b0c640SHans Verkuil 
262179b0c640SHans Verkuil 	switch (p->match.type) {
262279b0c640SHans Verkuil 	case V4L2_CHIP_MATCH_BRIDGE:
262379b0c640SHans Verkuil 		if (ops->vidioc_s_register)
262479b0c640SHans Verkuil 			p->flags |= V4L2_CHIP_FL_WRITABLE;
262579b0c640SHans Verkuil 		if (ops->vidioc_g_register)
262679b0c640SHans Verkuil 			p->flags |= V4L2_CHIP_FL_READABLE;
2627c0decac1SMauro Carvalho Chehab 		strscpy(p->name, vfd->v4l2_dev->name, sizeof(p->name));
262896b03d2aSHans Verkuil 		if (ops->vidioc_g_chip_info)
262996b03d2aSHans Verkuil 			return ops->vidioc_g_chip_info(file, fh, arg);
26300f0fe4b9SHans Verkuil 		if (p->match.addr)
26310f0fe4b9SHans Verkuil 			return -EINVAL;
263279b0c640SHans Verkuil 		return 0;
263379b0c640SHans Verkuil 
26343eef2510SHans Verkuil 	case V4L2_CHIP_MATCH_SUBDEV:
263579b0c640SHans Verkuil 		if (vfd->v4l2_dev == NULL)
263679b0c640SHans Verkuil 			break;
263779b0c640SHans Verkuil 		v4l2_device_for_each_subdev(sd, vfd->v4l2_dev) {
26383eef2510SHans Verkuil 			if (p->match.addr != idx++)
26393eef2510SHans Verkuil 				continue;
264079b0c640SHans Verkuil 			if (sd->ops->core && sd->ops->core->s_register)
264179b0c640SHans Verkuil 				p->flags |= V4L2_CHIP_FL_WRITABLE;
264279b0c640SHans Verkuil 			if (sd->ops->core && sd->ops->core->g_register)
264379b0c640SHans Verkuil 				p->flags |= V4L2_CHIP_FL_READABLE;
2644c0decac1SMauro Carvalho Chehab 			strscpy(p->name, sd->name, sizeof(p->name));
264579b0c640SHans Verkuil 			return 0;
264679b0c640SHans Verkuil 		}
264779b0c640SHans Verkuil 		break;
264879b0c640SHans Verkuil 	}
264979b0c640SHans Verkuil 	return -EINVAL;
2650cd634f1bSHans Verkuil #else
2651cd634f1bSHans Verkuil 	return -ENOTTY;
2652cd634f1bSHans Verkuil #endif
265379b0c640SHans Verkuil }
265479b0c640SHans Verkuil 
26555bc3cb74SMauro Carvalho Chehab static int v4l_dqevent(const struct v4l2_ioctl_ops *ops,
26565bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
26575bc3cb74SMauro Carvalho Chehab {
26585bc3cb74SMauro Carvalho Chehab 	return v4l2_event_dequeue(fh, arg, file->f_flags & O_NONBLOCK);
26595bc3cb74SMauro Carvalho Chehab }
26605bc3cb74SMauro Carvalho Chehab 
26615bc3cb74SMauro Carvalho Chehab static int v4l_subscribe_event(const struct v4l2_ioctl_ops *ops,
26625bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
26635bc3cb74SMauro Carvalho Chehab {
26645bc3cb74SMauro Carvalho Chehab 	return ops->vidioc_subscribe_event(fh, arg);
26655bc3cb74SMauro Carvalho Chehab }
26665bc3cb74SMauro Carvalho Chehab 
26675bc3cb74SMauro Carvalho Chehab static int v4l_unsubscribe_event(const struct v4l2_ioctl_ops *ops,
26685bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
26695bc3cb74SMauro Carvalho Chehab {
26705bc3cb74SMauro Carvalho Chehab 	return ops->vidioc_unsubscribe_event(fh, arg);
26715bc3cb74SMauro Carvalho Chehab }
26725bc3cb74SMauro Carvalho Chehab 
26735bc3cb74SMauro Carvalho Chehab static int v4l_g_sliced_vbi_cap(const struct v4l2_ioctl_ops *ops,
26745bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
26755bc3cb74SMauro Carvalho Chehab {
26765bc3cb74SMauro Carvalho Chehab 	struct v4l2_sliced_vbi_cap *p = arg;
26774b20259fSHans Verkuil 	int ret = check_fmt(file, p->type);
26784b20259fSHans Verkuil 
26794b20259fSHans Verkuil 	if (ret)
26804b20259fSHans Verkuil 		return ret;
26815bc3cb74SMauro Carvalho Chehab 
26825bc3cb74SMauro Carvalho Chehab 	/* Clear up to type, everything after type is zeroed already */
26835bc3cb74SMauro Carvalho Chehab 	memset(p, 0, offsetof(struct v4l2_sliced_vbi_cap, type));
26845bc3cb74SMauro Carvalho Chehab 
26855bc3cb74SMauro Carvalho Chehab 	return ops->vidioc_g_sliced_vbi_cap(file, fh, p);
26865bc3cb74SMauro Carvalho Chehab }
26875bc3cb74SMauro Carvalho Chehab 
26885bc3cb74SMauro Carvalho Chehab static int v4l_enum_freq_bands(const struct v4l2_ioctl_ops *ops,
26895bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
26905bc3cb74SMauro Carvalho Chehab {
26915bc3cb74SMauro Carvalho Chehab 	struct video_device *vfd = video_devdata(file);
26925bc3cb74SMauro Carvalho Chehab 	struct v4l2_frequency_band *p = arg;
26935bc3cb74SMauro Carvalho Chehab 	enum v4l2_tuner_type type;
26945bc3cb74SMauro Carvalho Chehab 	int err;
26955bc3cb74SMauro Carvalho Chehab 
269684099a28SAntti Palosaari 	if (vfd->vfl_type == VFL_TYPE_SDR) {
2697f3c3ececSAntti Palosaari 		if (p->type != V4L2_TUNER_SDR && p->type != V4L2_TUNER_RF)
269884099a28SAntti Palosaari 			return -EINVAL;
269984099a28SAntti Palosaari 		type = p->type;
270084099a28SAntti Palosaari 	} else {
27015bc3cb74SMauro Carvalho Chehab 		type = (vfd->vfl_type == VFL_TYPE_RADIO) ?
27025bc3cb74SMauro Carvalho Chehab 				V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV;
27035bc3cb74SMauro Carvalho Chehab 		if (type != p->type)
27045bc3cb74SMauro Carvalho Chehab 			return -EINVAL;
270584099a28SAntti Palosaari 	}
2706a7f404afSHans Verkuil 	if (ops->vidioc_enum_freq_bands) {
2707a7f404afSHans Verkuil 		err = ops->vidioc_enum_freq_bands(file, fh, p);
2708a7f404afSHans Verkuil 		if (err != -ENOTTY)
2709a7f404afSHans Verkuil 			return err;
2710a7f404afSHans Verkuil 	}
271173f35418SHans Verkuil 	if (is_valid_ioctl(vfd, VIDIOC_G_TUNER)) {
27125bc3cb74SMauro Carvalho Chehab 		struct v4l2_tuner t = {
27135bc3cb74SMauro Carvalho Chehab 			.index = p->tuner,
27145bc3cb74SMauro Carvalho Chehab 			.type = type,
27155bc3cb74SMauro Carvalho Chehab 		};
27165bc3cb74SMauro Carvalho Chehab 
271779e8c7beSMauro Carvalho Chehab 		if (p->index)
271879e8c7beSMauro Carvalho Chehab 			return -EINVAL;
27195bc3cb74SMauro Carvalho Chehab 		err = ops->vidioc_g_tuner(file, fh, &t);
27205bc3cb74SMauro Carvalho Chehab 		if (err)
27215bc3cb74SMauro Carvalho Chehab 			return err;
27225bc3cb74SMauro Carvalho Chehab 		p->capability = t.capability | V4L2_TUNER_CAP_FREQ_BANDS;
27235bc3cb74SMauro Carvalho Chehab 		p->rangelow = t.rangelow;
27245bc3cb74SMauro Carvalho Chehab 		p->rangehigh = t.rangehigh;
27255bc3cb74SMauro Carvalho Chehab 		p->modulation = (type == V4L2_TUNER_RADIO) ?
27265bc3cb74SMauro Carvalho Chehab 			V4L2_BAND_MODULATION_FM : V4L2_BAND_MODULATION_VSB;
27275bc3cb74SMauro Carvalho Chehab 		return 0;
27285bc3cb74SMauro Carvalho Chehab 	}
272973f35418SHans Verkuil 	if (is_valid_ioctl(vfd, VIDIOC_G_MODULATOR)) {
27305bc3cb74SMauro Carvalho Chehab 		struct v4l2_modulator m = {
27315bc3cb74SMauro Carvalho Chehab 			.index = p->tuner,
27325bc3cb74SMauro Carvalho Chehab 		};
27335bc3cb74SMauro Carvalho Chehab 
27345bc3cb74SMauro Carvalho Chehab 		if (type != V4L2_TUNER_RADIO)
27355bc3cb74SMauro Carvalho Chehab 			return -EINVAL;
273679e8c7beSMauro Carvalho Chehab 		if (p->index)
273779e8c7beSMauro Carvalho Chehab 			return -EINVAL;
27385bc3cb74SMauro Carvalho Chehab 		err = ops->vidioc_g_modulator(file, fh, &m);
27395bc3cb74SMauro Carvalho Chehab 		if (err)
27405bc3cb74SMauro Carvalho Chehab 			return err;
27415bc3cb74SMauro Carvalho Chehab 		p->capability = m.capability | V4L2_TUNER_CAP_FREQ_BANDS;
27425bc3cb74SMauro Carvalho Chehab 		p->rangelow = m.rangelow;
27435bc3cb74SMauro Carvalho Chehab 		p->rangehigh = m.rangehigh;
27445bc3cb74SMauro Carvalho Chehab 		p->modulation = (type == V4L2_TUNER_RADIO) ?
27455bc3cb74SMauro Carvalho Chehab 			V4L2_BAND_MODULATION_FM : V4L2_BAND_MODULATION_VSB;
27465bc3cb74SMauro Carvalho Chehab 		return 0;
27475bc3cb74SMauro Carvalho Chehab 	}
27485bc3cb74SMauro Carvalho Chehab 	return -ENOTTY;
27495bc3cb74SMauro Carvalho Chehab }
27505bc3cb74SMauro Carvalho Chehab 
27515bc3cb74SMauro Carvalho Chehab struct v4l2_ioctl_info {
27525bc3cb74SMauro Carvalho Chehab 	unsigned int ioctl;
27535bc3cb74SMauro Carvalho Chehab 	u32 flags;
27545bc3cb74SMauro Carvalho Chehab 	const char * const name;
27553ad3b7a2SSami Tolvanen 	int (*func)(const struct v4l2_ioctl_ops *ops, struct file *file,
27563ad3b7a2SSami Tolvanen 		    void *fh, void *p);
27575bc3cb74SMauro Carvalho Chehab 	void (*debug)(const void *arg, bool write_only);
27585bc3cb74SMauro Carvalho Chehab };
27595bc3cb74SMauro Carvalho Chehab 
27605bc3cb74SMauro Carvalho Chehab /* This control needs a priority check */
27615bc3cb74SMauro Carvalho Chehab #define INFO_FL_PRIO		(1 << 0)
27625bc3cb74SMauro Carvalho Chehab /* This control can be valid if the filehandle passes a control handler. */
27635bc3cb74SMauro Carvalho Chehab #define INFO_FL_CTRL		(1 << 1)
27645bc3cb74SMauro Carvalho Chehab /* Queuing ioctl */
27653ad3b7a2SSami Tolvanen #define INFO_FL_QUEUE		(1 << 2)
2766043f77edSHans Verkuil /* Always copy back result, even on error */
27673ad3b7a2SSami Tolvanen #define INFO_FL_ALWAYS_COPY	(1 << 3)
27685bc3cb74SMauro Carvalho Chehab /* Zero struct from after the field to the end */
27695bc3cb74SMauro Carvalho Chehab #define INFO_FL_CLEAR(v4l2_struct, field)			\
27705bc3cb74SMauro Carvalho Chehab 	((offsetof(struct v4l2_struct, field) +			\
2771c593642cSPankaj Bharadiya 	  sizeof_field(struct v4l2_struct, field)) << 16)
27725bc3cb74SMauro Carvalho Chehab #define INFO_FL_CLEAR_MASK	(_IOC_SIZEMASK << 16)
27735bc3cb74SMauro Carvalho Chehab 
27743ad3b7a2SSami Tolvanen #define DEFINE_V4L_STUB_FUNC(_vidioc)				\
27753ad3b7a2SSami Tolvanen 	static int v4l_stub_ ## _vidioc(			\
27763ad3b7a2SSami Tolvanen 			const struct v4l2_ioctl_ops *ops,	\
27773ad3b7a2SSami Tolvanen 			struct file *file, void *fh, void *p)	\
27783ad3b7a2SSami Tolvanen 	{							\
27793ad3b7a2SSami Tolvanen 		return ops->vidioc_ ## _vidioc(file, fh, p);	\
27803ad3b7a2SSami Tolvanen 	}
27813ad3b7a2SSami Tolvanen 
27823ad3b7a2SSami Tolvanen #define IOCTL_INFO(_ioctl, _func, _debug, _flags)		\
27835bc3cb74SMauro Carvalho Chehab 	[_IOC_NR(_ioctl)] = {					\
27845bc3cb74SMauro Carvalho Chehab 		.ioctl = _ioctl,				\
27853ad3b7a2SSami Tolvanen 		.flags = _flags,				\
27865bc3cb74SMauro Carvalho Chehab 		.name = #_ioctl,				\
27873ad3b7a2SSami Tolvanen 		.func = _func,					\
27885bc3cb74SMauro Carvalho Chehab 		.debug = _debug,				\
27895bc3cb74SMauro Carvalho Chehab 	}
27905bc3cb74SMauro Carvalho Chehab 
27913ad3b7a2SSami Tolvanen DEFINE_V4L_STUB_FUNC(g_fbuf)
27923ad3b7a2SSami Tolvanen DEFINE_V4L_STUB_FUNC(s_fbuf)
27933ad3b7a2SSami Tolvanen DEFINE_V4L_STUB_FUNC(expbuf)
27943ad3b7a2SSami Tolvanen DEFINE_V4L_STUB_FUNC(g_std)
27953ad3b7a2SSami Tolvanen DEFINE_V4L_STUB_FUNC(g_audio)
27963ad3b7a2SSami Tolvanen DEFINE_V4L_STUB_FUNC(s_audio)
27973ad3b7a2SSami Tolvanen DEFINE_V4L_STUB_FUNC(g_edid)
27983ad3b7a2SSami Tolvanen DEFINE_V4L_STUB_FUNC(s_edid)
27993ad3b7a2SSami Tolvanen DEFINE_V4L_STUB_FUNC(g_audout)
28003ad3b7a2SSami Tolvanen DEFINE_V4L_STUB_FUNC(s_audout)
28013ad3b7a2SSami Tolvanen DEFINE_V4L_STUB_FUNC(g_jpegcomp)
28023ad3b7a2SSami Tolvanen DEFINE_V4L_STUB_FUNC(s_jpegcomp)
28033ad3b7a2SSami Tolvanen DEFINE_V4L_STUB_FUNC(enumaudio)
28043ad3b7a2SSami Tolvanen DEFINE_V4L_STUB_FUNC(enumaudout)
28053ad3b7a2SSami Tolvanen DEFINE_V4L_STUB_FUNC(enum_framesizes)
28063ad3b7a2SSami Tolvanen DEFINE_V4L_STUB_FUNC(enum_frameintervals)
28073ad3b7a2SSami Tolvanen DEFINE_V4L_STUB_FUNC(g_enc_index)
28083ad3b7a2SSami Tolvanen DEFINE_V4L_STUB_FUNC(encoder_cmd)
28093ad3b7a2SSami Tolvanen DEFINE_V4L_STUB_FUNC(try_encoder_cmd)
28103ad3b7a2SSami Tolvanen DEFINE_V4L_STUB_FUNC(decoder_cmd)
28113ad3b7a2SSami Tolvanen DEFINE_V4L_STUB_FUNC(try_decoder_cmd)
28123ad3b7a2SSami Tolvanen DEFINE_V4L_STUB_FUNC(s_dv_timings)
28133ad3b7a2SSami Tolvanen DEFINE_V4L_STUB_FUNC(g_dv_timings)
28143ad3b7a2SSami Tolvanen DEFINE_V4L_STUB_FUNC(enum_dv_timings)
28153ad3b7a2SSami Tolvanen DEFINE_V4L_STUB_FUNC(query_dv_timings)
28163ad3b7a2SSami Tolvanen DEFINE_V4L_STUB_FUNC(dv_timings_cap)
28175bc3cb74SMauro Carvalho Chehab 
28187c91d0a4SEric Biggers static const struct v4l2_ioctl_info v4l2_ioctls[] = {
28193ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_QUERYCAP, v4l_querycap, v4l_print_querycap, 0),
2820e5b6b07aSLaurent Pinchart 	IOCTL_INFO(VIDIOC_ENUM_FMT, v4l_enum_fmt, v4l_print_fmtdesc, 0),
28213ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_G_FMT, v4l_g_fmt, v4l_print_format, 0),
28223ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_S_FMT, v4l_s_fmt, v4l_print_format, INFO_FL_PRIO),
28233ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_REQBUFS, v4l_reqbufs, v4l_print_requestbuffers, INFO_FL_PRIO | INFO_FL_QUEUE),
28243ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_QUERYBUF, v4l_querybuf, v4l_print_buffer, INFO_FL_QUEUE | INFO_FL_CLEAR(v4l2_buffer, length)),
28253ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_G_FBUF, v4l_stub_g_fbuf, v4l_print_framebuffer, 0),
28263ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_S_FBUF, v4l_stub_s_fbuf, v4l_print_framebuffer, INFO_FL_PRIO),
28273ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_OVERLAY, v4l_overlay, v4l_print_u32, INFO_FL_PRIO),
28283ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_QBUF, v4l_qbuf, v4l_print_buffer, INFO_FL_QUEUE),
28293ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_EXPBUF, v4l_stub_expbuf, v4l_print_exportbuffer, INFO_FL_QUEUE | INFO_FL_CLEAR(v4l2_exportbuffer, flags)),
28303ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_DQBUF, v4l_dqbuf, v4l_print_buffer, INFO_FL_QUEUE),
28313ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_STREAMON, v4l_streamon, v4l_print_buftype, INFO_FL_PRIO | INFO_FL_QUEUE),
28323ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_STREAMOFF, v4l_streamoff, v4l_print_buftype, INFO_FL_PRIO | INFO_FL_QUEUE),
28333ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_G_PARM, v4l_g_parm, v4l_print_streamparm, INFO_FL_CLEAR(v4l2_streamparm, type)),
28343ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_S_PARM, v4l_s_parm, v4l_print_streamparm, INFO_FL_PRIO),
28353ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_G_STD, v4l_stub_g_std, v4l_print_std, 0),
28363ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_S_STD, v4l_s_std, v4l_print_std, INFO_FL_PRIO),
28373ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_ENUMSTD, v4l_enumstd, v4l_print_standard, INFO_FL_CLEAR(v4l2_standard, index)),
28383ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_ENUMINPUT, v4l_enuminput, v4l_print_enuminput, INFO_FL_CLEAR(v4l2_input, index)),
28393ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_G_CTRL, v4l_g_ctrl, v4l_print_control, INFO_FL_CTRL | INFO_FL_CLEAR(v4l2_control, id)),
28403ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_S_CTRL, v4l_s_ctrl, v4l_print_control, INFO_FL_PRIO | INFO_FL_CTRL),
28413ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_G_TUNER, v4l_g_tuner, v4l_print_tuner, INFO_FL_CLEAR(v4l2_tuner, index)),
28423ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_S_TUNER, v4l_s_tuner, v4l_print_tuner, INFO_FL_PRIO),
28433ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_G_AUDIO, v4l_stub_g_audio, v4l_print_audio, 0),
28443ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_S_AUDIO, v4l_stub_s_audio, v4l_print_audio, INFO_FL_PRIO),
28453ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_QUERYCTRL, v4l_queryctrl, v4l_print_queryctrl, INFO_FL_CTRL | INFO_FL_CLEAR(v4l2_queryctrl, id)),
28463ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_QUERYMENU, v4l_querymenu, v4l_print_querymenu, INFO_FL_CTRL | INFO_FL_CLEAR(v4l2_querymenu, index)),
2847f645e625SNiklas Söderlund 	IOCTL_INFO(VIDIOC_G_INPUT, v4l_g_input, v4l_print_u32, 0),
28483ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_S_INPUT, v4l_s_input, v4l_print_u32, INFO_FL_PRIO),
28493ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_G_EDID, v4l_stub_g_edid, v4l_print_edid, INFO_FL_ALWAYS_COPY),
28503ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_S_EDID, v4l_stub_s_edid, v4l_print_edid, INFO_FL_PRIO | INFO_FL_ALWAYS_COPY),
2851f645e625SNiklas Söderlund 	IOCTL_INFO(VIDIOC_G_OUTPUT, v4l_g_output, v4l_print_u32, 0),
28523ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_S_OUTPUT, v4l_s_output, v4l_print_u32, INFO_FL_PRIO),
28533ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_ENUMOUTPUT, v4l_enumoutput, v4l_print_enumoutput, INFO_FL_CLEAR(v4l2_output, index)),
28543ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_G_AUDOUT, v4l_stub_g_audout, v4l_print_audioout, 0),
28553ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_S_AUDOUT, v4l_stub_s_audout, v4l_print_audioout, INFO_FL_PRIO),
28563ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_G_MODULATOR, v4l_g_modulator, v4l_print_modulator, INFO_FL_CLEAR(v4l2_modulator, index)),
28573ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_S_MODULATOR, v4l_s_modulator, v4l_print_modulator, INFO_FL_PRIO),
28583ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_G_FREQUENCY, v4l_g_frequency, v4l_print_frequency, INFO_FL_CLEAR(v4l2_frequency, tuner)),
28593ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_S_FREQUENCY, v4l_s_frequency, v4l_print_frequency, INFO_FL_PRIO),
28603ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_CROPCAP, v4l_cropcap, v4l_print_cropcap, INFO_FL_CLEAR(v4l2_cropcap, type)),
28613ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_G_CROP, v4l_g_crop, v4l_print_crop, INFO_FL_CLEAR(v4l2_crop, type)),
28623ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_S_CROP, v4l_s_crop, v4l_print_crop, INFO_FL_PRIO),
28633ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_G_SELECTION, v4l_g_selection, v4l_print_selection, INFO_FL_CLEAR(v4l2_selection, r)),
28643ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_S_SELECTION, v4l_s_selection, v4l_print_selection, INFO_FL_PRIO | INFO_FL_CLEAR(v4l2_selection, r)),
28653ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_G_JPEGCOMP, v4l_stub_g_jpegcomp, v4l_print_jpegcompression, 0),
28663ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_S_JPEGCOMP, v4l_stub_s_jpegcomp, v4l_print_jpegcompression, INFO_FL_PRIO),
28673ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_QUERYSTD, v4l_querystd, v4l_print_std, 0),
28683ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_TRY_FMT, v4l_try_fmt, v4l_print_format, 0),
28693ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_ENUMAUDIO, v4l_stub_enumaudio, v4l_print_audio, INFO_FL_CLEAR(v4l2_audio, index)),
28703ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_ENUMAUDOUT, v4l_stub_enumaudout, v4l_print_audioout, INFO_FL_CLEAR(v4l2_audioout, index)),
28713ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_G_PRIORITY, v4l_g_priority, v4l_print_u32, 0),
28723ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_S_PRIORITY, v4l_s_priority, v4l_print_u32, INFO_FL_PRIO),
28733ad3b7a2SSami 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)),
28743ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_LOG_STATUS, v4l_log_status, v4l_print_newline, 0),
2875f0da34f3SHans Verkuil 	IOCTL_INFO(VIDIOC_G_EXT_CTRLS, v4l_g_ext_ctrls, v4l_print_ext_controls, INFO_FL_CTRL | INFO_FL_ALWAYS_COPY),
2876f0da34f3SHans Verkuil 	IOCTL_INFO(VIDIOC_S_EXT_CTRLS, v4l_s_ext_ctrls, v4l_print_ext_controls, INFO_FL_PRIO | INFO_FL_CTRL | INFO_FL_ALWAYS_COPY),
2877f0da34f3SHans Verkuil 	IOCTL_INFO(VIDIOC_TRY_EXT_CTRLS, v4l_try_ext_ctrls, v4l_print_ext_controls, INFO_FL_CTRL | INFO_FL_ALWAYS_COPY),
28783ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_ENUM_FRAMESIZES, v4l_stub_enum_framesizes, v4l_print_frmsizeenum, INFO_FL_CLEAR(v4l2_frmsizeenum, pixel_format)),
28793ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_ENUM_FRAMEINTERVALS, v4l_stub_enum_frameintervals, v4l_print_frmivalenum, INFO_FL_CLEAR(v4l2_frmivalenum, height)),
28803ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_G_ENC_INDEX, v4l_stub_g_enc_index, v4l_print_enc_idx, 0),
28813ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_ENCODER_CMD, v4l_stub_encoder_cmd, v4l_print_encoder_cmd, INFO_FL_PRIO | INFO_FL_CLEAR(v4l2_encoder_cmd, flags)),
28823ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_TRY_ENCODER_CMD, v4l_stub_try_encoder_cmd, v4l_print_encoder_cmd, INFO_FL_CLEAR(v4l2_encoder_cmd, flags)),
28833ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_DECODER_CMD, v4l_stub_decoder_cmd, v4l_print_decoder_cmd, INFO_FL_PRIO),
28843ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_TRY_DECODER_CMD, v4l_stub_try_decoder_cmd, v4l_print_decoder_cmd, 0),
28853ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_DBG_S_REGISTER, v4l_dbg_s_register, v4l_print_dbg_register, 0),
28863ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_DBG_G_REGISTER, v4l_dbg_g_register, v4l_print_dbg_register, 0),
28873ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_S_HW_FREQ_SEEK, v4l_s_hw_freq_seek, v4l_print_hw_freq_seek, INFO_FL_PRIO),
28883ad3b7a2SSami 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)),
28893ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_G_DV_TIMINGS, v4l_stub_g_dv_timings, v4l_print_dv_timings, 0),
28903ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_DQEVENT, v4l_dqevent, v4l_print_event, 0),
28913ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_SUBSCRIBE_EVENT, v4l_subscribe_event, v4l_print_event_subscription, 0),
28923ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_UNSUBSCRIBE_EVENT, v4l_unsubscribe_event, v4l_print_event_subscription, 0),
28933ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_CREATE_BUFS, v4l_create_bufs, v4l_print_create_buffers, INFO_FL_PRIO | INFO_FL_QUEUE),
28943ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_PREPARE_BUF, v4l_prepare_buf, v4l_print_buffer, INFO_FL_QUEUE),
28953ad3b7a2SSami 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)),
28963ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_QUERY_DV_TIMINGS, v4l_stub_query_dv_timings, v4l_print_dv_timings, INFO_FL_ALWAYS_COPY),
28973ad3b7a2SSami 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)),
28983ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_ENUM_FREQ_BANDS, v4l_enum_freq_bands, v4l_print_freq_band, 0),
28993ad3b7a2SSami 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)),
29003ad3b7a2SSami 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)),
29015bc3cb74SMauro Carvalho Chehab };
29025bc3cb74SMauro Carvalho Chehab #define V4L2_IOCTLS ARRAY_SIZE(v4l2_ioctls)
29035bc3cb74SMauro Carvalho Chehab 
290473a11062SHans Verkuil static bool v4l2_is_known_ioctl(unsigned int cmd)
29055bc3cb74SMauro Carvalho Chehab {
29065bc3cb74SMauro Carvalho Chehab 	if (_IOC_NR(cmd) >= V4L2_IOCTLS)
29075bc3cb74SMauro Carvalho Chehab 		return false;
29085bc3cb74SMauro Carvalho Chehab 	return v4l2_ioctls[_IOC_NR(cmd)].ioctl == cmd;
29095bc3cb74SMauro Carvalho Chehab }
29105bc3cb74SMauro Carvalho Chehab 
291173a11062SHans Verkuil static struct mutex *v4l2_ioctl_get_lock(struct video_device *vdev,
2912d862bc08SHans Verkuil 					 struct v4l2_fh *vfh, unsigned int cmd,
2913d862bc08SHans Verkuil 					 void *arg)
29145bc3cb74SMauro Carvalho Chehab {
29155bc3cb74SMauro Carvalho Chehab 	if (_IOC_NR(cmd) >= V4L2_IOCTLS)
29165bc3cb74SMauro Carvalho Chehab 		return vdev->lock;
2917d862bc08SHans Verkuil 	if (vfh && vfh->m2m_ctx &&
2918d862bc08SHans Verkuil 	    (v4l2_ioctls[_IOC_NR(cmd)].flags & INFO_FL_QUEUE)) {
2919542a522dSEzequiel Garcia 		if (vfh->m2m_ctx->q_lock)
2920542a522dSEzequiel Garcia 			return vfh->m2m_ctx->q_lock;
2921d862bc08SHans Verkuil 	}
29225bc3cb74SMauro Carvalho Chehab 	if (vdev->queue && vdev->queue->lock &&
29235bc3cb74SMauro Carvalho Chehab 			(v4l2_ioctls[_IOC_NR(cmd)].flags & INFO_FL_QUEUE))
29245bc3cb74SMauro Carvalho Chehab 		return vdev->queue->lock;
29255bc3cb74SMauro Carvalho Chehab 	return vdev->lock;
29265bc3cb74SMauro Carvalho Chehab }
29275bc3cb74SMauro Carvalho Chehab 
29285bc3cb74SMauro Carvalho Chehab /* Common ioctl debug function. This function can be used by
29295bc3cb74SMauro Carvalho Chehab    external ioctl messages as well as internal V4L ioctl */
29305bc3cb74SMauro Carvalho Chehab void v4l_printk_ioctl(const char *prefix, unsigned int cmd)
29315bc3cb74SMauro Carvalho Chehab {
29325bc3cb74SMauro Carvalho Chehab 	const char *dir, *type;
29335bc3cb74SMauro Carvalho Chehab 
29345bc3cb74SMauro Carvalho Chehab 	if (prefix)
29355bc3cb74SMauro Carvalho Chehab 		printk(KERN_DEBUG "%s: ", prefix);
29365bc3cb74SMauro Carvalho Chehab 
29375bc3cb74SMauro Carvalho Chehab 	switch (_IOC_TYPE(cmd)) {
29385bc3cb74SMauro Carvalho Chehab 	case 'd':
29395bc3cb74SMauro Carvalho Chehab 		type = "v4l2_int";
29405bc3cb74SMauro Carvalho Chehab 		break;
29415bc3cb74SMauro Carvalho Chehab 	case 'V':
29425bc3cb74SMauro Carvalho Chehab 		if (_IOC_NR(cmd) >= V4L2_IOCTLS) {
29435bc3cb74SMauro Carvalho Chehab 			type = "v4l2";
29445bc3cb74SMauro Carvalho Chehab 			break;
29455bc3cb74SMauro Carvalho Chehab 		}
29465bc3cb74SMauro Carvalho Chehab 		pr_cont("%s", v4l2_ioctls[_IOC_NR(cmd)].name);
29475bc3cb74SMauro Carvalho Chehab 		return;
29485bc3cb74SMauro Carvalho Chehab 	default:
29495bc3cb74SMauro Carvalho Chehab 		type = "unknown";
29505bc3cb74SMauro Carvalho Chehab 		break;
29515bc3cb74SMauro Carvalho Chehab 	}
29525bc3cb74SMauro Carvalho Chehab 
29535bc3cb74SMauro Carvalho Chehab 	switch (_IOC_DIR(cmd)) {
29545bc3cb74SMauro Carvalho Chehab 	case _IOC_NONE:              dir = "--"; break;
29555bc3cb74SMauro Carvalho Chehab 	case _IOC_READ:              dir = "r-"; break;
29565bc3cb74SMauro Carvalho Chehab 	case _IOC_WRITE:             dir = "-w"; break;
29575bc3cb74SMauro Carvalho Chehab 	case _IOC_READ | _IOC_WRITE: dir = "rw"; break;
29585bc3cb74SMauro Carvalho Chehab 	default:                     dir = "*ERR*"; break;
29595bc3cb74SMauro Carvalho Chehab 	}
29605bc3cb74SMauro Carvalho Chehab 	pr_cont("%s ioctl '%c', dir=%s, #%d (0x%08x)",
29615bc3cb74SMauro Carvalho Chehab 		type, _IOC_TYPE(cmd), dir, _IOC_NR(cmd), cmd);
29625bc3cb74SMauro Carvalho Chehab }
29635bc3cb74SMauro Carvalho Chehab EXPORT_SYMBOL(v4l_printk_ioctl);
29645bc3cb74SMauro Carvalho Chehab 
29655bc3cb74SMauro Carvalho Chehab static long __video_do_ioctl(struct file *file,
29665bc3cb74SMauro Carvalho Chehab 		unsigned int cmd, void *arg)
29675bc3cb74SMauro Carvalho Chehab {
29685bc3cb74SMauro Carvalho Chehab 	struct video_device *vfd = video_devdata(file);
2969cc6eddcdSHans Verkuil 	struct mutex *req_queue_lock = NULL;
297073a11062SHans Verkuil 	struct mutex *lock; /* ioctl serialization mutex */
29715bc3cb74SMauro Carvalho Chehab 	const struct v4l2_ioctl_ops *ops = vfd->ioctl_ops;
29725bc3cb74SMauro Carvalho Chehab 	bool write_only = false;
29735bc3cb74SMauro Carvalho Chehab 	struct v4l2_ioctl_info default_info;
29745bc3cb74SMauro Carvalho Chehab 	const struct v4l2_ioctl_info *info;
29755bc3cb74SMauro Carvalho Chehab 	void *fh = file->private_data;
29765bc3cb74SMauro Carvalho Chehab 	struct v4l2_fh *vfh = NULL;
297717028cdbSHans Verkuil 	int dev_debug = vfd->dev_debug;
29785bc3cb74SMauro Carvalho Chehab 	long ret = -ENOTTY;
29795bc3cb74SMauro Carvalho Chehab 
29805bc3cb74SMauro Carvalho Chehab 	if (ops == NULL) {
29815bc3cb74SMauro Carvalho Chehab 		pr_warn("%s: has no ioctl_ops.\n",
29825bc3cb74SMauro Carvalho Chehab 				video_device_node_name(vfd));
29835bc3cb74SMauro Carvalho Chehab 		return ret;
29845bc3cb74SMauro Carvalho Chehab 	}
29855bc3cb74SMauro Carvalho Chehab 
2986b7284bb0SRamakrishnan Muthukrishnan 	if (test_bit(V4L2_FL_USES_V4L2_FH, &vfd->flags))
29875bc3cb74SMauro Carvalho Chehab 		vfh = file->private_data;
29885bc3cb74SMauro Carvalho Chehab 
2989cc6eddcdSHans Verkuil 	/*
2990cc6eddcdSHans Verkuil 	 * We need to serialize streamon/off with queueing new requests.
2991cc6eddcdSHans Verkuil 	 * These ioctls may trigger the cancellation of a streaming
2992cc6eddcdSHans Verkuil 	 * operation, and that should not be mixed with queueing a new
2993cc6eddcdSHans Verkuil 	 * request at the same time.
2994cc6eddcdSHans Verkuil 	 */
2995cc6eddcdSHans Verkuil 	if (v4l2_device_supports_requests(vfd->v4l2_dev) &&
2996cc6eddcdSHans Verkuil 	    (cmd == VIDIOC_STREAMON || cmd == VIDIOC_STREAMOFF)) {
2997cc6eddcdSHans Verkuil 		req_queue_lock = &vfd->v4l2_dev->mdev->req_queue_mutex;
2998cc6eddcdSHans Verkuil 
2999cc6eddcdSHans Verkuil 		if (mutex_lock_interruptible(req_queue_lock))
3000cc6eddcdSHans Verkuil 			return -ERESTARTSYS;
3001cc6eddcdSHans Verkuil 	}
3002cc6eddcdSHans Verkuil 
3003d862bc08SHans Verkuil 	lock = v4l2_ioctl_get_lock(vfd, vfh, cmd, arg);
300473a11062SHans Verkuil 
3005cc6eddcdSHans Verkuil 	if (lock && mutex_lock_interruptible(lock)) {
3006cc6eddcdSHans Verkuil 		if (req_queue_lock)
3007cc6eddcdSHans Verkuil 			mutex_unlock(req_queue_lock);
300873a11062SHans Verkuil 		return -ERESTARTSYS;
3009cc6eddcdSHans Verkuil 	}
301073a11062SHans Verkuil 
301173a11062SHans Verkuil 	if (!video_is_registered(vfd)) {
301273a11062SHans Verkuil 		ret = -ENODEV;
301373a11062SHans Verkuil 		goto unlock;
301473a11062SHans Verkuil 	}
301573a11062SHans Verkuil 
30165bc3cb74SMauro Carvalho Chehab 	if (v4l2_is_known_ioctl(cmd)) {
30175bc3cb74SMauro Carvalho Chehab 		info = &v4l2_ioctls[_IOC_NR(cmd)];
30185bc3cb74SMauro Carvalho Chehab 
30195bc3cb74SMauro Carvalho Chehab 		if (!test_bit(_IOC_NR(cmd), vfd->valid_ioctls) &&
30205bc3cb74SMauro Carvalho Chehab 		    !((info->flags & INFO_FL_CTRL) && vfh && vfh->ctrl_handler))
30215bc3cb74SMauro Carvalho Chehab 			goto done;
30225bc3cb74SMauro Carvalho Chehab 
3023b7284bb0SRamakrishnan Muthukrishnan 		if (vfh && (info->flags & INFO_FL_PRIO)) {
30245bc3cb74SMauro Carvalho Chehab 			ret = v4l2_prio_check(vfd->prio, vfh->prio);
30255bc3cb74SMauro Carvalho Chehab 			if (ret)
30265bc3cb74SMauro Carvalho Chehab 				goto done;
30275bc3cb74SMauro Carvalho Chehab 		}
30285bc3cb74SMauro Carvalho Chehab 	} else {
30295bc3cb74SMauro Carvalho Chehab 		default_info.ioctl = cmd;
30305bc3cb74SMauro Carvalho Chehab 		default_info.flags = 0;
30315bc3cb74SMauro Carvalho Chehab 		default_info.debug = v4l_print_default;
30325bc3cb74SMauro Carvalho Chehab 		info = &default_info;
30335bc3cb74SMauro Carvalho Chehab 	}
30345bc3cb74SMauro Carvalho Chehab 
30355bc3cb74SMauro Carvalho Chehab 	write_only = _IOC_DIR(cmd) == _IOC_WRITE;
30363ad3b7a2SSami Tolvanen 	if (info != &default_info) {
30373ad3b7a2SSami Tolvanen 		ret = info->func(ops, file, fh, arg);
30385bc3cb74SMauro Carvalho Chehab 	} else if (!ops->vidioc_default) {
30395bc3cb74SMauro Carvalho Chehab 		ret = -ENOTTY;
30405bc3cb74SMauro Carvalho Chehab 	} else {
30415bc3cb74SMauro Carvalho Chehab 		ret = ops->vidioc_default(file, fh,
3042b7284bb0SRamakrishnan Muthukrishnan 			vfh ? v4l2_prio_check(vfd->prio, vfh->prio) >= 0 : 0,
30435bc3cb74SMauro Carvalho Chehab 			cmd, arg);
30445bc3cb74SMauro Carvalho Chehab 	}
30455bc3cb74SMauro Carvalho Chehab 
30465bc3cb74SMauro Carvalho Chehab done:
304717028cdbSHans Verkuil 	if (dev_debug & (V4L2_DEV_DEBUG_IOCTL | V4L2_DEV_DEBUG_IOCTL_ARG)) {
304817028cdbSHans Verkuil 		if (!(dev_debug & V4L2_DEV_DEBUG_STREAMING) &&
304917028cdbSHans Verkuil 		    (cmd == VIDIOC_QBUF || cmd == VIDIOC_DQBUF))
30505983d3bcSHans Verkuil 			goto unlock;
305117028cdbSHans Verkuil 
30525bc3cb74SMauro Carvalho Chehab 		v4l_printk_ioctl(video_device_node_name(vfd), cmd);
30535bc3cb74SMauro Carvalho Chehab 		if (ret < 0)
3054505d04bdSHans Verkuil 			pr_cont(": error %ld", ret);
305517028cdbSHans Verkuil 		if (!(dev_debug & V4L2_DEV_DEBUG_IOCTL_ARG))
30565bc3cb74SMauro Carvalho Chehab 			pr_cont("\n");
30575bc3cb74SMauro Carvalho Chehab 		else if (_IOC_DIR(cmd) == _IOC_NONE)
30585bc3cb74SMauro Carvalho Chehab 			info->debug(arg, write_only);
30595bc3cb74SMauro Carvalho Chehab 		else {
30605bc3cb74SMauro Carvalho Chehab 			pr_cont(": ");
30615bc3cb74SMauro Carvalho Chehab 			info->debug(arg, write_only);
30625bc3cb74SMauro Carvalho Chehab 		}
30635bc3cb74SMauro Carvalho Chehab 	}
30645bc3cb74SMauro Carvalho Chehab 
306573a11062SHans Verkuil unlock:
306673a11062SHans Verkuil 	if (lock)
306773a11062SHans Verkuil 		mutex_unlock(lock);
3068cc6eddcdSHans Verkuil 	if (req_queue_lock)
3069cc6eddcdSHans Verkuil 		mutex_unlock(req_queue_lock);
30705bc3cb74SMauro Carvalho Chehab 	return ret;
30715bc3cb74SMauro Carvalho Chehab }
30725bc3cb74SMauro Carvalho Chehab 
30735bc3cb74SMauro Carvalho Chehab static int check_array_args(unsigned int cmd, void *parg, size_t *array_size,
3074ba2d35c1SHans Verkuil 			    void __user **user_ptr, void ***kernel_ptr)
30755bc3cb74SMauro Carvalho Chehab {
30765bc3cb74SMauro Carvalho Chehab 	int ret = 0;
30775bc3cb74SMauro Carvalho Chehab 
30785bc3cb74SMauro Carvalho Chehab 	switch (cmd) {
307996b1a702SHans Verkuil 	case VIDIOC_PREPARE_BUF:
30805bc3cb74SMauro Carvalho Chehab 	case VIDIOC_QUERYBUF:
30815bc3cb74SMauro Carvalho Chehab 	case VIDIOC_QBUF:
30825bc3cb74SMauro Carvalho Chehab 	case VIDIOC_DQBUF: {
30835bc3cb74SMauro Carvalho Chehab 		struct v4l2_buffer *buf = parg;
30845bc3cb74SMauro Carvalho Chehab 
30855bc3cb74SMauro Carvalho Chehab 		if (V4L2_TYPE_IS_MULTIPLANAR(buf->type) && buf->length > 0) {
30865bc3cb74SMauro Carvalho Chehab 			if (buf->length > VIDEO_MAX_PLANES) {
30875bc3cb74SMauro Carvalho Chehab 				ret = -EINVAL;
30885bc3cb74SMauro Carvalho Chehab 				break;
30895bc3cb74SMauro Carvalho Chehab 			}
30905bc3cb74SMauro Carvalho Chehab 			*user_ptr = (void __user *)buf->m.planes;
3091ba2d35c1SHans Verkuil 			*kernel_ptr = (void **)&buf->m.planes;
30925bc3cb74SMauro Carvalho Chehab 			*array_size = sizeof(struct v4l2_plane) * buf->length;
30935bc3cb74SMauro Carvalho Chehab 			ret = 1;
30945bc3cb74SMauro Carvalho Chehab 		}
30955bc3cb74SMauro Carvalho Chehab 		break;
30965bc3cb74SMauro Carvalho Chehab 	}
30975bc3cb74SMauro Carvalho Chehab 
3098dd519bb3SHans Verkuil 	case VIDIOC_G_EDID:
3099dd519bb3SHans Verkuil 	case VIDIOC_S_EDID: {
3100dd519bb3SHans Verkuil 		struct v4l2_edid *edid = parg;
3101ed45ce2cSHans Verkuil 
3102ed45ce2cSHans Verkuil 		if (edid->blocks) {
31031b8b10ccSHans Verkuil 			if (edid->blocks > 256) {
31041b8b10ccSHans Verkuil 				ret = -EINVAL;
31051b8b10ccSHans Verkuil 				break;
31061b8b10ccSHans Verkuil 			}
3107ed45ce2cSHans Verkuil 			*user_ptr = (void __user *)edid->edid;
3108ba2d35c1SHans Verkuil 			*kernel_ptr = (void **)&edid->edid;
3109ed45ce2cSHans Verkuil 			*array_size = edid->blocks * 128;
3110ed45ce2cSHans Verkuil 			ret = 1;
3111ed45ce2cSHans Verkuil 		}
3112ed45ce2cSHans Verkuil 		break;
3113ed45ce2cSHans Verkuil 	}
3114ed45ce2cSHans Verkuil 
31155bc3cb74SMauro Carvalho Chehab 	case VIDIOC_S_EXT_CTRLS:
31165bc3cb74SMauro Carvalho Chehab 	case VIDIOC_G_EXT_CTRLS:
31175bc3cb74SMauro Carvalho Chehab 	case VIDIOC_TRY_EXT_CTRLS: {
31185bc3cb74SMauro Carvalho Chehab 		struct v4l2_ext_controls *ctrls = parg;
31195bc3cb74SMauro Carvalho Chehab 
31205bc3cb74SMauro Carvalho Chehab 		if (ctrls->count != 0) {
31215bc3cb74SMauro Carvalho Chehab 			if (ctrls->count > V4L2_CID_MAX_CTRLS) {
31225bc3cb74SMauro Carvalho Chehab 				ret = -EINVAL;
31235bc3cb74SMauro Carvalho Chehab 				break;
31245bc3cb74SMauro Carvalho Chehab 			}
31255bc3cb74SMauro Carvalho Chehab 			*user_ptr = (void __user *)ctrls->controls;
3126ba2d35c1SHans Verkuil 			*kernel_ptr = (void **)&ctrls->controls;
31275bc3cb74SMauro Carvalho Chehab 			*array_size = sizeof(struct v4l2_ext_control)
31285bc3cb74SMauro Carvalho Chehab 				    * ctrls->count;
31295bc3cb74SMauro Carvalho Chehab 			ret = 1;
31305bc3cb74SMauro Carvalho Chehab 		}
31315bc3cb74SMauro Carvalho Chehab 		break;
31325bc3cb74SMauro Carvalho Chehab 	}
31333f65c6f6SArnd Bergmann 	case VIDIOC_G_FMT:
31343f65c6f6SArnd Bergmann 	case VIDIOC_S_FMT:
31353f65c6f6SArnd Bergmann 	case VIDIOC_TRY_FMT: {
31363f65c6f6SArnd Bergmann 		struct v4l2_format *fmt = parg;
31373f65c6f6SArnd Bergmann 
31383f65c6f6SArnd Bergmann 		if (fmt->type != V4L2_BUF_TYPE_VIDEO_OVERLAY &&
31393f65c6f6SArnd Bergmann 		    fmt->type != V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY)
31403f65c6f6SArnd Bergmann 			break;
31413f65c6f6SArnd Bergmann 		if (fmt->fmt.win.clipcount > 2048)
31423f65c6f6SArnd Bergmann 			return -EINVAL;
31433f65c6f6SArnd Bergmann 		if (!fmt->fmt.win.clipcount)
31443f65c6f6SArnd Bergmann 			break;
31453f65c6f6SArnd Bergmann 
31463f65c6f6SArnd Bergmann 		*user_ptr = (void __user *)fmt->fmt.win.clips;
31473f65c6f6SArnd Bergmann 		*kernel_ptr = (void **)&fmt->fmt.win.clips;
31483f65c6f6SArnd Bergmann 		*array_size = sizeof(struct v4l2_clip)
31493f65c6f6SArnd Bergmann 				* fmt->fmt.win.clipcount;
31503f65c6f6SArnd Bergmann 
31513f65c6f6SArnd Bergmann 		ret = 1;
31523f65c6f6SArnd Bergmann 		break;
31533f65c6f6SArnd Bergmann 	}
31545bc3cb74SMauro Carvalho Chehab 	}
31555bc3cb74SMauro Carvalho Chehab 
31565bc3cb74SMauro Carvalho Chehab 	return ret;
31575bc3cb74SMauro Carvalho Chehab }
31585bc3cb74SMauro Carvalho Chehab 
3159c8ef1a60SArnd Bergmann static unsigned int video_translate_cmd(unsigned int cmd)
3160c8ef1a60SArnd Bergmann {
3161c344f07aSArnd Bergmann #if !defined(CONFIG_64BIT) && defined(CONFIG_COMPAT_32BIT_TIME)
31621a6c0b36SArnd Bergmann 	switch (cmd) {
31631a6c0b36SArnd Bergmann 	case VIDIOC_DQEVENT_TIME32:
31641a6c0b36SArnd Bergmann 		return VIDIOC_DQEVENT;
3165577c89b0SArnd Bergmann 	case VIDIOC_QUERYBUF_TIME32:
3166577c89b0SArnd Bergmann 		return VIDIOC_QUERYBUF;
3167577c89b0SArnd Bergmann 	case VIDIOC_QBUF_TIME32:
3168577c89b0SArnd Bergmann 		return VIDIOC_QBUF;
3169577c89b0SArnd Bergmann 	case VIDIOC_DQBUF_TIME32:
3170577c89b0SArnd Bergmann 		return VIDIOC_DQBUF;
3171577c89b0SArnd Bergmann 	case VIDIOC_PREPARE_BUF_TIME32:
3172577c89b0SArnd Bergmann 		return VIDIOC_PREPARE_BUF;
31731a6c0b36SArnd Bergmann 	}
3174c344f07aSArnd Bergmann #endif
31758dbcc3faSArnd Bergmann 	if (in_compat_syscall())
31768dbcc3faSArnd Bergmann 		return v4l2_compat_translate_cmd(cmd);
31771a6c0b36SArnd Bergmann 
3178c8ef1a60SArnd Bergmann 	return cmd;
3179c8ef1a60SArnd Bergmann }
3180c8ef1a60SArnd Bergmann 
31818dbcc3faSArnd Bergmann static int video_get_user(void __user *arg, void *parg,
31828dbcc3faSArnd Bergmann 			  unsigned int real_cmd, unsigned int cmd,
3183c8ef1a60SArnd Bergmann 			  bool *always_copy)
3184c8ef1a60SArnd Bergmann {
31858dbcc3faSArnd Bergmann 	unsigned int n = _IOC_SIZE(real_cmd);
31868dbcc3faSArnd Bergmann 	int err = 0;
3187c8ef1a60SArnd Bergmann 
3188c8ef1a60SArnd Bergmann 	if (!(_IOC_DIR(cmd) & _IOC_WRITE)) {
3189c8ef1a60SArnd Bergmann 		/* read-only ioctl */
3190c8ef1a60SArnd Bergmann 		memset(parg, 0, n);
3191c8ef1a60SArnd Bergmann 		return 0;
3192c8ef1a60SArnd Bergmann 	}
3193c8ef1a60SArnd Bergmann 
31948dbcc3faSArnd Bergmann 	/*
31958dbcc3faSArnd Bergmann 	 * In some cases, only a few fields are used as input,
31968dbcc3faSArnd Bergmann 	 * i.e. when the app sets "index" and then the driver
31978dbcc3faSArnd Bergmann 	 * fills in the rest of the structure for the thing
31988dbcc3faSArnd Bergmann 	 * with that index.  We only need to copy up the first
31998dbcc3faSArnd Bergmann 	 * non-input field.
32008dbcc3faSArnd Bergmann 	 */
32018dbcc3faSArnd Bergmann 	if (v4l2_is_known_ioctl(real_cmd)) {
32028dbcc3faSArnd Bergmann 		u32 flags = v4l2_ioctls[_IOC_NR(real_cmd)].flags;
32038dbcc3faSArnd Bergmann 
32048dbcc3faSArnd Bergmann 		if (flags & INFO_FL_CLEAR_MASK)
32058dbcc3faSArnd Bergmann 			n = (flags & INFO_FL_CLEAR_MASK) >> 16;
32068dbcc3faSArnd Bergmann 		*always_copy = flags & INFO_FL_ALWAYS_COPY;
32078dbcc3faSArnd Bergmann 	}
32088dbcc3faSArnd Bergmann 
32098dbcc3faSArnd Bergmann 	if (cmd == real_cmd) {
32108dbcc3faSArnd Bergmann 		if (copy_from_user(parg, (void __user *)arg, n))
32118dbcc3faSArnd Bergmann 			err = -EFAULT;
32128dbcc3faSArnd Bergmann 	} else if (in_compat_syscall()) {
32137b53cca7SArnd Bergmann 		memset(parg, 0, n);
32148dbcc3faSArnd Bergmann 		err = v4l2_compat_get_user(arg, parg, cmd);
32158dbcc3faSArnd Bergmann 	} else {
32167b53cca7SArnd Bergmann 		memset(parg, 0, n);
3217c344f07aSArnd Bergmann #if !defined(CONFIG_64BIT) && defined(CONFIG_COMPAT_32BIT_TIME)
3218c8ef1a60SArnd Bergmann 		switch (cmd) {
3219577c89b0SArnd Bergmann 		case VIDIOC_QUERYBUF_TIME32:
3220577c89b0SArnd Bergmann 		case VIDIOC_QBUF_TIME32:
3221577c89b0SArnd Bergmann 		case VIDIOC_DQBUF_TIME32:
3222577c89b0SArnd Bergmann 		case VIDIOC_PREPARE_BUF_TIME32: {
3223577c89b0SArnd Bergmann 			struct v4l2_buffer_time32 vb32;
3224577c89b0SArnd Bergmann 			struct v4l2_buffer *vb = parg;
3225577c89b0SArnd Bergmann 
3226577c89b0SArnd Bergmann 			if (copy_from_user(&vb32, arg, sizeof(vb32)))
3227577c89b0SArnd Bergmann 				return -EFAULT;
3228577c89b0SArnd Bergmann 
3229577c89b0SArnd Bergmann 			*vb = (struct v4l2_buffer) {
3230577c89b0SArnd Bergmann 				.index		= vb32.index,
3231577c89b0SArnd Bergmann 				.type		= vb32.type,
3232577c89b0SArnd Bergmann 				.bytesused	= vb32.bytesused,
3233577c89b0SArnd Bergmann 				.flags		= vb32.flags,
3234577c89b0SArnd Bergmann 				.field		= vb32.field,
3235577c89b0SArnd Bergmann 				.timestamp.tv_sec	= vb32.timestamp.tv_sec,
3236577c89b0SArnd Bergmann 				.timestamp.tv_usec	= vb32.timestamp.tv_usec,
3237577c89b0SArnd Bergmann 				.timecode	= vb32.timecode,
3238577c89b0SArnd Bergmann 				.sequence	= vb32.sequence,
3239577c89b0SArnd Bergmann 				.memory		= vb32.memory,
3240577c89b0SArnd Bergmann 				.m.userptr	= vb32.m.userptr,
3241577c89b0SArnd Bergmann 				.length		= vb32.length,
3242577c89b0SArnd Bergmann 				.request_fd	= vb32.request_fd,
3243577c89b0SArnd Bergmann 			};
3244577c89b0SArnd Bergmann 			break;
3245577c89b0SArnd Bergmann 		}
3246c8ef1a60SArnd Bergmann 		}
3247c344f07aSArnd Bergmann #endif
32488dbcc3faSArnd Bergmann 	}
3249c8ef1a60SArnd Bergmann 
3250c8ef1a60SArnd Bergmann 	/* zero out anything we don't copy from userspace */
32518dbcc3faSArnd Bergmann 	if (!err && n < _IOC_SIZE(real_cmd))
32528dbcc3faSArnd Bergmann 		memset((u8 *)parg + n, 0, _IOC_SIZE(real_cmd) - n);
32538dbcc3faSArnd Bergmann 	return err;
3254c8ef1a60SArnd Bergmann }
3255c8ef1a60SArnd Bergmann 
32568dbcc3faSArnd Bergmann static int video_put_user(void __user *arg, void *parg,
32578dbcc3faSArnd Bergmann 			  unsigned int real_cmd, unsigned int cmd)
3258c8ef1a60SArnd Bergmann {
3259c8ef1a60SArnd Bergmann 	if (!(_IOC_DIR(cmd) & _IOC_READ))
3260c8ef1a60SArnd Bergmann 		return 0;
3261c8ef1a60SArnd Bergmann 
32628dbcc3faSArnd Bergmann 	if (cmd == real_cmd) {
32638dbcc3faSArnd Bergmann 		/*  Copy results into user buffer  */
32648dbcc3faSArnd Bergmann 		if (copy_to_user(arg, parg, _IOC_SIZE(cmd)))
32658dbcc3faSArnd Bergmann 			return -EFAULT;
32668dbcc3faSArnd Bergmann 		return 0;
32678dbcc3faSArnd Bergmann 	}
32688dbcc3faSArnd Bergmann 
32698dbcc3faSArnd Bergmann 	if (in_compat_syscall())
32708dbcc3faSArnd Bergmann 		return v4l2_compat_put_user(arg, parg, cmd);
32718dbcc3faSArnd Bergmann 
3272c344f07aSArnd Bergmann #if !defined(CONFIG_64BIT) && defined(CONFIG_COMPAT_32BIT_TIME)
3273c8ef1a60SArnd Bergmann 	switch (cmd) {
32741a6c0b36SArnd Bergmann 	case VIDIOC_DQEVENT_TIME32: {
32751a6c0b36SArnd Bergmann 		struct v4l2_event *ev = parg;
32764ffb879eSPeilin Ye 		struct v4l2_event_time32 ev32;
32774ffb879eSPeilin Ye 
32784ffb879eSPeilin Ye 		memset(&ev32, 0, sizeof(ev32));
32794ffb879eSPeilin Ye 
32804ffb879eSPeilin Ye 		ev32.type	= ev->type;
32814ffb879eSPeilin Ye 		ev32.pending	= ev->pending;
32824ffb879eSPeilin Ye 		ev32.sequence	= ev->sequence;
32834ffb879eSPeilin Ye 		ev32.timestamp.tv_sec	= ev->timestamp.tv_sec;
32844ffb879eSPeilin Ye 		ev32.timestamp.tv_nsec	= ev->timestamp.tv_nsec;
32854ffb879eSPeilin Ye 		ev32.id		= ev->id;
32861a6c0b36SArnd Bergmann 
32871a6c0b36SArnd Bergmann 		memcpy(&ev32.u, &ev->u, sizeof(ev->u));
32881a6c0b36SArnd Bergmann 		memcpy(&ev32.reserved, &ev->reserved, sizeof(ev->reserved));
32891a6c0b36SArnd Bergmann 
32901a6c0b36SArnd Bergmann 		if (copy_to_user(arg, &ev32, sizeof(ev32)))
32911a6c0b36SArnd Bergmann 			return -EFAULT;
32921a6c0b36SArnd Bergmann 		break;
32931a6c0b36SArnd Bergmann 	}
3294577c89b0SArnd Bergmann 	case VIDIOC_QUERYBUF_TIME32:
3295577c89b0SArnd Bergmann 	case VIDIOC_QBUF_TIME32:
3296577c89b0SArnd Bergmann 	case VIDIOC_DQBUF_TIME32:
3297577c89b0SArnd Bergmann 	case VIDIOC_PREPARE_BUF_TIME32: {
3298577c89b0SArnd Bergmann 		struct v4l2_buffer *vb = parg;
32994ffb879eSPeilin Ye 		struct v4l2_buffer_time32 vb32;
33004ffb879eSPeilin Ye 
33014ffb879eSPeilin Ye 		memset(&vb32, 0, sizeof(vb32));
33024ffb879eSPeilin Ye 
33034ffb879eSPeilin Ye 		vb32.index	= vb->index;
33044ffb879eSPeilin Ye 		vb32.type	= vb->type;
33054ffb879eSPeilin Ye 		vb32.bytesused	= vb->bytesused;
33064ffb879eSPeilin Ye 		vb32.flags	= vb->flags;
33074ffb879eSPeilin Ye 		vb32.field	= vb->field;
33084ffb879eSPeilin Ye 		vb32.timestamp.tv_sec	= vb->timestamp.tv_sec;
33094ffb879eSPeilin Ye 		vb32.timestamp.tv_usec	= vb->timestamp.tv_usec;
33104ffb879eSPeilin Ye 		vb32.timecode	= vb->timecode;
33114ffb879eSPeilin Ye 		vb32.sequence	= vb->sequence;
33124ffb879eSPeilin Ye 		vb32.memory	= vb->memory;
33134ffb879eSPeilin Ye 		vb32.m.userptr	= vb->m.userptr;
33144ffb879eSPeilin Ye 		vb32.length	= vb->length;
33154ffb879eSPeilin Ye 		vb32.request_fd	= vb->request_fd;
3316577c89b0SArnd Bergmann 
3317577c89b0SArnd Bergmann 		if (copy_to_user(arg, &vb32, sizeof(vb32)))
3318577c89b0SArnd Bergmann 			return -EFAULT;
3319577c89b0SArnd Bergmann 		break;
3320577c89b0SArnd Bergmann 	}
3321c8ef1a60SArnd Bergmann 	}
3322c344f07aSArnd Bergmann #endif
3323c8ef1a60SArnd Bergmann 
3324c8ef1a60SArnd Bergmann 	return 0;
3325c8ef1a60SArnd Bergmann }
3326c8ef1a60SArnd Bergmann 
33275bc3cb74SMauro Carvalho Chehab long
3328c8ef1a60SArnd Bergmann video_usercopy(struct file *file, unsigned int orig_cmd, unsigned long arg,
33295bc3cb74SMauro Carvalho Chehab 	       v4l2_kioctl func)
33305bc3cb74SMauro Carvalho Chehab {
33315bc3cb74SMauro Carvalho Chehab 	char	sbuf[128];
3332fb18802aSSakari Ailus 	void    *mbuf = NULL, *array_buf = NULL;
33335bc3cb74SMauro Carvalho Chehab 	void	*parg = (void *)arg;
33345bc3cb74SMauro Carvalho Chehab 	long	err  = -EINVAL;
33355bc3cb74SMauro Carvalho Chehab 	bool	has_array_args;
3336043f77edSHans Verkuil 	bool	always_copy = false;
33375bc3cb74SMauro Carvalho Chehab 	size_t  array_size = 0;
33385bc3cb74SMauro Carvalho Chehab 	void __user *user_ptr = NULL;
33395bc3cb74SMauro Carvalho Chehab 	void	**kernel_ptr = NULL;
3340c8ef1a60SArnd Bergmann 	unsigned int cmd = video_translate_cmd(orig_cmd);
3341f8a695c4SMauro Carvalho Chehab 	const size_t ioc_size = _IOC_SIZE(cmd);
33425bc3cb74SMauro Carvalho Chehab 
33435bc3cb74SMauro Carvalho Chehab 	/*  Copy arguments into temp kernel buffer  */
33445bc3cb74SMauro Carvalho Chehab 	if (_IOC_DIR(cmd) != _IOC_NONE) {
3345f8a695c4SMauro Carvalho Chehab 		if (ioc_size <= sizeof(sbuf)) {
33465bc3cb74SMauro Carvalho Chehab 			parg = sbuf;
33475bc3cb74SMauro Carvalho Chehab 		} else {
33485bc3cb74SMauro Carvalho Chehab 			/* too big to allocate from stack */
334962a12551SSakari Ailus 			mbuf = kmalloc(ioc_size, GFP_KERNEL);
33505bc3cb74SMauro Carvalho Chehab 			if (NULL == mbuf)
33515bc3cb74SMauro Carvalho Chehab 				return -ENOMEM;
33525bc3cb74SMauro Carvalho Chehab 			parg = mbuf;
33535bc3cb74SMauro Carvalho Chehab 		}
33545bc3cb74SMauro Carvalho Chehab 
33558dbcc3faSArnd Bergmann 		err = video_get_user((void __user *)arg, parg, cmd,
33568dbcc3faSArnd Bergmann 				     orig_cmd, &always_copy);
3357c8ef1a60SArnd Bergmann 		if (err)
33585bc3cb74SMauro Carvalho Chehab 			goto out;
33591dc8b65cSArnd Bergmann 	}
33605bc3cb74SMauro Carvalho Chehab 
33615bc3cb74SMauro Carvalho Chehab 	err = check_array_args(cmd, parg, &array_size, &user_ptr, &kernel_ptr);
33625bc3cb74SMauro Carvalho Chehab 	if (err < 0)
33635bc3cb74SMauro Carvalho Chehab 		goto out;
33645bc3cb74SMauro Carvalho Chehab 	has_array_args = err;
33655bc3cb74SMauro Carvalho Chehab 
33665bc3cb74SMauro Carvalho Chehab 	if (has_array_args) {
3367fb18802aSSakari Ailus 		array_buf = kvmalloc(array_size, GFP_KERNEL);
33685bc3cb74SMauro Carvalho Chehab 		err = -ENOMEM;
3369fb18802aSSakari Ailus 		if (array_buf == NULL)
3370f0da34f3SHans Verkuil 			goto out;
33718dbcc3faSArnd Bergmann 		if (in_compat_syscall())
3372fb18802aSSakari Ailus 			err = v4l2_compat_get_array_args(file, array_buf,
3373fb18802aSSakari Ailus 							 user_ptr, array_size,
3374fb18802aSSakari Ailus 							 orig_cmd, parg);
33758dbcc3faSArnd Bergmann 		else
3376fb18802aSSakari Ailus 			err = copy_from_user(array_buf, user_ptr, array_size) ?
33778dbcc3faSArnd Bergmann 								-EFAULT : 0;
33788dbcc3faSArnd Bergmann 		if (err)
3379f0da34f3SHans Verkuil 			goto out;
3380fb18802aSSakari Ailus 		*kernel_ptr = array_buf;
33815bc3cb74SMauro Carvalho Chehab 	}
33825bc3cb74SMauro Carvalho Chehab 
33835bc3cb74SMauro Carvalho Chehab 	/* Handles IOCTL */
33845bc3cb74SMauro Carvalho Chehab 	err = func(file, cmd, parg);
3385181a4a2dSHans Verkuil 	if (err == -ENOTTY || err == -ENOIOCTLCMD) {
33865bc3cb74SMauro Carvalho Chehab 		err = -ENOTTY;
3387181a4a2dSHans Verkuil 		goto out;
3388181a4a2dSHans Verkuil 	}
3389181a4a2dSHans Verkuil 
3390aa32f4c0SHans Verkuil 	if (err == 0) {
3391aa32f4c0SHans Verkuil 		if (cmd == VIDIOC_DQBUF)
3392aa32f4c0SHans Verkuil 			trace_v4l2_dqbuf(video_devdata(file)->minor, parg);
3393aa32f4c0SHans Verkuil 		else if (cmd == VIDIOC_QBUF)
3394aa32f4c0SHans Verkuil 			trace_v4l2_qbuf(video_devdata(file)->minor, parg);
3395aa32f4c0SHans Verkuil 	}
33965bc3cb74SMauro Carvalho Chehab 
3397f0da34f3SHans Verkuil 	/*
3398f0da34f3SHans Verkuil 	 * Some ioctls can return an error, but still have valid
3399f0da34f3SHans Verkuil 	 * results that must be returned.
3400f0da34f3SHans Verkuil 	 */
3401f0da34f3SHans Verkuil 	if (err < 0 && !always_copy)
3402f0da34f3SHans Verkuil 		goto out;
3403f0da34f3SHans Verkuil 
34045bc3cb74SMauro Carvalho Chehab 	if (has_array_args) {
3405ba2d35c1SHans Verkuil 		*kernel_ptr = (void __force *)user_ptr;
34068dbcc3faSArnd Bergmann 		if (in_compat_syscall()) {
34078dbcc3faSArnd Bergmann 			int put_err;
34088dbcc3faSArnd Bergmann 
3409fb18802aSSakari Ailus 			put_err = v4l2_compat_put_array_args(file, user_ptr,
3410fb18802aSSakari Ailus 							     array_buf,
3411fb18802aSSakari Ailus 							     array_size,
3412fb18802aSSakari Ailus 							     orig_cmd, parg);
34138dbcc3faSArnd Bergmann 			if (put_err)
34148dbcc3faSArnd Bergmann 				err = put_err;
3415fb18802aSSakari Ailus 		} else if (copy_to_user(user_ptr, array_buf, array_size)) {
34165bc3cb74SMauro Carvalho Chehab 			err = -EFAULT;
34178dbcc3faSArnd Bergmann 		}
34185bc3cb74SMauro Carvalho Chehab 	}
34195bc3cb74SMauro Carvalho Chehab 
34208dbcc3faSArnd Bergmann 	if (video_put_user((void __user *)arg, parg, cmd, orig_cmd))
34215bc3cb74SMauro Carvalho Chehab 		err = -EFAULT;
34225bc3cb74SMauro Carvalho Chehab out:
3423fb18802aSSakari Ailus 	kvfree(array_buf);
342462a12551SSakari Ailus 	kfree(mbuf);
34255bc3cb74SMauro Carvalho Chehab 	return err;
34265bc3cb74SMauro Carvalho Chehab }
34275bc3cb74SMauro Carvalho Chehab 
34285bc3cb74SMauro Carvalho Chehab long video_ioctl2(struct file *file,
34295bc3cb74SMauro Carvalho Chehab 	       unsigned int cmd, unsigned long arg)
34305bc3cb74SMauro Carvalho Chehab {
34315bc3cb74SMauro Carvalho Chehab 	return video_usercopy(file, cmd, arg, __video_do_ioctl);
34325bc3cb74SMauro Carvalho Chehab }
34335bc3cb74SMauro Carvalho Chehab EXPORT_SYMBOL(video_ioctl2);
3434