15bc3cb74SMauro Carvalho Chehab /*
25bc3cb74SMauro Carvalho Chehab  * Video capture interface for Linux version 2
35bc3cb74SMauro Carvalho Chehab  *
45bc3cb74SMauro Carvalho Chehab  * A generic framework to process V4L2 ioctl commands.
55bc3cb74SMauro Carvalho Chehab  *
65bc3cb74SMauro Carvalho Chehab  * This program is free software; you can redistribute it and/or
75bc3cb74SMauro Carvalho Chehab  * modify it under the terms of the GNU General Public License
85bc3cb74SMauro Carvalho Chehab  * as published by the Free Software Foundation; either version
95bc3cb74SMauro Carvalho Chehab  * 2 of the License, or (at your option) any later version.
105bc3cb74SMauro Carvalho Chehab  *
115bc3cb74SMauro Carvalho Chehab  * Authors:	Alan Cox, <alan@lxorguk.ukuu.org.uk> (version 1)
1232590819SMauro Carvalho Chehab  *              Mauro Carvalho Chehab <mchehab@kernel.org> (version 2)
135bc3cb74SMauro Carvalho Chehab  */
145bc3cb74SMauro Carvalho Chehab 
15758d90e1STomasz Figa #include <linux/mm.h>
165bc3cb74SMauro Carvalho Chehab #include <linux/module.h>
175bc3cb74SMauro Carvalho Chehab #include <linux/slab.h>
185bc3cb74SMauro Carvalho Chehab #include <linux/types.h>
195bc3cb74SMauro Carvalho Chehab #include <linux/kernel.h>
205bc3cb74SMauro Carvalho Chehab #include <linux/version.h>
215bc3cb74SMauro Carvalho Chehab 
225bc3cb74SMauro Carvalho Chehab #include <linux/videodev2.h>
235bc3cb74SMauro Carvalho Chehab 
245bc3cb74SMauro Carvalho Chehab #include <media/v4l2-common.h>
255bc3cb74SMauro Carvalho Chehab #include <media/v4l2-ioctl.h>
265bc3cb74SMauro Carvalho Chehab #include <media/v4l2-ctrls.h>
275bc3cb74SMauro Carvalho Chehab #include <media/v4l2-fh.h>
285bc3cb74SMauro Carvalho Chehab #include <media/v4l2-event.h>
295bc3cb74SMauro Carvalho Chehab #include <media/v4l2-device.h>
30c139990eSJunghak Sung #include <media/videobuf2-v4l2.h>
3177fa4e07SShuah Khan #include <media/v4l2-mc.h>
32d862bc08SHans Verkuil #include <media/v4l2-mem2mem.h>
335bc3cb74SMauro Carvalho Chehab 
34aa32f4c0SHans Verkuil #include <trace/events/v4l2.h>
35aa32f4c0SHans Verkuil 
365bc3cb74SMauro Carvalho Chehab /* Zero out the end of the struct pointed to by p.  Everything after, but
375bc3cb74SMauro Carvalho Chehab  * not including, the specified field is cleared. */
385bc3cb74SMauro Carvalho Chehab #define CLEAR_AFTER_FIELD(p, field) \
395bc3cb74SMauro Carvalho Chehab 	memset((u8 *)(p) + offsetof(typeof(*(p)), field) + sizeof((p)->field), \
405bc3cb74SMauro Carvalho Chehab 	0, sizeof(*(p)) - offsetof(typeof(*(p)), field) - sizeof((p)->field))
415bc3cb74SMauro Carvalho Chehab 
4273f35418SHans Verkuil #define is_valid_ioctl(vfd, cmd) test_bit(_IOC_NR(cmd), (vfd)->valid_ioctls)
4373f35418SHans Verkuil 
445bc3cb74SMauro Carvalho Chehab struct std_descr {
455bc3cb74SMauro Carvalho Chehab 	v4l2_std_id std;
465bc3cb74SMauro Carvalho Chehab 	const char *descr;
475bc3cb74SMauro Carvalho Chehab };
485bc3cb74SMauro Carvalho Chehab 
495bc3cb74SMauro Carvalho Chehab static const struct std_descr standards[] = {
505bc3cb74SMauro Carvalho Chehab 	{ V4L2_STD_NTSC,	"NTSC"      },
515bc3cb74SMauro Carvalho Chehab 	{ V4L2_STD_NTSC_M,	"NTSC-M"    },
525bc3cb74SMauro Carvalho Chehab 	{ V4L2_STD_NTSC_M_JP,	"NTSC-M-JP" },
535bc3cb74SMauro Carvalho Chehab 	{ V4L2_STD_NTSC_M_KR,	"NTSC-M-KR" },
545bc3cb74SMauro Carvalho Chehab 	{ V4L2_STD_NTSC_443,	"NTSC-443"  },
555bc3cb74SMauro Carvalho Chehab 	{ V4L2_STD_PAL,		"PAL"       },
565bc3cb74SMauro Carvalho Chehab 	{ V4L2_STD_PAL_BG,	"PAL-BG"    },
575bc3cb74SMauro Carvalho Chehab 	{ V4L2_STD_PAL_B,	"PAL-B"     },
585bc3cb74SMauro Carvalho Chehab 	{ V4L2_STD_PAL_B1,	"PAL-B1"    },
595bc3cb74SMauro Carvalho Chehab 	{ V4L2_STD_PAL_G,	"PAL-G"     },
605bc3cb74SMauro Carvalho Chehab 	{ V4L2_STD_PAL_H,	"PAL-H"     },
615bc3cb74SMauro Carvalho Chehab 	{ V4L2_STD_PAL_I,	"PAL-I"     },
625bc3cb74SMauro Carvalho Chehab 	{ V4L2_STD_PAL_DK,	"PAL-DK"    },
635bc3cb74SMauro Carvalho Chehab 	{ V4L2_STD_PAL_D,	"PAL-D"     },
645bc3cb74SMauro Carvalho Chehab 	{ V4L2_STD_PAL_D1,	"PAL-D1"    },
655bc3cb74SMauro Carvalho Chehab 	{ V4L2_STD_PAL_K,	"PAL-K"     },
665bc3cb74SMauro Carvalho Chehab 	{ V4L2_STD_PAL_M,	"PAL-M"     },
675bc3cb74SMauro Carvalho Chehab 	{ V4L2_STD_PAL_N,	"PAL-N"     },
685bc3cb74SMauro Carvalho Chehab 	{ V4L2_STD_PAL_Nc,	"PAL-Nc"    },
695bc3cb74SMauro Carvalho Chehab 	{ V4L2_STD_PAL_60,	"PAL-60"    },
705bc3cb74SMauro Carvalho Chehab 	{ V4L2_STD_SECAM,	"SECAM"     },
715bc3cb74SMauro Carvalho Chehab 	{ V4L2_STD_SECAM_B,	"SECAM-B"   },
725bc3cb74SMauro Carvalho Chehab 	{ V4L2_STD_SECAM_G,	"SECAM-G"   },
735bc3cb74SMauro Carvalho Chehab 	{ V4L2_STD_SECAM_H,	"SECAM-H"   },
745bc3cb74SMauro Carvalho Chehab 	{ V4L2_STD_SECAM_DK,	"SECAM-DK"  },
755bc3cb74SMauro Carvalho Chehab 	{ V4L2_STD_SECAM_D,	"SECAM-D"   },
765bc3cb74SMauro Carvalho Chehab 	{ V4L2_STD_SECAM_K,	"SECAM-K"   },
775bc3cb74SMauro Carvalho Chehab 	{ V4L2_STD_SECAM_K1,	"SECAM-K1"  },
785bc3cb74SMauro Carvalho Chehab 	{ V4L2_STD_SECAM_L,	"SECAM-L"   },
795bc3cb74SMauro Carvalho Chehab 	{ V4L2_STD_SECAM_LC,	"SECAM-Lc"  },
805bc3cb74SMauro Carvalho Chehab 	{ 0,			"Unknown"   }
815bc3cb74SMauro Carvalho Chehab };
825bc3cb74SMauro Carvalho Chehab 
835bc3cb74SMauro Carvalho Chehab /* video4linux standard ID conversion to standard name
845bc3cb74SMauro Carvalho Chehab  */
855bc3cb74SMauro Carvalho Chehab const char *v4l2_norm_to_name(v4l2_std_id id)
865bc3cb74SMauro Carvalho Chehab {
875bc3cb74SMauro Carvalho Chehab 	u32 myid = id;
885bc3cb74SMauro Carvalho Chehab 	int i;
895bc3cb74SMauro Carvalho Chehab 
905bc3cb74SMauro Carvalho Chehab 	/* HACK: ppc32 architecture doesn't have __ucmpdi2 function to handle
914faf7066SMauro Carvalho Chehab 	   64 bit comparisons. So, on that architecture, with some gcc
925bc3cb74SMauro Carvalho Chehab 	   variants, compilation fails. Currently, the max value is 30bit wide.
935bc3cb74SMauro Carvalho Chehab 	 */
945bc3cb74SMauro Carvalho Chehab 	BUG_ON(myid != id);
955bc3cb74SMauro Carvalho Chehab 
965bc3cb74SMauro Carvalho Chehab 	for (i = 0; standards[i].std; i++)
975bc3cb74SMauro Carvalho Chehab 		if (myid == standards[i].std)
985bc3cb74SMauro Carvalho Chehab 			break;
995bc3cb74SMauro Carvalho Chehab 	return standards[i].descr;
1005bc3cb74SMauro Carvalho Chehab }
1015bc3cb74SMauro Carvalho Chehab EXPORT_SYMBOL(v4l2_norm_to_name);
1025bc3cb74SMauro Carvalho Chehab 
1035bc3cb74SMauro Carvalho Chehab /* Returns frame period for the given standard */
1045bc3cb74SMauro Carvalho Chehab void v4l2_video_std_frame_period(int id, struct v4l2_fract *frameperiod)
1055bc3cb74SMauro Carvalho Chehab {
1065bc3cb74SMauro Carvalho Chehab 	if (id & V4L2_STD_525_60) {
1075bc3cb74SMauro Carvalho Chehab 		frameperiod->numerator = 1001;
1085bc3cb74SMauro Carvalho Chehab 		frameperiod->denominator = 30000;
1095bc3cb74SMauro Carvalho Chehab 	} else {
1105bc3cb74SMauro Carvalho Chehab 		frameperiod->numerator = 1;
1115bc3cb74SMauro Carvalho Chehab 		frameperiod->denominator = 25;
1125bc3cb74SMauro Carvalho Chehab 	}
1135bc3cb74SMauro Carvalho Chehab }
1145bc3cb74SMauro Carvalho Chehab EXPORT_SYMBOL(v4l2_video_std_frame_period);
1155bc3cb74SMauro Carvalho Chehab 
1165bc3cb74SMauro Carvalho Chehab /* Fill in the fields of a v4l2_standard structure according to the
1175bc3cb74SMauro Carvalho Chehab    'id' and 'transmission' parameters.  Returns negative on error.  */
1185bc3cb74SMauro Carvalho Chehab int v4l2_video_std_construct(struct v4l2_standard *vs,
1195bc3cb74SMauro Carvalho Chehab 			     int id, const char *name)
1205bc3cb74SMauro Carvalho Chehab {
1215bc3cb74SMauro Carvalho Chehab 	vs->id = id;
1225bc3cb74SMauro Carvalho Chehab 	v4l2_video_std_frame_period(id, &vs->frameperiod);
1235bc3cb74SMauro Carvalho Chehab 	vs->framelines = (id & V4L2_STD_525_60) ? 525 : 625;
124c0decac1SMauro Carvalho Chehab 	strscpy(vs->name, name, sizeof(vs->name));
1255bc3cb74SMauro Carvalho Chehab 	return 0;
1265bc3cb74SMauro Carvalho Chehab }
1275bc3cb74SMauro Carvalho Chehab EXPORT_SYMBOL(v4l2_video_std_construct);
1285bc3cb74SMauro Carvalho Chehab 
129aa2f8871SNiklas Söderlund /* Fill in the fields of a v4l2_standard structure according to the
130aa2f8871SNiklas Söderlund  * 'id' and 'vs->index' parameters. Returns negative on error. */
131aa2f8871SNiklas Söderlund int v4l_video_std_enumstd(struct v4l2_standard *vs, v4l2_std_id id)
132aa2f8871SNiklas Söderlund {
133aa2f8871SNiklas Söderlund 	v4l2_std_id curr_id = 0;
134aa2f8871SNiklas Söderlund 	unsigned int index = vs->index, i, j = 0;
135aa2f8871SNiklas Söderlund 	const char *descr = "";
136aa2f8871SNiklas Söderlund 
137aa2f8871SNiklas Söderlund 	/* Return -ENODATA if the id for the current input
138aa2f8871SNiklas Söderlund 	   or output is 0, meaning that it doesn't support this API. */
139aa2f8871SNiklas Söderlund 	if (id == 0)
140aa2f8871SNiklas Söderlund 		return -ENODATA;
141aa2f8871SNiklas Söderlund 
142aa2f8871SNiklas Söderlund 	/* Return norm array in a canonical way */
143aa2f8871SNiklas Söderlund 	for (i = 0; i <= index && id; i++) {
144aa2f8871SNiklas Söderlund 		/* last std value in the standards array is 0, so this
145aa2f8871SNiklas Söderlund 		   while always ends there since (id & 0) == 0. */
146aa2f8871SNiklas Söderlund 		while ((id & standards[j].std) != standards[j].std)
147aa2f8871SNiklas Söderlund 			j++;
148aa2f8871SNiklas Söderlund 		curr_id = standards[j].std;
149aa2f8871SNiklas Söderlund 		descr = standards[j].descr;
150aa2f8871SNiklas Söderlund 		j++;
151aa2f8871SNiklas Söderlund 		if (curr_id == 0)
152aa2f8871SNiklas Söderlund 			break;
153aa2f8871SNiklas Söderlund 		if (curr_id != V4L2_STD_PAL &&
154aa2f8871SNiklas Söderlund 				curr_id != V4L2_STD_SECAM &&
155aa2f8871SNiklas Söderlund 				curr_id != V4L2_STD_NTSC)
156aa2f8871SNiklas Söderlund 			id &= ~curr_id;
157aa2f8871SNiklas Söderlund 	}
158aa2f8871SNiklas Söderlund 	if (i <= index)
159aa2f8871SNiklas Söderlund 		return -EINVAL;
160aa2f8871SNiklas Söderlund 
161aa2f8871SNiklas Söderlund 	v4l2_video_std_construct(vs, curr_id, descr);
162aa2f8871SNiklas Söderlund 	return 0;
163aa2f8871SNiklas Söderlund }
164aa2f8871SNiklas Söderlund 
1655bc3cb74SMauro Carvalho Chehab /* ----------------------------------------------------------------- */
1665bc3cb74SMauro Carvalho Chehab /* some arrays for pretty-printing debug messages of enum types      */
1675bc3cb74SMauro Carvalho Chehab 
1685bc3cb74SMauro Carvalho Chehab const char *v4l2_field_names[] = {
1695bc3cb74SMauro Carvalho Chehab 	[V4L2_FIELD_ANY]        = "any",
1705bc3cb74SMauro Carvalho Chehab 	[V4L2_FIELD_NONE]       = "none",
1715bc3cb74SMauro Carvalho Chehab 	[V4L2_FIELD_TOP]        = "top",
1725bc3cb74SMauro Carvalho Chehab 	[V4L2_FIELD_BOTTOM]     = "bottom",
1735bc3cb74SMauro Carvalho Chehab 	[V4L2_FIELD_INTERLACED] = "interlaced",
1745bc3cb74SMauro Carvalho Chehab 	[V4L2_FIELD_SEQ_TB]     = "seq-tb",
1755bc3cb74SMauro Carvalho Chehab 	[V4L2_FIELD_SEQ_BT]     = "seq-bt",
1765bc3cb74SMauro Carvalho Chehab 	[V4L2_FIELD_ALTERNATE]  = "alternate",
1775bc3cb74SMauro Carvalho Chehab 	[V4L2_FIELD_INTERLACED_TB] = "interlaced-tb",
1785bc3cb74SMauro Carvalho Chehab 	[V4L2_FIELD_INTERLACED_BT] = "interlaced-bt",
1795bc3cb74SMauro Carvalho Chehab };
1805bc3cb74SMauro Carvalho Chehab EXPORT_SYMBOL(v4l2_field_names);
1815bc3cb74SMauro Carvalho Chehab 
1825bc3cb74SMauro Carvalho Chehab const char *v4l2_type_names[] = {
183839aa56dSHans Verkuil 	[0]				   = "0",
1845bc3cb74SMauro Carvalho Chehab 	[V4L2_BUF_TYPE_VIDEO_CAPTURE]      = "vid-cap",
1855bc3cb74SMauro Carvalho Chehab 	[V4L2_BUF_TYPE_VIDEO_OVERLAY]      = "vid-overlay",
1865bc3cb74SMauro Carvalho Chehab 	[V4L2_BUF_TYPE_VIDEO_OUTPUT]       = "vid-out",
1875bc3cb74SMauro Carvalho Chehab 	[V4L2_BUF_TYPE_VBI_CAPTURE]        = "vbi-cap",
1885bc3cb74SMauro Carvalho Chehab 	[V4L2_BUF_TYPE_VBI_OUTPUT]         = "vbi-out",
1895bc3cb74SMauro Carvalho Chehab 	[V4L2_BUF_TYPE_SLICED_VBI_CAPTURE] = "sliced-vbi-cap",
1905bc3cb74SMauro Carvalho Chehab 	[V4L2_BUF_TYPE_SLICED_VBI_OUTPUT]  = "sliced-vbi-out",
1915bc3cb74SMauro Carvalho Chehab 	[V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY] = "vid-out-overlay",
1925bc3cb74SMauro Carvalho Chehab 	[V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE] = "vid-cap-mplane",
1935bc3cb74SMauro Carvalho Chehab 	[V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE] = "vid-out-mplane",
1946f3073b8SAntti Palosaari 	[V4L2_BUF_TYPE_SDR_CAPTURE]        = "sdr-cap",
1959effc72fSAntti Palosaari 	[V4L2_BUF_TYPE_SDR_OUTPUT]         = "sdr-out",
196fb9ffa6aSLaurent Pinchart 	[V4L2_BUF_TYPE_META_CAPTURE]       = "meta-cap",
19772148d1aSSakari Ailus 	[V4L2_BUF_TYPE_META_OUTPUT]	   = "meta-out",
1985bc3cb74SMauro Carvalho Chehab };
1995bc3cb74SMauro Carvalho Chehab EXPORT_SYMBOL(v4l2_type_names);
2005bc3cb74SMauro Carvalho Chehab 
2015bc3cb74SMauro Carvalho Chehab static const char *v4l2_memory_names[] = {
2025bc3cb74SMauro Carvalho Chehab 	[V4L2_MEMORY_MMAP]    = "mmap",
2035bc3cb74SMauro Carvalho Chehab 	[V4L2_MEMORY_USERPTR] = "userptr",
2045bc3cb74SMauro Carvalho Chehab 	[V4L2_MEMORY_OVERLAY] = "overlay",
205051c7788SSumit Semwal 	[V4L2_MEMORY_DMABUF] = "dmabuf",
2065bc3cb74SMauro Carvalho Chehab };
2075bc3cb74SMauro Carvalho Chehab 
208d9246240SHans Verkuil #define prt_names(a, arr) (((unsigned)(a)) < ARRAY_SIZE(arr) ? arr[a] : "unknown")
2095bc3cb74SMauro Carvalho Chehab 
2105bc3cb74SMauro Carvalho Chehab /* ------------------------------------------------------------------ */
2115bc3cb74SMauro Carvalho Chehab /* debug help functions                                               */
2125bc3cb74SMauro Carvalho Chehab 
2135bc3cb74SMauro Carvalho Chehab static void v4l_print_querycap(const void *arg, bool write_only)
2145bc3cb74SMauro Carvalho Chehab {
2155bc3cb74SMauro Carvalho Chehab 	const struct v4l2_capability *p = arg;
2165bc3cb74SMauro Carvalho Chehab 
2178720427cSMauro Carvalho Chehab 	pr_cont("driver=%.*s, card=%.*s, bus=%.*s, version=0x%08x, capabilities=0x%08x, device_caps=0x%08x\n",
21827d5a87cSHans Verkuil 		(int)sizeof(p->driver), p->driver,
21927d5a87cSHans Verkuil 		(int)sizeof(p->card), p->card,
22027d5a87cSHans Verkuil 		(int)sizeof(p->bus_info), p->bus_info,
2215bc3cb74SMauro Carvalho Chehab 		p->version, p->capabilities, p->device_caps);
2225bc3cb74SMauro Carvalho Chehab }
2235bc3cb74SMauro Carvalho Chehab 
2245bc3cb74SMauro Carvalho Chehab static void v4l_print_enuminput(const void *arg, bool write_only)
2255bc3cb74SMauro Carvalho Chehab {
2265bc3cb74SMauro Carvalho Chehab 	const struct v4l2_input *p = arg;
2275bc3cb74SMauro Carvalho Chehab 
2288720427cSMauro 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",
22927d5a87cSHans Verkuil 		p->index, (int)sizeof(p->name), p->name, p->type, p->audioset,
23027d5a87cSHans Verkuil 		p->tuner, (unsigned long long)p->std, p->status,
23127d5a87cSHans Verkuil 		p->capabilities);
2325bc3cb74SMauro Carvalho Chehab }
2335bc3cb74SMauro Carvalho Chehab 
2345bc3cb74SMauro Carvalho Chehab static void v4l_print_enumoutput(const void *arg, bool write_only)
2355bc3cb74SMauro Carvalho Chehab {
2365bc3cb74SMauro Carvalho Chehab 	const struct v4l2_output *p = arg;
2375bc3cb74SMauro Carvalho Chehab 
2388720427cSMauro Carvalho Chehab 	pr_cont("index=%u, name=%.*s, type=%u, audioset=0x%x, modulator=%u, std=0x%08Lx, capabilities=0x%x\n",
23927d5a87cSHans Verkuil 		p->index, (int)sizeof(p->name), p->name, p->type, p->audioset,
24027d5a87cSHans Verkuil 		p->modulator, (unsigned long long)p->std, p->capabilities);
2415bc3cb74SMauro Carvalho Chehab }
2425bc3cb74SMauro Carvalho Chehab 
2435bc3cb74SMauro Carvalho Chehab static void v4l_print_audio(const void *arg, bool write_only)
2445bc3cb74SMauro Carvalho Chehab {
2455bc3cb74SMauro Carvalho Chehab 	const struct v4l2_audio *p = arg;
2465bc3cb74SMauro Carvalho Chehab 
2475bc3cb74SMauro Carvalho Chehab 	if (write_only)
2485bc3cb74SMauro Carvalho Chehab 		pr_cont("index=%u, mode=0x%x\n", p->index, p->mode);
2495bc3cb74SMauro Carvalho Chehab 	else
25027d5a87cSHans Verkuil 		pr_cont("index=%u, name=%.*s, capability=0x%x, mode=0x%x\n",
25127d5a87cSHans Verkuil 			p->index, (int)sizeof(p->name), p->name,
25227d5a87cSHans Verkuil 			p->capability, p->mode);
2535bc3cb74SMauro Carvalho Chehab }
2545bc3cb74SMauro Carvalho Chehab 
2555bc3cb74SMauro Carvalho Chehab static void v4l_print_audioout(const void *arg, bool write_only)
2565bc3cb74SMauro Carvalho Chehab {
2575bc3cb74SMauro Carvalho Chehab 	const struct v4l2_audioout *p = arg;
2585bc3cb74SMauro Carvalho Chehab 
2595bc3cb74SMauro Carvalho Chehab 	if (write_only)
2605bc3cb74SMauro Carvalho Chehab 		pr_cont("index=%u\n", p->index);
2615bc3cb74SMauro Carvalho Chehab 	else
26227d5a87cSHans Verkuil 		pr_cont("index=%u, name=%.*s, capability=0x%x, mode=0x%x\n",
26327d5a87cSHans Verkuil 			p->index, (int)sizeof(p->name), p->name,
26427d5a87cSHans Verkuil 			p->capability, p->mode);
2655bc3cb74SMauro Carvalho Chehab }
2665bc3cb74SMauro Carvalho Chehab 
2675bc3cb74SMauro Carvalho Chehab static void v4l_print_fmtdesc(const void *arg, bool write_only)
2685bc3cb74SMauro Carvalho Chehab {
2695bc3cb74SMauro Carvalho Chehab 	const struct v4l2_fmtdesc *p = arg;
2705bc3cb74SMauro Carvalho Chehab 
27127d5a87cSHans Verkuil 	pr_cont("index=%u, type=%s, flags=0x%x, pixelformat=%c%c%c%c, description='%.*s'\n",
2725bc3cb74SMauro Carvalho Chehab 		p->index, prt_names(p->type, v4l2_type_names),
2735bc3cb74SMauro Carvalho Chehab 		p->flags, (p->pixelformat & 0xff),
2745bc3cb74SMauro Carvalho Chehab 		(p->pixelformat >>  8) & 0xff,
2755bc3cb74SMauro Carvalho Chehab 		(p->pixelformat >> 16) & 0xff,
2765bc3cb74SMauro Carvalho Chehab 		(p->pixelformat >> 24) & 0xff,
27727d5a87cSHans Verkuil 		(int)sizeof(p->description), p->description);
2785bc3cb74SMauro Carvalho Chehab }
2795bc3cb74SMauro Carvalho Chehab 
2805bc3cb74SMauro Carvalho Chehab static void v4l_print_format(const void *arg, bool write_only)
2815bc3cb74SMauro Carvalho Chehab {
2825bc3cb74SMauro Carvalho Chehab 	const struct v4l2_format *p = arg;
2835bc3cb74SMauro Carvalho Chehab 	const struct v4l2_pix_format *pix;
2845bc3cb74SMauro Carvalho Chehab 	const struct v4l2_pix_format_mplane *mp;
2855bc3cb74SMauro Carvalho Chehab 	const struct v4l2_vbi_format *vbi;
2865bc3cb74SMauro Carvalho Chehab 	const struct v4l2_sliced_vbi_format *sliced;
2875bc3cb74SMauro Carvalho Chehab 	const struct v4l2_window *win;
28887185c95SAntti Palosaari 	const struct v4l2_sdr_format *sdr;
289fb9ffa6aSLaurent Pinchart 	const struct v4l2_meta_format *meta;
2907fe9f01cSSakari Ailus 	u32 planes;
2915bc3cb74SMauro Carvalho Chehab 	unsigned i;
2925bc3cb74SMauro Carvalho Chehab 
2935bc3cb74SMauro Carvalho Chehab 	pr_cont("type=%s", prt_names(p->type, v4l2_type_names));
2945bc3cb74SMauro Carvalho Chehab 	switch (p->type) {
2955bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_CAPTURE:
2965bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_OUTPUT:
2975bc3cb74SMauro Carvalho Chehab 		pix = &p->fmt.pix;
2988720427cSMauro Carvalho Chehab 		pr_cont(", width=%u, height=%u, pixelformat=%c%c%c%c, field=%s, bytesperline=%u, sizeimage=%u, colorspace=%d, flags=0x%x, ycbcr_enc=%u, quantization=%u, xfer_func=%u\n",
2995bc3cb74SMauro Carvalho Chehab 			pix->width, pix->height,
3005bc3cb74SMauro Carvalho Chehab 			(pix->pixelformat & 0xff),
3015bc3cb74SMauro Carvalho Chehab 			(pix->pixelformat >>  8) & 0xff,
3025bc3cb74SMauro Carvalho Chehab 			(pix->pixelformat >> 16) & 0xff,
3035bc3cb74SMauro Carvalho Chehab 			(pix->pixelformat >> 24) & 0xff,
3045bc3cb74SMauro Carvalho Chehab 			prt_names(pix->field, v4l2_field_names),
3055bc3cb74SMauro Carvalho Chehab 			pix->bytesperline, pix->sizeimage,
306736d96b5SHans Verkuil 			pix->colorspace, pix->flags, pix->ycbcr_enc,
30774fdcb2eSHans Verkuil 			pix->quantization, pix->xfer_func);
3085bc3cb74SMauro Carvalho Chehab 		break;
3095bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
3105bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
3115bc3cb74SMauro Carvalho Chehab 		mp = &p->fmt.pix_mp;
3128720427cSMauro Carvalho Chehab 		pr_cont(", width=%u, height=%u, format=%c%c%c%c, field=%s, colorspace=%d, num_planes=%u, flags=0x%x, ycbcr_enc=%u, quantization=%u, xfer_func=%u\n",
3135bc3cb74SMauro Carvalho Chehab 			mp->width, mp->height,
3145bc3cb74SMauro Carvalho Chehab 			(mp->pixelformat & 0xff),
3155bc3cb74SMauro Carvalho Chehab 			(mp->pixelformat >>  8) & 0xff,
3165bc3cb74SMauro Carvalho Chehab 			(mp->pixelformat >> 16) & 0xff,
3175bc3cb74SMauro Carvalho Chehab 			(mp->pixelformat >> 24) & 0xff,
3185bc3cb74SMauro Carvalho Chehab 			prt_names(mp->field, v4l2_field_names),
319736d96b5SHans Verkuil 			mp->colorspace, mp->num_planes, mp->flags,
32074fdcb2eSHans Verkuil 			mp->ycbcr_enc, mp->quantization, mp->xfer_func);
3217fe9f01cSSakari Ailus 		planes = min_t(u32, mp->num_planes, VIDEO_MAX_PLANES);
3227fe9f01cSSakari Ailus 		for (i = 0; i < planes; i++)
3235bc3cb74SMauro Carvalho Chehab 			printk(KERN_DEBUG "plane %u: bytesperline=%u sizeimage=%u\n", i,
3245bc3cb74SMauro Carvalho Chehab 					mp->plane_fmt[i].bytesperline,
3255bc3cb74SMauro Carvalho Chehab 					mp->plane_fmt[i].sizeimage);
3265bc3cb74SMauro Carvalho Chehab 		break;
3275bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_OVERLAY:
3285bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
3295bc3cb74SMauro Carvalho Chehab 		win = &p->fmt.win;
330560dde24SHans Verkuil 		/* Note: we can't print the clip list here since the clips
331560dde24SHans Verkuil 		 * pointer is a userspace pointer, not a kernelspace
332560dde24SHans Verkuil 		 * pointer. */
333560dde24SHans 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",
334560dde24SHans Verkuil 			win->w.width, win->w.height, win->w.left, win->w.top,
3355bc3cb74SMauro Carvalho Chehab 			prt_names(win->field, v4l2_field_names),
336560dde24SHans Verkuil 			win->chromakey, win->clipcount, win->clips,
337560dde24SHans Verkuil 			win->bitmap, win->global_alpha);
3385bc3cb74SMauro Carvalho Chehab 		break;
3395bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VBI_CAPTURE:
3405bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VBI_OUTPUT:
3415bc3cb74SMauro Carvalho Chehab 		vbi = &p->fmt.vbi;
3428720427cSMauro Carvalho Chehab 		pr_cont(", sampling_rate=%u, offset=%u, samples_per_line=%u, sample_format=%c%c%c%c, start=%u,%u, count=%u,%u\n",
3435bc3cb74SMauro Carvalho Chehab 			vbi->sampling_rate, vbi->offset,
3445bc3cb74SMauro Carvalho Chehab 			vbi->samples_per_line,
3455bc3cb74SMauro Carvalho Chehab 			(vbi->sample_format & 0xff),
3465bc3cb74SMauro Carvalho Chehab 			(vbi->sample_format >>  8) & 0xff,
3475bc3cb74SMauro Carvalho Chehab 			(vbi->sample_format >> 16) & 0xff,
3485bc3cb74SMauro Carvalho Chehab 			(vbi->sample_format >> 24) & 0xff,
3495bc3cb74SMauro Carvalho Chehab 			vbi->start[0], vbi->start[1],
3505bc3cb74SMauro Carvalho Chehab 			vbi->count[0], vbi->count[1]);
3515bc3cb74SMauro Carvalho Chehab 		break;
3525bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
3535bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
3545bc3cb74SMauro Carvalho Chehab 		sliced = &p->fmt.sliced;
3555bc3cb74SMauro Carvalho Chehab 		pr_cont(", service_set=0x%08x, io_size=%d\n",
3565bc3cb74SMauro Carvalho Chehab 				sliced->service_set, sliced->io_size);
3575bc3cb74SMauro Carvalho Chehab 		for (i = 0; i < 24; i++)
3585bc3cb74SMauro Carvalho Chehab 			printk(KERN_DEBUG "line[%02u]=0x%04x, 0x%04x\n", i,
3595bc3cb74SMauro Carvalho Chehab 				sliced->service_lines[0][i],
3605bc3cb74SMauro Carvalho Chehab 				sliced->service_lines[1][i]);
3615bc3cb74SMauro Carvalho Chehab 		break;
362582c52cbSAntti Palosaari 	case V4L2_BUF_TYPE_SDR_CAPTURE:
3639effc72fSAntti Palosaari 	case V4L2_BUF_TYPE_SDR_OUTPUT:
364582c52cbSAntti Palosaari 		sdr = &p->fmt.sdr;
365582c52cbSAntti Palosaari 		pr_cont(", pixelformat=%c%c%c%c\n",
366582c52cbSAntti Palosaari 			(sdr->pixelformat >>  0) & 0xff,
367582c52cbSAntti Palosaari 			(sdr->pixelformat >>  8) & 0xff,
368582c52cbSAntti Palosaari 			(sdr->pixelformat >> 16) & 0xff,
369582c52cbSAntti Palosaari 			(sdr->pixelformat >> 24) & 0xff);
370582c52cbSAntti Palosaari 		break;
371fb9ffa6aSLaurent Pinchart 	case V4L2_BUF_TYPE_META_CAPTURE:
37272148d1aSSakari Ailus 	case V4L2_BUF_TYPE_META_OUTPUT:
373fb9ffa6aSLaurent Pinchart 		meta = &p->fmt.meta;
374fb9ffa6aSLaurent Pinchart 		pr_cont(", dataformat=%c%c%c%c, buffersize=%u\n",
375fb9ffa6aSLaurent Pinchart 			(meta->dataformat >>  0) & 0xff,
376fb9ffa6aSLaurent Pinchart 			(meta->dataformat >>  8) & 0xff,
377fb9ffa6aSLaurent Pinchart 			(meta->dataformat >> 16) & 0xff,
378fb9ffa6aSLaurent Pinchart 			(meta->dataformat >> 24) & 0xff,
379fb9ffa6aSLaurent Pinchart 			meta->buffersize);
380fb9ffa6aSLaurent Pinchart 		break;
3815bc3cb74SMauro Carvalho Chehab 	}
3825bc3cb74SMauro Carvalho Chehab }
3835bc3cb74SMauro Carvalho Chehab 
3845bc3cb74SMauro Carvalho Chehab static void v4l_print_framebuffer(const void *arg, bool write_only)
3855bc3cb74SMauro Carvalho Chehab {
3865bc3cb74SMauro Carvalho Chehab 	const struct v4l2_framebuffer *p = arg;
3875bc3cb74SMauro Carvalho Chehab 
3888720427cSMauro Carvalho Chehab 	pr_cont("capability=0x%x, flags=0x%x, base=0x%p, width=%u, height=%u, pixelformat=%c%c%c%c, bytesperline=%u, sizeimage=%u, colorspace=%d\n",
3895bc3cb74SMauro Carvalho Chehab 			p->capability, p->flags, p->base,
3905bc3cb74SMauro Carvalho Chehab 			p->fmt.width, p->fmt.height,
3915bc3cb74SMauro Carvalho Chehab 			(p->fmt.pixelformat & 0xff),
3925bc3cb74SMauro Carvalho Chehab 			(p->fmt.pixelformat >>  8) & 0xff,
3935bc3cb74SMauro Carvalho Chehab 			(p->fmt.pixelformat >> 16) & 0xff,
3945bc3cb74SMauro Carvalho Chehab 			(p->fmt.pixelformat >> 24) & 0xff,
3955bc3cb74SMauro Carvalho Chehab 			p->fmt.bytesperline, p->fmt.sizeimage,
3965bc3cb74SMauro Carvalho Chehab 			p->fmt.colorspace);
3975bc3cb74SMauro Carvalho Chehab }
3985bc3cb74SMauro Carvalho Chehab 
3995bc3cb74SMauro Carvalho Chehab static void v4l_print_buftype(const void *arg, bool write_only)
4005bc3cb74SMauro Carvalho Chehab {
4015bc3cb74SMauro Carvalho Chehab 	pr_cont("type=%s\n", prt_names(*(u32 *)arg, v4l2_type_names));
4025bc3cb74SMauro Carvalho Chehab }
4035bc3cb74SMauro Carvalho Chehab 
4045bc3cb74SMauro Carvalho Chehab static void v4l_print_modulator(const void *arg, bool write_only)
4055bc3cb74SMauro Carvalho Chehab {
4065bc3cb74SMauro Carvalho Chehab 	const struct v4l2_modulator *p = arg;
4075bc3cb74SMauro Carvalho Chehab 
4085bc3cb74SMauro Carvalho Chehab 	if (write_only)
409560dde24SHans Verkuil 		pr_cont("index=%u, txsubchans=0x%x\n", p->index, p->txsubchans);
4105bc3cb74SMauro Carvalho Chehab 	else
4118720427cSMauro Carvalho Chehab 		pr_cont("index=%u, name=%.*s, capability=0x%x, rangelow=%u, rangehigh=%u, txsubchans=0x%x\n",
41227d5a87cSHans Verkuil 			p->index, (int)sizeof(p->name), p->name, p->capability,
4135bc3cb74SMauro Carvalho Chehab 			p->rangelow, p->rangehigh, p->txsubchans);
4145bc3cb74SMauro Carvalho Chehab }
4155bc3cb74SMauro Carvalho Chehab 
4165bc3cb74SMauro Carvalho Chehab static void v4l_print_tuner(const void *arg, bool write_only)
4175bc3cb74SMauro Carvalho Chehab {
4185bc3cb74SMauro Carvalho Chehab 	const struct v4l2_tuner *p = arg;
4195bc3cb74SMauro Carvalho Chehab 
4205bc3cb74SMauro Carvalho Chehab 	if (write_only)
4215bc3cb74SMauro Carvalho Chehab 		pr_cont("index=%u, audmode=%u\n", p->index, p->audmode);
4225bc3cb74SMauro Carvalho Chehab 	else
4238720427cSMauro 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",
42427d5a87cSHans Verkuil 			p->index, (int)sizeof(p->name), p->name, p->type,
4255bc3cb74SMauro Carvalho Chehab 			p->capability, p->rangelow,
4265bc3cb74SMauro Carvalho Chehab 			p->rangehigh, p->signal, p->afc,
4275bc3cb74SMauro Carvalho Chehab 			p->rxsubchans, p->audmode);
4285bc3cb74SMauro Carvalho Chehab }
4295bc3cb74SMauro Carvalho Chehab 
4305bc3cb74SMauro Carvalho Chehab static void v4l_print_frequency(const void *arg, bool write_only)
4315bc3cb74SMauro Carvalho Chehab {
4325bc3cb74SMauro Carvalho Chehab 	const struct v4l2_frequency *p = arg;
4335bc3cb74SMauro Carvalho Chehab 
4345bc3cb74SMauro Carvalho Chehab 	pr_cont("tuner=%u, type=%u, frequency=%u\n",
4355bc3cb74SMauro Carvalho Chehab 				p->tuner, p->type, p->frequency);
4365bc3cb74SMauro Carvalho Chehab }
4375bc3cb74SMauro Carvalho Chehab 
4385bc3cb74SMauro Carvalho Chehab static void v4l_print_standard(const void *arg, bool write_only)
4395bc3cb74SMauro Carvalho Chehab {
4405bc3cb74SMauro Carvalho Chehab 	const struct v4l2_standard *p = arg;
4415bc3cb74SMauro Carvalho Chehab 
4428720427cSMauro Carvalho Chehab 	pr_cont("index=%u, id=0x%Lx, name=%.*s, fps=%u/%u, framelines=%u\n",
4438720427cSMauro Carvalho Chehab 		p->index,
44427d5a87cSHans Verkuil 		(unsigned long long)p->id, (int)sizeof(p->name), p->name,
4455bc3cb74SMauro Carvalho Chehab 		p->frameperiod.numerator,
4465bc3cb74SMauro Carvalho Chehab 		p->frameperiod.denominator,
4475bc3cb74SMauro Carvalho Chehab 		p->framelines);
4485bc3cb74SMauro Carvalho Chehab }
4495bc3cb74SMauro Carvalho Chehab 
4505bc3cb74SMauro Carvalho Chehab static void v4l_print_std(const void *arg, bool write_only)
4515bc3cb74SMauro Carvalho Chehab {
4525bc3cb74SMauro Carvalho Chehab 	pr_cont("std=0x%08Lx\n", *(const long long unsigned *)arg);
4535bc3cb74SMauro Carvalho Chehab }
4545bc3cb74SMauro Carvalho Chehab 
4555bc3cb74SMauro Carvalho Chehab static void v4l_print_hw_freq_seek(const void *arg, bool write_only)
4565bc3cb74SMauro Carvalho Chehab {
4575bc3cb74SMauro Carvalho Chehab 	const struct v4l2_hw_freq_seek *p = arg;
4585bc3cb74SMauro Carvalho Chehab 
4598720427cSMauro Carvalho Chehab 	pr_cont("tuner=%u, type=%u, seek_upward=%u, wrap_around=%u, spacing=%u, rangelow=%u, rangehigh=%u\n",
46079e8c7beSMauro Carvalho Chehab 		p->tuner, p->type, p->seek_upward, p->wrap_around, p->spacing,
46179e8c7beSMauro Carvalho Chehab 		p->rangelow, p->rangehigh);
4625bc3cb74SMauro Carvalho Chehab }
4635bc3cb74SMauro Carvalho Chehab 
4645bc3cb74SMauro Carvalho Chehab static void v4l_print_requestbuffers(const void *arg, bool write_only)
4655bc3cb74SMauro Carvalho Chehab {
4665bc3cb74SMauro Carvalho Chehab 	const struct v4l2_requestbuffers *p = arg;
4675bc3cb74SMauro Carvalho Chehab 
4685bc3cb74SMauro Carvalho Chehab 	pr_cont("count=%d, type=%s, memory=%s\n",
4695bc3cb74SMauro Carvalho Chehab 		p->count,
4705bc3cb74SMauro Carvalho Chehab 		prt_names(p->type, v4l2_type_names),
4715bc3cb74SMauro Carvalho Chehab 		prt_names(p->memory, v4l2_memory_names));
4725bc3cb74SMauro Carvalho Chehab }
4735bc3cb74SMauro Carvalho Chehab 
4745bc3cb74SMauro Carvalho Chehab static void v4l_print_buffer(const void *arg, bool write_only)
4755bc3cb74SMauro Carvalho Chehab {
4765bc3cb74SMauro Carvalho Chehab 	const struct v4l2_buffer *p = arg;
4775bc3cb74SMauro Carvalho Chehab 	const struct v4l2_timecode *tc = &p->timecode;
4785bc3cb74SMauro Carvalho Chehab 	const struct v4l2_plane *plane;
4795bc3cb74SMauro Carvalho Chehab 	int i;
4805bc3cb74SMauro Carvalho Chehab 
48162fed26fSHans Verkuil 	pr_cont("%02ld:%02d:%02d.%08ld index=%d, type=%s, request_fd=%d, flags=0x%08x, field=%s, sequence=%d, memory=%s",
4825bc3cb74SMauro Carvalho Chehab 			p->timestamp.tv_sec / 3600,
4835bc3cb74SMauro Carvalho Chehab 			(int)(p->timestamp.tv_sec / 60) % 60,
4845bc3cb74SMauro Carvalho Chehab 			(int)(p->timestamp.tv_sec % 60),
4855bc3cb74SMauro Carvalho Chehab 			(long)p->timestamp.tv_usec,
4865bc3cb74SMauro Carvalho Chehab 			p->index,
48762fed26fSHans Verkuil 			prt_names(p->type, v4l2_type_names), p->request_fd,
4885bc3cb74SMauro Carvalho Chehab 			p->flags, prt_names(p->field, v4l2_field_names),
4895bc3cb74SMauro Carvalho Chehab 			p->sequence, prt_names(p->memory, v4l2_memory_names));
4905bc3cb74SMauro Carvalho Chehab 
4915bc3cb74SMauro Carvalho Chehab 	if (V4L2_TYPE_IS_MULTIPLANAR(p->type) && p->m.planes) {
4925bc3cb74SMauro Carvalho Chehab 		pr_cont("\n");
4935bc3cb74SMauro Carvalho Chehab 		for (i = 0; i < p->length; ++i) {
4945bc3cb74SMauro Carvalho Chehab 			plane = &p->m.planes[i];
4955bc3cb74SMauro Carvalho Chehab 			printk(KERN_DEBUG
4968720427cSMauro Carvalho Chehab 				"plane %d: bytesused=%d, data_offset=0x%08x, offset/userptr=0x%lx, length=%d\n",
4975bc3cb74SMauro Carvalho Chehab 				i, plane->bytesused, plane->data_offset,
4985bc3cb74SMauro Carvalho Chehab 				plane->m.userptr, plane->length);
4995bc3cb74SMauro Carvalho Chehab 		}
5005bc3cb74SMauro Carvalho Chehab 	} else {
501560dde24SHans Verkuil 		pr_cont(", bytesused=%d, offset/userptr=0x%lx, length=%d\n",
5025bc3cb74SMauro Carvalho Chehab 			p->bytesused, p->m.userptr, p->length);
5035bc3cb74SMauro Carvalho Chehab 	}
5045bc3cb74SMauro Carvalho Chehab 
5058720427cSMauro Carvalho Chehab 	printk(KERN_DEBUG "timecode=%02d:%02d:%02d type=%d, flags=0x%08x, frames=%d, userbits=0x%08x\n",
5065bc3cb74SMauro Carvalho Chehab 			tc->hours, tc->minutes, tc->seconds,
5075bc3cb74SMauro Carvalho Chehab 			tc->type, tc->flags, tc->frames, *(__u32 *)tc->userbits);
5085bc3cb74SMauro Carvalho Chehab }
5095bc3cb74SMauro Carvalho Chehab 
510b799d09aSTomasz Stanislawski static void v4l_print_exportbuffer(const void *arg, bool write_only)
511b799d09aSTomasz Stanislawski {
512b799d09aSTomasz Stanislawski 	const struct v4l2_exportbuffer *p = arg;
513b799d09aSTomasz Stanislawski 
514b799d09aSTomasz Stanislawski 	pr_cont("fd=%d, type=%s, index=%u, plane=%u, flags=0x%08x\n",
515b799d09aSTomasz Stanislawski 		p->fd, prt_names(p->type, v4l2_type_names),
516b799d09aSTomasz Stanislawski 		p->index, p->plane, p->flags);
517b799d09aSTomasz Stanislawski }
518b799d09aSTomasz Stanislawski 
5195bc3cb74SMauro Carvalho Chehab static void v4l_print_create_buffers(const void *arg, bool write_only)
5205bc3cb74SMauro Carvalho Chehab {
5215bc3cb74SMauro Carvalho Chehab 	const struct v4l2_create_buffers *p = arg;
5225bc3cb74SMauro Carvalho Chehab 
5235bc3cb74SMauro Carvalho Chehab 	pr_cont("index=%d, count=%d, memory=%s, ",
5245bc3cb74SMauro Carvalho Chehab 			p->index, p->count,
5255bc3cb74SMauro Carvalho Chehab 			prt_names(p->memory, v4l2_memory_names));
5265bc3cb74SMauro Carvalho Chehab 	v4l_print_format(&p->format, write_only);
5275bc3cb74SMauro Carvalho Chehab }
5285bc3cb74SMauro Carvalho Chehab 
5295bc3cb74SMauro Carvalho Chehab static void v4l_print_streamparm(const void *arg, bool write_only)
5305bc3cb74SMauro Carvalho Chehab {
5315bc3cb74SMauro Carvalho Chehab 	const struct v4l2_streamparm *p = arg;
5325bc3cb74SMauro Carvalho Chehab 
5335bc3cb74SMauro Carvalho Chehab 	pr_cont("type=%s", prt_names(p->type, v4l2_type_names));
5345bc3cb74SMauro Carvalho Chehab 
5355bc3cb74SMauro Carvalho Chehab 	if (p->type == V4L2_BUF_TYPE_VIDEO_CAPTURE ||
5365bc3cb74SMauro Carvalho Chehab 	    p->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
5375bc3cb74SMauro Carvalho Chehab 		const struct v4l2_captureparm *c = &p->parm.capture;
5385bc3cb74SMauro Carvalho Chehab 
5398720427cSMauro Carvalho Chehab 		pr_cont(", capability=0x%x, capturemode=0x%x, timeperframe=%d/%d, extendedmode=%d, readbuffers=%d\n",
5405bc3cb74SMauro Carvalho Chehab 			c->capability, c->capturemode,
5415bc3cb74SMauro Carvalho Chehab 			c->timeperframe.numerator, c->timeperframe.denominator,
5425bc3cb74SMauro Carvalho Chehab 			c->extendedmode, c->readbuffers);
5435bc3cb74SMauro Carvalho Chehab 	} else if (p->type == V4L2_BUF_TYPE_VIDEO_OUTPUT ||
5445bc3cb74SMauro Carvalho Chehab 		   p->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
5455bc3cb74SMauro Carvalho Chehab 		const struct v4l2_outputparm *c = &p->parm.output;
5465bc3cb74SMauro Carvalho Chehab 
5478720427cSMauro Carvalho Chehab 		pr_cont(", capability=0x%x, outputmode=0x%x, timeperframe=%d/%d, extendedmode=%d, writebuffers=%d\n",
5485bc3cb74SMauro Carvalho Chehab 			c->capability, c->outputmode,
5495bc3cb74SMauro Carvalho Chehab 			c->timeperframe.numerator, c->timeperframe.denominator,
5505bc3cb74SMauro Carvalho Chehab 			c->extendedmode, c->writebuffers);
551560dde24SHans Verkuil 	} else {
552560dde24SHans Verkuil 		pr_cont("\n");
5535bc3cb74SMauro Carvalho Chehab 	}
5545bc3cb74SMauro Carvalho Chehab }
5555bc3cb74SMauro Carvalho Chehab 
5565bc3cb74SMauro Carvalho Chehab static void v4l_print_queryctrl(const void *arg, bool write_only)
5575bc3cb74SMauro Carvalho Chehab {
5585bc3cb74SMauro Carvalho Chehab 	const struct v4l2_queryctrl *p = arg;
5595bc3cb74SMauro Carvalho Chehab 
5608720427cSMauro Carvalho Chehab 	pr_cont("id=0x%x, type=%d, name=%.*s, min/max=%d/%d, step=%d, default=%d, flags=0x%08x\n",
56127d5a87cSHans Verkuil 			p->id, p->type, (int)sizeof(p->name), p->name,
5625bc3cb74SMauro Carvalho Chehab 			p->minimum, p->maximum,
5635bc3cb74SMauro Carvalho Chehab 			p->step, p->default_value, p->flags);
5645bc3cb74SMauro Carvalho Chehab }
5655bc3cb74SMauro Carvalho Chehab 
566e6bee368SHans Verkuil static void v4l_print_query_ext_ctrl(const void *arg, bool write_only)
567e6bee368SHans Verkuil {
568e6bee368SHans Verkuil 	const struct v4l2_query_ext_ctrl *p = arg;
569e6bee368SHans Verkuil 
5708720427cSMauro 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",
571e6bee368SHans Verkuil 			p->id, p->type, (int)sizeof(p->name), p->name,
572e6bee368SHans Verkuil 			p->minimum, p->maximum,
573e6bee368SHans Verkuil 			p->step, p->default_value, p->flags,
574e6bee368SHans Verkuil 			p->elem_size, p->elems, p->nr_of_dims,
5750176077aSHans Verkuil 			p->dims[0], p->dims[1], p->dims[2], p->dims[3]);
576e6bee368SHans Verkuil }
577e6bee368SHans Verkuil 
5785bc3cb74SMauro Carvalho Chehab static void v4l_print_querymenu(const void *arg, bool write_only)
5795bc3cb74SMauro Carvalho Chehab {
5805bc3cb74SMauro Carvalho Chehab 	const struct v4l2_querymenu *p = arg;
5815bc3cb74SMauro Carvalho Chehab 
5825bc3cb74SMauro Carvalho Chehab 	pr_cont("id=0x%x, index=%d\n", p->id, p->index);
5835bc3cb74SMauro Carvalho Chehab }
5845bc3cb74SMauro Carvalho Chehab 
5855bc3cb74SMauro Carvalho Chehab static void v4l_print_control(const void *arg, bool write_only)
5865bc3cb74SMauro Carvalho Chehab {
5875bc3cb74SMauro Carvalho Chehab 	const struct v4l2_control *p = arg;
5885bc3cb74SMauro Carvalho Chehab 
5895bc3cb74SMauro Carvalho Chehab 	pr_cont("id=0x%x, value=%d\n", p->id, p->value);
5905bc3cb74SMauro Carvalho Chehab }
5915bc3cb74SMauro Carvalho Chehab 
5925bc3cb74SMauro Carvalho Chehab static void v4l_print_ext_controls(const void *arg, bool write_only)
5935bc3cb74SMauro Carvalho Chehab {
5945bc3cb74SMauro Carvalho Chehab 	const struct v4l2_ext_controls *p = arg;
5955bc3cb74SMauro Carvalho Chehab 	int i;
5965bc3cb74SMauro Carvalho Chehab 
597f23317adSAlexandre Courbot 	pr_cont("which=0x%x, count=%d, error_idx=%d, request_fd=%d",
598f23317adSAlexandre Courbot 			p->which, p->count, p->error_idx, p->request_fd);
5995bc3cb74SMauro Carvalho Chehab 	for (i = 0; i < p->count; i++) {
600017ab36aSHans Verkuil 		if (!p->controls[i].size)
6015bc3cb74SMauro Carvalho Chehab 			pr_cont(", id/val=0x%x/0x%x",
6025bc3cb74SMauro Carvalho Chehab 				p->controls[i].id, p->controls[i].value);
6035bc3cb74SMauro Carvalho Chehab 		else
6045bc3cb74SMauro Carvalho Chehab 			pr_cont(", id/size=0x%x/%u",
6055bc3cb74SMauro Carvalho Chehab 				p->controls[i].id, p->controls[i].size);
6065bc3cb74SMauro Carvalho Chehab 	}
6075bc3cb74SMauro Carvalho Chehab 	pr_cont("\n");
6085bc3cb74SMauro Carvalho Chehab }
6095bc3cb74SMauro Carvalho Chehab 
6105bc3cb74SMauro Carvalho Chehab static void v4l_print_cropcap(const void *arg, bool write_only)
6115bc3cb74SMauro Carvalho Chehab {
6125bc3cb74SMauro Carvalho Chehab 	const struct v4l2_cropcap *p = arg;
6135bc3cb74SMauro Carvalho Chehab 
6148720427cSMauro 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",
6155bc3cb74SMauro Carvalho Chehab 		prt_names(p->type, v4l2_type_names),
6165bc3cb74SMauro Carvalho Chehab 		p->bounds.width, p->bounds.height,
6175bc3cb74SMauro Carvalho Chehab 		p->bounds.left, p->bounds.top,
6185bc3cb74SMauro Carvalho Chehab 		p->defrect.width, p->defrect.height,
6195bc3cb74SMauro Carvalho Chehab 		p->defrect.left, p->defrect.top,
6205bc3cb74SMauro Carvalho Chehab 		p->pixelaspect.numerator, p->pixelaspect.denominator);
6215bc3cb74SMauro Carvalho Chehab }
6225bc3cb74SMauro Carvalho Chehab 
6235bc3cb74SMauro Carvalho Chehab static void v4l_print_crop(const void *arg, bool write_only)
6245bc3cb74SMauro Carvalho Chehab {
6255bc3cb74SMauro Carvalho Chehab 	const struct v4l2_crop *p = arg;
6265bc3cb74SMauro Carvalho Chehab 
6275bc3cb74SMauro Carvalho Chehab 	pr_cont("type=%s, wxh=%dx%d, x,y=%d,%d\n",
6285bc3cb74SMauro Carvalho Chehab 		prt_names(p->type, v4l2_type_names),
6295bc3cb74SMauro Carvalho Chehab 		p->c.width, p->c.height,
6305bc3cb74SMauro Carvalho Chehab 		p->c.left, p->c.top);
6315bc3cb74SMauro Carvalho Chehab }
6325bc3cb74SMauro Carvalho Chehab 
6335bc3cb74SMauro Carvalho Chehab static void v4l_print_selection(const void *arg, bool write_only)
6345bc3cb74SMauro Carvalho Chehab {
6355bc3cb74SMauro Carvalho Chehab 	const struct v4l2_selection *p = arg;
6365bc3cb74SMauro Carvalho Chehab 
6375bc3cb74SMauro Carvalho Chehab 	pr_cont("type=%s, target=%d, flags=0x%x, wxh=%dx%d, x,y=%d,%d\n",
6385bc3cb74SMauro Carvalho Chehab 		prt_names(p->type, v4l2_type_names),
6395bc3cb74SMauro Carvalho Chehab 		p->target, p->flags,
6405bc3cb74SMauro Carvalho Chehab 		p->r.width, p->r.height, p->r.left, p->r.top);
6415bc3cb74SMauro Carvalho Chehab }
6425bc3cb74SMauro Carvalho Chehab 
6435bc3cb74SMauro Carvalho Chehab static void v4l_print_jpegcompression(const void *arg, bool write_only)
6445bc3cb74SMauro Carvalho Chehab {
6455bc3cb74SMauro Carvalho Chehab 	const struct v4l2_jpegcompression *p = arg;
6465bc3cb74SMauro Carvalho Chehab 
6478720427cSMauro Carvalho Chehab 	pr_cont("quality=%d, APPn=%d, APP_len=%d, COM_len=%d, jpeg_markers=0x%x\n",
6485bc3cb74SMauro Carvalho Chehab 		p->quality, p->APPn, p->APP_len,
6495bc3cb74SMauro Carvalho Chehab 		p->COM_len, p->jpeg_markers);
6505bc3cb74SMauro Carvalho Chehab }
6515bc3cb74SMauro Carvalho Chehab 
6525bc3cb74SMauro Carvalho Chehab static void v4l_print_enc_idx(const void *arg, bool write_only)
6535bc3cb74SMauro Carvalho Chehab {
6545bc3cb74SMauro Carvalho Chehab 	const struct v4l2_enc_idx *p = arg;
6555bc3cb74SMauro Carvalho Chehab 
6565bc3cb74SMauro Carvalho Chehab 	pr_cont("entries=%d, entries_cap=%d\n",
6575bc3cb74SMauro Carvalho Chehab 			p->entries, p->entries_cap);
6585bc3cb74SMauro Carvalho Chehab }
6595bc3cb74SMauro Carvalho Chehab 
6605bc3cb74SMauro Carvalho Chehab static void v4l_print_encoder_cmd(const void *arg, bool write_only)
6615bc3cb74SMauro Carvalho Chehab {
6625bc3cb74SMauro Carvalho Chehab 	const struct v4l2_encoder_cmd *p = arg;
6635bc3cb74SMauro Carvalho Chehab 
6645bc3cb74SMauro Carvalho Chehab 	pr_cont("cmd=%d, flags=0x%x\n",
6655bc3cb74SMauro Carvalho Chehab 			p->cmd, p->flags);
6665bc3cb74SMauro Carvalho Chehab }
6675bc3cb74SMauro Carvalho Chehab 
6685bc3cb74SMauro Carvalho Chehab static void v4l_print_decoder_cmd(const void *arg, bool write_only)
6695bc3cb74SMauro Carvalho Chehab {
6705bc3cb74SMauro Carvalho Chehab 	const struct v4l2_decoder_cmd *p = arg;
6715bc3cb74SMauro Carvalho Chehab 
6725bc3cb74SMauro Carvalho Chehab 	pr_cont("cmd=%d, flags=0x%x\n", p->cmd, p->flags);
6735bc3cb74SMauro Carvalho Chehab 
6745bc3cb74SMauro Carvalho Chehab 	if (p->cmd == V4L2_DEC_CMD_START)
6755bc3cb74SMauro Carvalho Chehab 		pr_info("speed=%d, format=%u\n",
6765bc3cb74SMauro Carvalho Chehab 				p->start.speed, p->start.format);
6775bc3cb74SMauro Carvalho Chehab 	else if (p->cmd == V4L2_DEC_CMD_STOP)
6785bc3cb74SMauro Carvalho Chehab 		pr_info("pts=%llu\n", p->stop.pts);
6795bc3cb74SMauro Carvalho Chehab }
6805bc3cb74SMauro Carvalho Chehab 
68196b03d2aSHans Verkuil static void v4l_print_dbg_chip_info(const void *arg, bool write_only)
68279b0c640SHans Verkuil {
68396b03d2aSHans Verkuil 	const struct v4l2_dbg_chip_info *p = arg;
68479b0c640SHans Verkuil 
68579b0c640SHans Verkuil 	pr_cont("type=%u, ", p->match.type);
6863eef2510SHans Verkuil 	if (p->match.type == V4L2_CHIP_MATCH_I2C_DRIVER)
68779b0c640SHans Verkuil 		pr_cont("name=%.*s, ",
68879b0c640SHans Verkuil 				(int)sizeof(p->match.name), p->match.name);
68979b0c640SHans Verkuil 	else
69079b0c640SHans Verkuil 		pr_cont("addr=%u, ", p->match.addr);
69179b0c640SHans Verkuil 	pr_cont("name=%.*s\n", (int)sizeof(p->name), p->name);
69279b0c640SHans Verkuil }
69379b0c640SHans Verkuil 
6945bc3cb74SMauro Carvalho Chehab static void v4l_print_dbg_register(const void *arg, bool write_only)
6955bc3cb74SMauro Carvalho Chehab {
6965bc3cb74SMauro Carvalho Chehab 	const struct v4l2_dbg_register *p = arg;
6975bc3cb74SMauro Carvalho Chehab 
6985bc3cb74SMauro Carvalho Chehab 	pr_cont("type=%u, ", p->match.type);
6993eef2510SHans Verkuil 	if (p->match.type == V4L2_CHIP_MATCH_I2C_DRIVER)
70027d5a87cSHans Verkuil 		pr_cont("name=%.*s, ",
70127d5a87cSHans Verkuil 				(int)sizeof(p->match.name), p->match.name);
7025bc3cb74SMauro Carvalho Chehab 	else
7035bc3cb74SMauro Carvalho Chehab 		pr_cont("addr=%u, ", p->match.addr);
7045bc3cb74SMauro Carvalho Chehab 	pr_cont("reg=0x%llx, val=0x%llx\n",
7055bc3cb74SMauro Carvalho Chehab 			p->reg, p->val);
7065bc3cb74SMauro Carvalho Chehab }
7075bc3cb74SMauro Carvalho Chehab 
7085bc3cb74SMauro Carvalho Chehab static void v4l_print_dv_timings(const void *arg, bool write_only)
7095bc3cb74SMauro Carvalho Chehab {
7105bc3cb74SMauro Carvalho Chehab 	const struct v4l2_dv_timings *p = arg;
7115bc3cb74SMauro Carvalho Chehab 
7125bc3cb74SMauro Carvalho Chehab 	switch (p->type) {
7135bc3cb74SMauro Carvalho Chehab 	case V4L2_DV_BT_656_1120:
7148720427cSMauro 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",
7155bc3cb74SMauro Carvalho Chehab 				p->bt.interlaced, p->bt.pixelclock,
7165bc3cb74SMauro Carvalho Chehab 				p->bt.width, p->bt.height,
7175bc3cb74SMauro Carvalho Chehab 				p->bt.polarities, p->bt.hfrontporch,
7185bc3cb74SMauro Carvalho Chehab 				p->bt.hsync, p->bt.hbackporch,
7195bc3cb74SMauro Carvalho Chehab 				p->bt.vfrontporch, p->bt.vsync,
7205bc3cb74SMauro Carvalho Chehab 				p->bt.vbackporch, p->bt.il_vfrontporch,
7215bc3cb74SMauro Carvalho Chehab 				p->bt.il_vsync, p->bt.il_vbackporch,
7225bc3cb74SMauro Carvalho Chehab 				p->bt.standards, p->bt.flags);
7235bc3cb74SMauro Carvalho Chehab 		break;
7245bc3cb74SMauro Carvalho Chehab 	default:
7255bc3cb74SMauro Carvalho Chehab 		pr_cont("type=%d\n", p->type);
7265bc3cb74SMauro Carvalho Chehab 		break;
7275bc3cb74SMauro Carvalho Chehab 	}
7285bc3cb74SMauro Carvalho Chehab }
7295bc3cb74SMauro Carvalho Chehab 
7305bc3cb74SMauro Carvalho Chehab static void v4l_print_enum_dv_timings(const void *arg, bool write_only)
7315bc3cb74SMauro Carvalho Chehab {
7325bc3cb74SMauro Carvalho Chehab 	const struct v4l2_enum_dv_timings *p = arg;
7335bc3cb74SMauro Carvalho Chehab 
7345bc3cb74SMauro Carvalho Chehab 	pr_cont("index=%u, ", p->index);
7355bc3cb74SMauro Carvalho Chehab 	v4l_print_dv_timings(&p->timings, write_only);
7365bc3cb74SMauro Carvalho Chehab }
7375bc3cb74SMauro Carvalho Chehab 
7385bc3cb74SMauro Carvalho Chehab static void v4l_print_dv_timings_cap(const void *arg, bool write_only)
7395bc3cb74SMauro Carvalho Chehab {
7405bc3cb74SMauro Carvalho Chehab 	const struct v4l2_dv_timings_cap *p = arg;
7415bc3cb74SMauro Carvalho Chehab 
7425bc3cb74SMauro Carvalho Chehab 	switch (p->type) {
7435bc3cb74SMauro Carvalho Chehab 	case V4L2_DV_BT_656_1120:
7448720427cSMauro Carvalho Chehab 		pr_cont("type=bt-656/1120, width=%u-%u, height=%u-%u, pixelclock=%llu-%llu, standards=0x%x, capabilities=0x%x\n",
7455bc3cb74SMauro Carvalho Chehab 			p->bt.min_width, p->bt.max_width,
7465bc3cb74SMauro Carvalho Chehab 			p->bt.min_height, p->bt.max_height,
7475bc3cb74SMauro Carvalho Chehab 			p->bt.min_pixelclock, p->bt.max_pixelclock,
7485bc3cb74SMauro Carvalho Chehab 			p->bt.standards, p->bt.capabilities);
7495bc3cb74SMauro Carvalho Chehab 		break;
7505bc3cb74SMauro Carvalho Chehab 	default:
7515bc3cb74SMauro Carvalho Chehab 		pr_cont("type=%u\n", p->type);
7525bc3cb74SMauro Carvalho Chehab 		break;
7535bc3cb74SMauro Carvalho Chehab 	}
7545bc3cb74SMauro Carvalho Chehab }
7555bc3cb74SMauro Carvalho Chehab 
7565bc3cb74SMauro Carvalho Chehab static void v4l_print_frmsizeenum(const void *arg, bool write_only)
7575bc3cb74SMauro Carvalho Chehab {
7585bc3cb74SMauro Carvalho Chehab 	const struct v4l2_frmsizeenum *p = arg;
7595bc3cb74SMauro Carvalho Chehab 
7605bc3cb74SMauro Carvalho Chehab 	pr_cont("index=%u, pixelformat=%c%c%c%c, type=%u",
7615bc3cb74SMauro Carvalho Chehab 			p->index,
7625bc3cb74SMauro Carvalho Chehab 			(p->pixel_format & 0xff),
7635bc3cb74SMauro Carvalho Chehab 			(p->pixel_format >>  8) & 0xff,
7645bc3cb74SMauro Carvalho Chehab 			(p->pixel_format >> 16) & 0xff,
7655bc3cb74SMauro Carvalho Chehab 			(p->pixel_format >> 24) & 0xff,
7665bc3cb74SMauro Carvalho Chehab 			p->type);
7675bc3cb74SMauro Carvalho Chehab 	switch (p->type) {
7685bc3cb74SMauro Carvalho Chehab 	case V4L2_FRMSIZE_TYPE_DISCRETE:
769560dde24SHans Verkuil 		pr_cont(", wxh=%ux%u\n",
7705bc3cb74SMauro Carvalho Chehab 			p->discrete.width, p->discrete.height);
7715bc3cb74SMauro Carvalho Chehab 		break;
7725bc3cb74SMauro Carvalho Chehab 	case V4L2_FRMSIZE_TYPE_STEPWISE:
773560dde24SHans Verkuil 		pr_cont(", min=%ux%u, max=%ux%u, step=%ux%u\n",
7742489477eSRicardo Ribalda 				p->stepwise.min_width,
7752489477eSRicardo Ribalda 				p->stepwise.min_height,
7762489477eSRicardo Ribalda 				p->stepwise.max_width,
7772489477eSRicardo Ribalda 				p->stepwise.max_height,
7782489477eSRicardo Ribalda 				p->stepwise.step_width,
7792489477eSRicardo Ribalda 				p->stepwise.step_height);
7805bc3cb74SMauro Carvalho Chehab 		break;
7815bc3cb74SMauro Carvalho Chehab 	case V4L2_FRMSIZE_TYPE_CONTINUOUS:
7825bc3cb74SMauro Carvalho Chehab 		/* fall through */
7835bc3cb74SMauro Carvalho Chehab 	default:
7845bc3cb74SMauro Carvalho Chehab 		pr_cont("\n");
7855bc3cb74SMauro Carvalho Chehab 		break;
7865bc3cb74SMauro Carvalho Chehab 	}
7875bc3cb74SMauro Carvalho Chehab }
7885bc3cb74SMauro Carvalho Chehab 
7895bc3cb74SMauro Carvalho Chehab static void v4l_print_frmivalenum(const void *arg, bool write_only)
7905bc3cb74SMauro Carvalho Chehab {
7915bc3cb74SMauro Carvalho Chehab 	const struct v4l2_frmivalenum *p = arg;
7925bc3cb74SMauro Carvalho Chehab 
7935bc3cb74SMauro Carvalho Chehab 	pr_cont("index=%u, pixelformat=%c%c%c%c, wxh=%ux%u, type=%u",
7945bc3cb74SMauro Carvalho Chehab 			p->index,
7955bc3cb74SMauro Carvalho Chehab 			(p->pixel_format & 0xff),
7965bc3cb74SMauro Carvalho Chehab 			(p->pixel_format >>  8) & 0xff,
7975bc3cb74SMauro Carvalho Chehab 			(p->pixel_format >> 16) & 0xff,
7985bc3cb74SMauro Carvalho Chehab 			(p->pixel_format >> 24) & 0xff,
7995bc3cb74SMauro Carvalho Chehab 			p->width, p->height, p->type);
8005bc3cb74SMauro Carvalho Chehab 	switch (p->type) {
8015bc3cb74SMauro Carvalho Chehab 	case V4L2_FRMIVAL_TYPE_DISCRETE:
802560dde24SHans Verkuil 		pr_cont(", fps=%d/%d\n",
8035bc3cb74SMauro Carvalho Chehab 				p->discrete.numerator,
8045bc3cb74SMauro Carvalho Chehab 				p->discrete.denominator);
8055bc3cb74SMauro Carvalho Chehab 		break;
8065bc3cb74SMauro Carvalho Chehab 	case V4L2_FRMIVAL_TYPE_STEPWISE:
807560dde24SHans Verkuil 		pr_cont(", min=%d/%d, max=%d/%d, step=%d/%d\n",
8085bc3cb74SMauro Carvalho Chehab 				p->stepwise.min.numerator,
8095bc3cb74SMauro Carvalho Chehab 				p->stepwise.min.denominator,
8105bc3cb74SMauro Carvalho Chehab 				p->stepwise.max.numerator,
8115bc3cb74SMauro Carvalho Chehab 				p->stepwise.max.denominator,
8125bc3cb74SMauro Carvalho Chehab 				p->stepwise.step.numerator,
8135bc3cb74SMauro Carvalho Chehab 				p->stepwise.step.denominator);
8145bc3cb74SMauro Carvalho Chehab 		break;
8155bc3cb74SMauro Carvalho Chehab 	case V4L2_FRMIVAL_TYPE_CONTINUOUS:
8165bc3cb74SMauro Carvalho Chehab 		/* fall through */
8175bc3cb74SMauro Carvalho Chehab 	default:
8185bc3cb74SMauro Carvalho Chehab 		pr_cont("\n");
8195bc3cb74SMauro Carvalho Chehab 		break;
8205bc3cb74SMauro Carvalho Chehab 	}
8215bc3cb74SMauro Carvalho Chehab }
8225bc3cb74SMauro Carvalho Chehab 
8235bc3cb74SMauro Carvalho Chehab static void v4l_print_event(const void *arg, bool write_only)
8245bc3cb74SMauro Carvalho Chehab {
8255bc3cb74SMauro Carvalho Chehab 	const struct v4l2_event *p = arg;
8265bc3cb74SMauro Carvalho Chehab 	const struct v4l2_event_ctrl *c;
8275bc3cb74SMauro Carvalho Chehab 
8288720427cSMauro Carvalho Chehab 	pr_cont("type=0x%x, pending=%u, sequence=%u, id=%u, timestamp=%lu.%9.9lu\n",
8295bc3cb74SMauro Carvalho Chehab 			p->type, p->pending, p->sequence, p->id,
8305bc3cb74SMauro Carvalho Chehab 			p->timestamp.tv_sec, p->timestamp.tv_nsec);
8315bc3cb74SMauro Carvalho Chehab 	switch (p->type) {
8325bc3cb74SMauro Carvalho Chehab 	case V4L2_EVENT_VSYNC:
8335bc3cb74SMauro Carvalho Chehab 		printk(KERN_DEBUG "field=%s\n",
8345bc3cb74SMauro Carvalho Chehab 			prt_names(p->u.vsync.field, v4l2_field_names));
8355bc3cb74SMauro Carvalho Chehab 		break;
8365bc3cb74SMauro Carvalho Chehab 	case V4L2_EVENT_CTRL:
8375bc3cb74SMauro Carvalho Chehab 		c = &p->u.ctrl;
8385bc3cb74SMauro Carvalho Chehab 		printk(KERN_DEBUG "changes=0x%x, type=%u, ",
8395bc3cb74SMauro Carvalho Chehab 			c->changes, c->type);
8405bc3cb74SMauro Carvalho Chehab 		if (c->type == V4L2_CTRL_TYPE_INTEGER64)
8415bc3cb74SMauro Carvalho Chehab 			pr_cont("value64=%lld, ", c->value64);
8425bc3cb74SMauro Carvalho Chehab 		else
8435bc3cb74SMauro Carvalho Chehab 			pr_cont("value=%d, ", c->value);
8448720427cSMauro Carvalho Chehab 		pr_cont("flags=0x%x, minimum=%d, maximum=%d, step=%d, default_value=%d\n",
8455bc3cb74SMauro Carvalho Chehab 			c->flags, c->minimum, c->maximum,
8465bc3cb74SMauro Carvalho Chehab 			c->step, c->default_value);
8475bc3cb74SMauro Carvalho Chehab 		break;
8485bc3cb74SMauro Carvalho Chehab 	case V4L2_EVENT_FRAME_SYNC:
8495bc3cb74SMauro Carvalho Chehab 		pr_cont("frame_sequence=%u\n",
8505bc3cb74SMauro Carvalho Chehab 			p->u.frame_sync.frame_sequence);
8515bc3cb74SMauro Carvalho Chehab 		break;
8525bc3cb74SMauro Carvalho Chehab 	}
8535bc3cb74SMauro Carvalho Chehab }
8545bc3cb74SMauro Carvalho Chehab 
8555bc3cb74SMauro Carvalho Chehab static void v4l_print_event_subscription(const void *arg, bool write_only)
8565bc3cb74SMauro Carvalho Chehab {
8575bc3cb74SMauro Carvalho Chehab 	const struct v4l2_event_subscription *p = arg;
8585bc3cb74SMauro Carvalho Chehab 
8595bc3cb74SMauro Carvalho Chehab 	pr_cont("type=0x%x, id=0x%x, flags=0x%x\n",
8605bc3cb74SMauro Carvalho Chehab 			p->type, p->id, p->flags);
8615bc3cb74SMauro Carvalho Chehab }
8625bc3cb74SMauro Carvalho Chehab 
8635bc3cb74SMauro Carvalho Chehab static void v4l_print_sliced_vbi_cap(const void *arg, bool write_only)
8645bc3cb74SMauro Carvalho Chehab {
8655bc3cb74SMauro Carvalho Chehab 	const struct v4l2_sliced_vbi_cap *p = arg;
8665bc3cb74SMauro Carvalho Chehab 	int i;
8675bc3cb74SMauro Carvalho Chehab 
8685bc3cb74SMauro Carvalho Chehab 	pr_cont("type=%s, service_set=0x%08x\n",
8695bc3cb74SMauro Carvalho Chehab 			prt_names(p->type, v4l2_type_names), p->service_set);
8705bc3cb74SMauro Carvalho Chehab 	for (i = 0; i < 24; i++)
8715bc3cb74SMauro Carvalho Chehab 		printk(KERN_DEBUG "line[%02u]=0x%04x, 0x%04x\n", i,
8725bc3cb74SMauro Carvalho Chehab 				p->service_lines[0][i],
8735bc3cb74SMauro Carvalho Chehab 				p->service_lines[1][i]);
8745bc3cb74SMauro Carvalho Chehab }
8755bc3cb74SMauro Carvalho Chehab 
8765bc3cb74SMauro Carvalho Chehab static void v4l_print_freq_band(const void *arg, bool write_only)
8775bc3cb74SMauro Carvalho Chehab {
8785bc3cb74SMauro Carvalho Chehab 	const struct v4l2_frequency_band *p = arg;
8795bc3cb74SMauro Carvalho Chehab 
8808720427cSMauro Carvalho Chehab 	pr_cont("tuner=%u, type=%u, index=%u, capability=0x%x, rangelow=%u, rangehigh=%u, modulation=0x%x\n",
8815bc3cb74SMauro Carvalho Chehab 			p->tuner, p->type, p->index,
8825bc3cb74SMauro Carvalho Chehab 			p->capability, p->rangelow,
8835bc3cb74SMauro Carvalho Chehab 			p->rangehigh, p->modulation);
8845bc3cb74SMauro Carvalho Chehab }
8855bc3cb74SMauro Carvalho Chehab 
886dd519bb3SHans Verkuil static void v4l_print_edid(const void *arg, bool write_only)
887dd519bb3SHans Verkuil {
888dd519bb3SHans Verkuil 	const struct v4l2_edid *p = arg;
889dd519bb3SHans Verkuil 
890dd519bb3SHans Verkuil 	pr_cont("pad=%u, start_block=%u, blocks=%u\n",
891dd519bb3SHans Verkuil 		p->pad, p->start_block, p->blocks);
892dd519bb3SHans Verkuil }
893dd519bb3SHans Verkuil 
8945bc3cb74SMauro Carvalho Chehab static void v4l_print_u32(const void *arg, bool write_only)
8955bc3cb74SMauro Carvalho Chehab {
8965bc3cb74SMauro Carvalho Chehab 	pr_cont("value=%u\n", *(const u32 *)arg);
8975bc3cb74SMauro Carvalho Chehab }
8985bc3cb74SMauro Carvalho Chehab 
8995bc3cb74SMauro Carvalho Chehab static void v4l_print_newline(const void *arg, bool write_only)
9005bc3cb74SMauro Carvalho Chehab {
9015bc3cb74SMauro Carvalho Chehab 	pr_cont("\n");
9025bc3cb74SMauro Carvalho Chehab }
9035bc3cb74SMauro Carvalho Chehab 
9045bc3cb74SMauro Carvalho Chehab static void v4l_print_default(const void *arg, bool write_only)
9055bc3cb74SMauro Carvalho Chehab {
9065bc3cb74SMauro Carvalho Chehab 	pr_cont("driver-specific ioctl\n");
9075bc3cb74SMauro Carvalho Chehab }
9085bc3cb74SMauro Carvalho Chehab 
9095bc3cb74SMauro Carvalho Chehab static int check_ext_ctrls(struct v4l2_ext_controls *c, int allow_priv)
9105bc3cb74SMauro Carvalho Chehab {
9115bc3cb74SMauro Carvalho Chehab 	__u32 i;
9125bc3cb74SMauro Carvalho Chehab 
9135bc3cb74SMauro Carvalho Chehab 	/* zero the reserved fields */
914f23317adSAlexandre Courbot 	c->reserved[0] = 0;
9155bc3cb74SMauro Carvalho Chehab 	for (i = 0; i < c->count; i++)
9165bc3cb74SMauro Carvalho Chehab 		c->controls[i].reserved2[0] = 0;
9175bc3cb74SMauro Carvalho Chehab 
9185bc3cb74SMauro Carvalho Chehab 	/* V4L2_CID_PRIVATE_BASE cannot be used as control class
9195bc3cb74SMauro Carvalho Chehab 	   when using extended controls.
9205bc3cb74SMauro Carvalho Chehab 	   Only when passed in through VIDIOC_G_CTRL and VIDIOC_S_CTRL
9215bc3cb74SMauro Carvalho Chehab 	   is it allowed for backwards compatibility.
9225bc3cb74SMauro Carvalho Chehab 	 */
9230f8017beSRicardo Ribalda 	if (!allow_priv && c->which == V4L2_CID_PRIVATE_BASE)
9245bc3cb74SMauro Carvalho Chehab 		return 0;
9250f8017beSRicardo Ribalda 	if (!c->which)
9269b239b22SHans Verkuil 		return 1;
9275bc3cb74SMauro Carvalho Chehab 	/* Check that all controls are from the same control class. */
9285bc3cb74SMauro Carvalho Chehab 	for (i = 0; i < c->count; i++) {
9290f8017beSRicardo Ribalda 		if (V4L2_CTRL_ID2WHICH(c->controls[i].id) != c->which) {
9305bc3cb74SMauro Carvalho Chehab 			c->error_idx = i;
9315bc3cb74SMauro Carvalho Chehab 			return 0;
9325bc3cb74SMauro Carvalho Chehab 		}
9335bc3cb74SMauro Carvalho Chehab 	}
9345bc3cb74SMauro Carvalho Chehab 	return 1;
9355bc3cb74SMauro Carvalho Chehab }
9365bc3cb74SMauro Carvalho Chehab 
9374b20259fSHans Verkuil static int check_fmt(struct file *file, enum v4l2_buf_type type)
9385bc3cb74SMauro Carvalho Chehab {
9394b20259fSHans Verkuil 	struct video_device *vfd = video_devdata(file);
9404b20259fSHans Verkuil 	const struct v4l2_ioctl_ops *ops = vfd->ioctl_ops;
9414b20259fSHans Verkuil 	bool is_vid = vfd->vfl_type == VFL_TYPE_GRABBER;
9424b20259fSHans Verkuil 	bool is_vbi = vfd->vfl_type == VFL_TYPE_VBI;
943582c52cbSAntti Palosaari 	bool is_sdr = vfd->vfl_type == VFL_TYPE_SDR;
944b2fe22d0SNick Dyer 	bool is_tch = vfd->vfl_type == VFL_TYPE_TOUCH;
9454b20259fSHans Verkuil 	bool is_rx = vfd->vfl_dir != VFL_DIR_TX;
9464b20259fSHans Verkuil 	bool is_tx = vfd->vfl_dir != VFL_DIR_RX;
9474b20259fSHans Verkuil 
9485bc3cb74SMauro Carvalho Chehab 	if (ops == NULL)
9495bc3cb74SMauro Carvalho Chehab 		return -EINVAL;
9505bc3cb74SMauro Carvalho Chehab 
9515bc3cb74SMauro Carvalho Chehab 	switch (type) {
9525bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_CAPTURE:
953b2fe22d0SNick Dyer 		if ((is_vid || is_tch) && is_rx &&
9544b20259fSHans Verkuil 		    (ops->vidioc_g_fmt_vid_cap || ops->vidioc_g_fmt_vid_cap_mplane))
9555bc3cb74SMauro Carvalho Chehab 			return 0;
9565bc3cb74SMauro Carvalho Chehab 		break;
9575bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
9584b20259fSHans Verkuil 		if (is_vid && is_rx && ops->vidioc_g_fmt_vid_cap_mplane)
9595bc3cb74SMauro Carvalho Chehab 			return 0;
9605bc3cb74SMauro Carvalho Chehab 		break;
9615bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_OVERLAY:
9624b20259fSHans Verkuil 		if (is_vid && is_rx && ops->vidioc_g_fmt_vid_overlay)
9635bc3cb74SMauro Carvalho Chehab 			return 0;
9645bc3cb74SMauro Carvalho Chehab 		break;
9655bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_OUTPUT:
9664b20259fSHans Verkuil 		if (is_vid && is_tx &&
9674b20259fSHans Verkuil 		    (ops->vidioc_g_fmt_vid_out || ops->vidioc_g_fmt_vid_out_mplane))
9685bc3cb74SMauro Carvalho Chehab 			return 0;
9695bc3cb74SMauro Carvalho Chehab 		break;
9705bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
9714b20259fSHans Verkuil 		if (is_vid && is_tx && ops->vidioc_g_fmt_vid_out_mplane)
9725bc3cb74SMauro Carvalho Chehab 			return 0;
9735bc3cb74SMauro Carvalho Chehab 		break;
9745bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
9754b20259fSHans Verkuil 		if (is_vid && is_tx && ops->vidioc_g_fmt_vid_out_overlay)
9765bc3cb74SMauro Carvalho Chehab 			return 0;
9775bc3cb74SMauro Carvalho Chehab 		break;
9785bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VBI_CAPTURE:
9794b20259fSHans Verkuil 		if (is_vbi && is_rx && ops->vidioc_g_fmt_vbi_cap)
9805bc3cb74SMauro Carvalho Chehab 			return 0;
9815bc3cb74SMauro Carvalho Chehab 		break;
9825bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VBI_OUTPUT:
9834b20259fSHans Verkuil 		if (is_vbi && is_tx && ops->vidioc_g_fmt_vbi_out)
9845bc3cb74SMauro Carvalho Chehab 			return 0;
9855bc3cb74SMauro Carvalho Chehab 		break;
9865bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
9874b20259fSHans Verkuil 		if (is_vbi && is_rx && ops->vidioc_g_fmt_sliced_vbi_cap)
9885bc3cb74SMauro Carvalho Chehab 			return 0;
9895bc3cb74SMauro Carvalho Chehab 		break;
9905bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
9914b20259fSHans Verkuil 		if (is_vbi && is_tx && ops->vidioc_g_fmt_sliced_vbi_out)
9925bc3cb74SMauro Carvalho Chehab 			return 0;
9935bc3cb74SMauro Carvalho Chehab 		break;
994582c52cbSAntti Palosaari 	case V4L2_BUF_TYPE_SDR_CAPTURE:
995582c52cbSAntti Palosaari 		if (is_sdr && is_rx && ops->vidioc_g_fmt_sdr_cap)
996582c52cbSAntti Palosaari 			return 0;
997582c52cbSAntti Palosaari 		break;
9989effc72fSAntti Palosaari 	case V4L2_BUF_TYPE_SDR_OUTPUT:
9999effc72fSAntti Palosaari 		if (is_sdr && is_tx && ops->vidioc_g_fmt_sdr_out)
10009effc72fSAntti Palosaari 			return 0;
10019effc72fSAntti Palosaari 		break;
1002fb9ffa6aSLaurent Pinchart 	case V4L2_BUF_TYPE_META_CAPTURE:
1003fb9ffa6aSLaurent Pinchart 		if (is_vid && is_rx && ops->vidioc_g_fmt_meta_cap)
1004fb9ffa6aSLaurent Pinchart 			return 0;
1005fb9ffa6aSLaurent Pinchart 		break;
100672148d1aSSakari Ailus 	case V4L2_BUF_TYPE_META_OUTPUT:
100772148d1aSSakari Ailus 		if (is_vid && is_tx && ops->vidioc_g_fmt_meta_out)
100872148d1aSSakari Ailus 			return 0;
100972148d1aSSakari Ailus 		break;
1010633c98e5SHans Verkuil 	default:
10115bc3cb74SMauro Carvalho Chehab 		break;
10125bc3cb74SMauro Carvalho Chehab 	}
10135bc3cb74SMauro Carvalho Chehab 	return -EINVAL;
10145bc3cb74SMauro Carvalho Chehab }
10155bc3cb74SMauro Carvalho Chehab 
1016d52e2381SLaurent Pinchart static void v4l_sanitize_format(struct v4l2_format *fmt)
1017d52e2381SLaurent Pinchart {
1018d52e2381SLaurent Pinchart 	unsigned int offset;
1019d52e2381SLaurent Pinchart 
102014c8e80eSEzequiel Garcia 	/* Make sure num_planes is not bogus */
102114c8e80eSEzequiel Garcia 	if (fmt->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE ||
102214c8e80eSEzequiel Garcia 	    fmt->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)
102314c8e80eSEzequiel Garcia 		fmt->fmt.pix_mp.num_planes = min_t(u32, fmt->fmt.pix_mp.num_planes,
102414c8e80eSEzequiel Garcia 					       VIDEO_MAX_PLANES);
102514c8e80eSEzequiel Garcia 
1026d52e2381SLaurent Pinchart 	/*
1027d52e2381SLaurent Pinchart 	 * The v4l2_pix_format structure has been extended with fields that were
1028d52e2381SLaurent Pinchart 	 * not previously required to be set to zero by applications. The priv
1029d52e2381SLaurent Pinchart 	 * field, when set to a magic value, indicates the the extended fields
1030d52e2381SLaurent Pinchart 	 * are valid. Otherwise they will contain undefined values. To simplify
1031d52e2381SLaurent Pinchart 	 * the API towards drivers zero the extended fields and set the priv
1032d52e2381SLaurent Pinchart 	 * field to the magic value when the extended pixel format structure
1033d52e2381SLaurent Pinchart 	 * isn't used by applications.
1034d52e2381SLaurent Pinchart 	 */
1035d52e2381SLaurent Pinchart 
1036d52e2381SLaurent Pinchart 	if (fmt->type != V4L2_BUF_TYPE_VIDEO_CAPTURE &&
1037d52e2381SLaurent Pinchart 	    fmt->type != V4L2_BUF_TYPE_VIDEO_OUTPUT)
1038d52e2381SLaurent Pinchart 		return;
1039d52e2381SLaurent Pinchart 
1040d52e2381SLaurent Pinchart 	if (fmt->fmt.pix.priv == V4L2_PIX_FMT_PRIV_MAGIC)
1041d52e2381SLaurent Pinchart 		return;
1042d52e2381SLaurent Pinchart 
1043d52e2381SLaurent Pinchart 	fmt->fmt.pix.priv = V4L2_PIX_FMT_PRIV_MAGIC;
1044d52e2381SLaurent Pinchart 
1045d52e2381SLaurent Pinchart 	offset = offsetof(struct v4l2_pix_format, priv)
1046d52e2381SLaurent Pinchart 	       + sizeof(fmt->fmt.pix.priv);
1047d52e2381SLaurent Pinchart 	memset(((void *)&fmt->fmt.pix) + offset, 0,
1048d52e2381SLaurent Pinchart 	       sizeof(fmt->fmt.pix) - offset);
1049d52e2381SLaurent Pinchart }
1050d52e2381SLaurent Pinchart 
10515bc3cb74SMauro Carvalho Chehab static int v4l_querycap(const struct v4l2_ioctl_ops *ops,
10525bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
10535bc3cb74SMauro Carvalho Chehab {
10545bc3cb74SMauro Carvalho Chehab 	struct v4l2_capability *cap = (struct v4l2_capability *)arg;
10557bbe7813SHans Verkuil 	struct video_device *vfd = video_devdata(file);
1056d52e2381SLaurent Pinchart 	int ret;
10575bc3cb74SMauro Carvalho Chehab 
10585bc3cb74SMauro Carvalho Chehab 	cap->version = LINUX_VERSION_CODE;
10597bbe7813SHans Verkuil 	cap->device_caps = vfd->device_caps;
10607bbe7813SHans Verkuil 	cap->capabilities = vfd->device_caps | V4L2_CAP_DEVICE_CAPS;
1061d52e2381SLaurent Pinchart 
1062d52e2381SLaurent Pinchart 	ret = ops->vidioc_querycap(file, fh, cap);
1063d52e2381SLaurent Pinchart 
1064d52e2381SLaurent Pinchart 	cap->capabilities |= V4L2_CAP_EXT_PIX_FORMAT;
1065454a4e72SHans Verkuil 	/*
1066454a4e72SHans Verkuil 	 * Drivers MUST fill in device_caps, so check for this and
1067454a4e72SHans Verkuil 	 * warn if it was forgotten.
1068454a4e72SHans Verkuil 	 */
10696d7570c4SLaura Abbott 	WARN(!(cap->capabilities & V4L2_CAP_DEVICE_CAPS) ||
10706d7570c4SLaura Abbott 		!cap->device_caps, "Bad caps for driver %s, %x %x",
10716d7570c4SLaura Abbott 		cap->driver, cap->capabilities, cap->device_caps);
1072796a2bd2SHans Verkuil 	cap->device_caps |= V4L2_CAP_EXT_PIX_FORMAT;
1073d52e2381SLaurent Pinchart 
1074d52e2381SLaurent Pinchart 	return ret;
10755bc3cb74SMauro Carvalho Chehab }
10765bc3cb74SMauro Carvalho Chehab 
10775bc3cb74SMauro Carvalho Chehab static int v4l_s_input(const struct v4l2_ioctl_ops *ops,
10785bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
10795bc3cb74SMauro Carvalho Chehab {
108077fa4e07SShuah Khan 	struct video_device *vfd = video_devdata(file);
108177fa4e07SShuah Khan 	int ret;
108277fa4e07SShuah Khan 
108377fa4e07SShuah Khan 	ret = v4l_enable_media_source(vfd);
108477fa4e07SShuah Khan 	if (ret)
108577fa4e07SShuah Khan 		return ret;
10865bc3cb74SMauro Carvalho Chehab 	return ops->vidioc_s_input(file, fh, *(unsigned int *)arg);
10875bc3cb74SMauro Carvalho Chehab }
10885bc3cb74SMauro Carvalho Chehab 
10895bc3cb74SMauro Carvalho Chehab static int v4l_s_output(const struct v4l2_ioctl_ops *ops,
10905bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
10915bc3cb74SMauro Carvalho Chehab {
10925bc3cb74SMauro Carvalho Chehab 	return ops->vidioc_s_output(file, fh, *(unsigned int *)arg);
10935bc3cb74SMauro Carvalho Chehab }
10945bc3cb74SMauro Carvalho Chehab 
10955bc3cb74SMauro Carvalho Chehab static int v4l_g_priority(const struct v4l2_ioctl_ops *ops,
10965bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
10975bc3cb74SMauro Carvalho Chehab {
10985bc3cb74SMauro Carvalho Chehab 	struct video_device *vfd;
10995bc3cb74SMauro Carvalho Chehab 	u32 *p = arg;
11005bc3cb74SMauro Carvalho Chehab 
11015bc3cb74SMauro Carvalho Chehab 	vfd = video_devdata(file);
110259b702eaSLaurent Pinchart 	*p = v4l2_prio_max(vfd->prio);
11035bc3cb74SMauro Carvalho Chehab 	return 0;
11045bc3cb74SMauro Carvalho Chehab }
11055bc3cb74SMauro Carvalho Chehab 
11065bc3cb74SMauro Carvalho Chehab static int v4l_s_priority(const struct v4l2_ioctl_ops *ops,
11075bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
11085bc3cb74SMauro Carvalho Chehab {
11095bc3cb74SMauro Carvalho Chehab 	struct video_device *vfd;
11105bc3cb74SMauro Carvalho Chehab 	struct v4l2_fh *vfh;
11115bc3cb74SMauro Carvalho Chehab 	u32 *p = arg;
11125bc3cb74SMauro Carvalho Chehab 
11135bc3cb74SMauro Carvalho Chehab 	vfd = video_devdata(file);
11142438e78aSHans Verkuil 	if (!test_bit(V4L2_FL_USES_V4L2_FH, &vfd->flags))
11152438e78aSHans Verkuil 		return -ENOTTY;
11165bc3cb74SMauro Carvalho Chehab 	vfh = file->private_data;
111759b702eaSLaurent Pinchart 	return v4l2_prio_change(vfd->prio, &vfh->prio, *p);
11185bc3cb74SMauro Carvalho Chehab }
11195bc3cb74SMauro Carvalho Chehab 
11205bc3cb74SMauro Carvalho Chehab static int v4l_enuminput(const struct v4l2_ioctl_ops *ops,
11215bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
11225bc3cb74SMauro Carvalho Chehab {
112373f35418SHans Verkuil 	struct video_device *vfd = video_devdata(file);
11245bc3cb74SMauro Carvalho Chehab 	struct v4l2_input *p = arg;
11255bc3cb74SMauro Carvalho Chehab 
11265bc3cb74SMauro Carvalho Chehab 	/*
112702fa6282SHans Verkuil 	 * We set the flags for CAP_DV_TIMINGS &
11285bc3cb74SMauro Carvalho Chehab 	 * CAP_STD here based on ioctl handler provided by the
11295bc3cb74SMauro Carvalho Chehab 	 * driver. If the driver doesn't support these
11305bc3cb74SMauro Carvalho Chehab 	 * for a specific input, it must override these flags.
11315bc3cb74SMauro Carvalho Chehab 	 */
113273f35418SHans Verkuil 	if (is_valid_ioctl(vfd, VIDIOC_S_STD))
11335bc3cb74SMauro Carvalho Chehab 		p->capabilities |= V4L2_IN_CAP_STD;
11345bc3cb74SMauro Carvalho Chehab 
11355bc3cb74SMauro Carvalho Chehab 	return ops->vidioc_enum_input(file, fh, p);
11365bc3cb74SMauro Carvalho Chehab }
11375bc3cb74SMauro Carvalho Chehab 
11385bc3cb74SMauro Carvalho Chehab static int v4l_enumoutput(const struct v4l2_ioctl_ops *ops,
11395bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
11405bc3cb74SMauro Carvalho Chehab {
114173f35418SHans Verkuil 	struct video_device *vfd = video_devdata(file);
11425bc3cb74SMauro Carvalho Chehab 	struct v4l2_output *p = arg;
11435bc3cb74SMauro Carvalho Chehab 
11445bc3cb74SMauro Carvalho Chehab 	/*
114502fa6282SHans Verkuil 	 * We set the flags for CAP_DV_TIMINGS &
11465bc3cb74SMauro Carvalho Chehab 	 * CAP_STD here based on ioctl handler provided by the
11475bc3cb74SMauro Carvalho Chehab 	 * driver. If the driver doesn't support these
11485bc3cb74SMauro Carvalho Chehab 	 * for a specific output, it must override these flags.
11495bc3cb74SMauro Carvalho Chehab 	 */
115073f35418SHans Verkuil 	if (is_valid_ioctl(vfd, VIDIOC_S_STD))
11515bc3cb74SMauro Carvalho Chehab 		p->capabilities |= V4L2_OUT_CAP_STD;
11525bc3cb74SMauro Carvalho Chehab 
11535bc3cb74SMauro Carvalho Chehab 	return ops->vidioc_enum_output(file, fh, p);
11545bc3cb74SMauro Carvalho Chehab }
11555bc3cb74SMauro Carvalho Chehab 
1156ba300204SHans Verkuil static void v4l_fill_fmtdesc(struct v4l2_fmtdesc *fmt)
1157ba300204SHans Verkuil {
1158ba300204SHans Verkuil 	const unsigned sz = sizeof(fmt->description);
1159ba300204SHans Verkuil 	const char *descr = NULL;
1160ba300204SHans Verkuil 	u32 flags = 0;
1161ba300204SHans Verkuil 
1162ba300204SHans Verkuil 	/*
1163ba300204SHans Verkuil 	 * We depart from the normal coding style here since the descriptions
1164ba300204SHans Verkuil 	 * should be aligned so it is easy to see which descriptions will be
1165ba300204SHans Verkuil 	 * longer than 31 characters (the max length for a description).
1166ba300204SHans Verkuil 	 * And frankly, this is easier to read anyway.
1167ba300204SHans Verkuil 	 *
1168ba300204SHans Verkuil 	 * Note that gcc will use O(log N) comparisons to find the right case.
1169ba300204SHans Verkuil 	 */
1170ba300204SHans Verkuil 	switch (fmt->pixelformat) {
1171ba300204SHans Verkuil 	/* Max description length mask:	descr = "0123456789012345678901234567890" */
1172ba300204SHans Verkuil 	case V4L2_PIX_FMT_RGB332:	descr = "8-bit RGB 3-3-2"; break;
1173ba300204SHans Verkuil 	case V4L2_PIX_FMT_RGB444:	descr = "16-bit A/XRGB 4-4-4-4"; break;
1174ba300204SHans Verkuil 	case V4L2_PIX_FMT_ARGB444:	descr = "16-bit ARGB 4-4-4-4"; break;
1175ba300204SHans Verkuil 	case V4L2_PIX_FMT_XRGB444:	descr = "16-bit XRGB 4-4-4-4"; break;
1176ba300204SHans Verkuil 	case V4L2_PIX_FMT_RGB555:	descr = "16-bit A/XRGB 1-5-5-5"; break;
1177ba300204SHans Verkuil 	case V4L2_PIX_FMT_ARGB555:	descr = "16-bit ARGB 1-5-5-5"; break;
1178ba300204SHans Verkuil 	case V4L2_PIX_FMT_XRGB555:	descr = "16-bit XRGB 1-5-5-5"; break;
1179ba300204SHans Verkuil 	case V4L2_PIX_FMT_RGB565:	descr = "16-bit RGB 5-6-5"; break;
1180ba300204SHans Verkuil 	case V4L2_PIX_FMT_RGB555X:	descr = "16-bit A/XRGB 1-5-5-5 BE"; break;
1181ba300204SHans Verkuil 	case V4L2_PIX_FMT_ARGB555X:	descr = "16-bit ARGB 1-5-5-5 BE"; break;
1182ba300204SHans Verkuil 	case V4L2_PIX_FMT_XRGB555X:	descr = "16-bit XRGB 1-5-5-5 BE"; break;
1183ba300204SHans Verkuil 	case V4L2_PIX_FMT_RGB565X:	descr = "16-bit RGB 5-6-5 BE"; break;
1184ba300204SHans Verkuil 	case V4L2_PIX_FMT_BGR666:	descr = "18-bit BGRX 6-6-6-14"; break;
1185ba300204SHans Verkuil 	case V4L2_PIX_FMT_BGR24:	descr = "24-bit BGR 8-8-8"; break;
1186ba300204SHans Verkuil 	case V4L2_PIX_FMT_RGB24:	descr = "24-bit RGB 8-8-8"; break;
1187ba300204SHans Verkuil 	case V4L2_PIX_FMT_BGR32:	descr = "32-bit BGRA/X 8-8-8-8"; break;
1188ba300204SHans Verkuil 	case V4L2_PIX_FMT_ABGR32:	descr = "32-bit BGRA 8-8-8-8"; break;
1189ba300204SHans Verkuil 	case V4L2_PIX_FMT_XBGR32:	descr = "32-bit BGRX 8-8-8-8"; break;
1190ba300204SHans Verkuil 	case V4L2_PIX_FMT_RGB32:	descr = "32-bit A/XRGB 8-8-8-8"; break;
1191ba300204SHans Verkuil 	case V4L2_PIX_FMT_ARGB32:	descr = "32-bit ARGB 8-8-8-8"; break;
1192ba300204SHans Verkuil 	case V4L2_PIX_FMT_XRGB32:	descr = "32-bit XRGB 8-8-8-8"; break;
1193ba300204SHans Verkuil 	case V4L2_PIX_FMT_GREY:		descr = "8-bit Greyscale"; break;
1194ba300204SHans Verkuil 	case V4L2_PIX_FMT_Y4:		descr = "4-bit Greyscale"; break;
1195ba300204SHans Verkuil 	case V4L2_PIX_FMT_Y6:		descr = "6-bit Greyscale"; break;
1196ba300204SHans Verkuil 	case V4L2_PIX_FMT_Y10:		descr = "10-bit Greyscale"; break;
1197ba300204SHans Verkuil 	case V4L2_PIX_FMT_Y12:		descr = "12-bit Greyscale"; break;
1198ba300204SHans Verkuil 	case V4L2_PIX_FMT_Y16:		descr = "16-bit Greyscale"; break;
11992e5e435fSRicardo Ribalda 	case V4L2_PIX_FMT_Y16_BE:	descr = "16-bit Greyscale BE"; break;
1200ba300204SHans Verkuil 	case V4L2_PIX_FMT_Y10BPACK:	descr = "10-bit Greyscale (Packed)"; break;
12016e15bec4STodor Tomov 	case V4L2_PIX_FMT_Y10P:		descr = "10-bit Greyscale (MIPI Packed)"; break;
12025b382290SLaurent Pinchart 	case V4L2_PIX_FMT_Y8I:		descr = "Interleaved 8-bit Greyscale"; break;
12035b382290SLaurent Pinchart 	case V4L2_PIX_FMT_Y12I:		descr = "Interleaved 12-bit Greyscale"; break;
12045b382290SLaurent Pinchart 	case V4L2_PIX_FMT_Z16:		descr = "16-bit Depth"; break;
12055df082e2SEvgeni Raikhel 	case V4L2_PIX_FMT_INZI:		descr = "Planar 10:16 Greyscale Depth"; break;
120692799ef7SSergey Dorodnicov 	case V4L2_PIX_FMT_CNF4:		descr = "4-bit Depth Confidence (Packed)"; break;
1207ba300204SHans Verkuil 	case V4L2_PIX_FMT_PAL8:		descr = "8-bit Palette"; break;
1208ba300204SHans Verkuil 	case V4L2_PIX_FMT_UV8:		descr = "8-bit Chrominance UV 4-4"; break;
1209ba300204SHans Verkuil 	case V4L2_PIX_FMT_YVU410:	descr = "Planar YVU 4:1:0"; break;
1210ba300204SHans Verkuil 	case V4L2_PIX_FMT_YVU420:	descr = "Planar YVU 4:2:0"; break;
1211ba300204SHans Verkuil 	case V4L2_PIX_FMT_YUYV:		descr = "YUYV 4:2:2"; break;
1212ba300204SHans Verkuil 	case V4L2_PIX_FMT_YYUV:		descr = "YYUV 4:2:2"; break;
1213ba300204SHans Verkuil 	case V4L2_PIX_FMT_YVYU:		descr = "YVYU 4:2:2"; break;
1214ba300204SHans Verkuil 	case V4L2_PIX_FMT_UYVY:		descr = "UYVY 4:2:2"; break;
1215ba300204SHans Verkuil 	case V4L2_PIX_FMT_VYUY:		descr = "VYUY 4:2:2"; break;
1216fcbafafbSPhilipp Zabel 	case V4L2_PIX_FMT_YUV422P:	descr = "Planar YUV 4:2:2"; break;
1217ba300204SHans Verkuil 	case V4L2_PIX_FMT_YUV411P:	descr = "Planar YUV 4:1:1"; break;
1218ba300204SHans Verkuil 	case V4L2_PIX_FMT_Y41P:		descr = "YUV 4:1:1 (Packed)"; break;
1219ba300204SHans Verkuil 	case V4L2_PIX_FMT_YUV444:	descr = "16-bit A/XYUV 4-4-4-4"; break;
1220ba300204SHans Verkuil 	case V4L2_PIX_FMT_YUV555:	descr = "16-bit A/XYUV 1-5-5-5"; break;
1221ba300204SHans Verkuil 	case V4L2_PIX_FMT_YUV565:	descr = "16-bit YUV 5-6-5"; break;
1222ba300204SHans Verkuil 	case V4L2_PIX_FMT_YUV32:	descr = "32-bit A/XYUV 8-8-8-8"; break;
1223a7fe4ca7SVivek Kasireddy 	case V4L2_PIX_FMT_AYUV32:	descr = "32-bit AYUV 8-8-8-8"; break;
1224a7fe4ca7SVivek Kasireddy 	case V4L2_PIX_FMT_XYUV32:	descr = "32-bit XYUV 8-8-8-8"; break;
1225a7fe4ca7SVivek Kasireddy 	case V4L2_PIX_FMT_VUYA32:	descr = "32-bit VUYA 8-8-8-8"; break;
1226a7fe4ca7SVivek Kasireddy 	case V4L2_PIX_FMT_VUYX32:	descr = "32-bit VUYX 8-8-8-8"; break;
1227ba300204SHans Verkuil 	case V4L2_PIX_FMT_YUV410:	descr = "Planar YUV 4:1:0"; break;
1228ba300204SHans Verkuil 	case V4L2_PIX_FMT_YUV420:	descr = "Planar YUV 4:2:0"; break;
1229ba300204SHans Verkuil 	case V4L2_PIX_FMT_HI240:	descr = "8-bit Dithered RGB (BTTV)"; break;
1230ba300204SHans Verkuil 	case V4L2_PIX_FMT_HM12:		descr = "YUV 4:2:0 (16x16 Macroblocks)"; break;
1231ba300204SHans Verkuil 	case V4L2_PIX_FMT_M420:		descr = "YUV 4:2:0 (M420)"; break;
1232ba300204SHans Verkuil 	case V4L2_PIX_FMT_NV12:		descr = "Y/CbCr 4:2:0"; break;
1233ba300204SHans Verkuil 	case V4L2_PIX_FMT_NV21:		descr = "Y/CrCb 4:2:0"; break;
1234ba300204SHans Verkuil 	case V4L2_PIX_FMT_NV16:		descr = "Y/CbCr 4:2:2"; break;
1235ba300204SHans Verkuil 	case V4L2_PIX_FMT_NV61:		descr = "Y/CrCb 4:2:2"; break;
1236ba300204SHans Verkuil 	case V4L2_PIX_FMT_NV24:		descr = "Y/CbCr 4:4:4"; break;
1237ba300204SHans Verkuil 	case V4L2_PIX_FMT_NV42:		descr = "Y/CrCb 4:4:4"; break;
1238ba300204SHans Verkuil 	case V4L2_PIX_FMT_NV12M:	descr = "Y/CbCr 4:2:0 (N-C)"; break;
1239ba300204SHans Verkuil 	case V4L2_PIX_FMT_NV21M:	descr = "Y/CrCb 4:2:0 (N-C)"; break;
1240ba300204SHans Verkuil 	case V4L2_PIX_FMT_NV16M:	descr = "Y/CbCr 4:2:2 (N-C)"; break;
1241ba300204SHans Verkuil 	case V4L2_PIX_FMT_NV61M:	descr = "Y/CrCb 4:2:2 (N-C)"; break;
1242ba300204SHans Verkuil 	case V4L2_PIX_FMT_NV12MT:	descr = "Y/CbCr 4:2:0 (64x32 MB, N-C)"; break;
1243ba300204SHans Verkuil 	case V4L2_PIX_FMT_NV12MT_16X16:	descr = "Y/CbCr 4:2:0 (16x16 MB, N-C)"; break;
1244ba300204SHans Verkuil 	case V4L2_PIX_FMT_YUV420M:	descr = "Planar YUV 4:2:0 (N-C)"; break;
1245ba300204SHans Verkuil 	case V4L2_PIX_FMT_YVU420M:	descr = "Planar YVU 4:2:0 (N-C)"; break;
1246d65fae92SLaurent Pinchart 	case V4L2_PIX_FMT_YUV422M:	descr = "Planar YUV 4:2:2 (N-C)"; break;
1247d65fae92SLaurent Pinchart 	case V4L2_PIX_FMT_YVU422M:	descr = "Planar YVU 4:2:2 (N-C)"; break;
1248d65fae92SLaurent Pinchart 	case V4L2_PIX_FMT_YUV444M:	descr = "Planar YUV 4:4:4 (N-C)"; break;
1249d65fae92SLaurent Pinchart 	case V4L2_PIX_FMT_YVU444M:	descr = "Planar YVU 4:4:4 (N-C)"; break;
1250ba300204SHans Verkuil 	case V4L2_PIX_FMT_SBGGR8:	descr = "8-bit Bayer BGBG/GRGR"; break;
1251ba300204SHans Verkuil 	case V4L2_PIX_FMT_SGBRG8:	descr = "8-bit Bayer GBGB/RGRG"; break;
1252ba300204SHans Verkuil 	case V4L2_PIX_FMT_SGRBG8:	descr = "8-bit Bayer GRGR/BGBG"; break;
1253ba300204SHans Verkuil 	case V4L2_PIX_FMT_SRGGB8:	descr = "8-bit Bayer RGRG/GBGB"; break;
1254ba300204SHans Verkuil 	case V4L2_PIX_FMT_SBGGR10:	descr = "10-bit Bayer BGBG/GRGR"; break;
1255ba300204SHans Verkuil 	case V4L2_PIX_FMT_SGBRG10:	descr = "10-bit Bayer GBGB/RGRG"; break;
1256ba300204SHans Verkuil 	case V4L2_PIX_FMT_SGRBG10:	descr = "10-bit Bayer GRGR/BGBG"; break;
1257ba300204SHans Verkuil 	case V4L2_PIX_FMT_SRGGB10:	descr = "10-bit Bayer RGRG/GBGB"; break;
1258ba300204SHans Verkuil 	case V4L2_PIX_FMT_SBGGR10P:	descr = "10-bit Bayer BGBG/GRGR Packed"; break;
1259ba300204SHans Verkuil 	case V4L2_PIX_FMT_SGBRG10P:	descr = "10-bit Bayer GBGB/RGRG Packed"; break;
1260ba300204SHans Verkuil 	case V4L2_PIX_FMT_SGRBG10P:	descr = "10-bit Bayer GRGR/BGBG Packed"; break;
1261ba300204SHans Verkuil 	case V4L2_PIX_FMT_SRGGB10P:	descr = "10-bit Bayer RGRG/GBGB Packed"; break;
1262e8391b76SYong Zhi 	case V4L2_PIX_FMT_IPU3_SBGGR10: descr = "10-bit bayer BGGR IPU3 Packed"; break;
1263e8391b76SYong Zhi 	case V4L2_PIX_FMT_IPU3_SGBRG10: descr = "10-bit bayer GBRG IPU3 Packed"; break;
1264e8391b76SYong Zhi 	case V4L2_PIX_FMT_IPU3_SGRBG10: descr = "10-bit bayer GRBG IPU3 Packed"; break;
1265e8391b76SYong Zhi 	case V4L2_PIX_FMT_IPU3_SRGGB10: descr = "10-bit bayer RGGB IPU3 Packed"; break;
1266ba300204SHans Verkuil 	case V4L2_PIX_FMT_SBGGR10ALAW8:	descr = "8-bit Bayer BGBG/GRGR (A-law)"; break;
1267ba300204SHans Verkuil 	case V4L2_PIX_FMT_SGBRG10ALAW8:	descr = "8-bit Bayer GBGB/RGRG (A-law)"; break;
1268ba300204SHans Verkuil 	case V4L2_PIX_FMT_SGRBG10ALAW8:	descr = "8-bit Bayer GRGR/BGBG (A-law)"; break;
1269ba300204SHans Verkuil 	case V4L2_PIX_FMT_SRGGB10ALAW8:	descr = "8-bit Bayer RGRG/GBGB (A-law)"; break;
1270ba300204SHans Verkuil 	case V4L2_PIX_FMT_SBGGR10DPCM8:	descr = "8-bit Bayer BGBG/GRGR (DPCM)"; break;
1271ba300204SHans Verkuil 	case V4L2_PIX_FMT_SGBRG10DPCM8:	descr = "8-bit Bayer GBGB/RGRG (DPCM)"; break;
1272ba300204SHans Verkuil 	case V4L2_PIX_FMT_SGRBG10DPCM8:	descr = "8-bit Bayer GRGR/BGBG (DPCM)"; break;
1273ba300204SHans Verkuil 	case V4L2_PIX_FMT_SRGGB10DPCM8:	descr = "8-bit Bayer RGRG/GBGB (DPCM)"; break;
1274d1b3437eSSakari Ailus 	case V4L2_PIX_FMT_SBGGR12:	descr = "12-bit Bayer BGBG/GRGR"; break;
1275d1b3437eSSakari Ailus 	case V4L2_PIX_FMT_SGBRG12:	descr = "12-bit Bayer GBGB/RGRG"; break;
1276d1b3437eSSakari Ailus 	case V4L2_PIX_FMT_SGRBG12:	descr = "12-bit Bayer GRGR/BGBG"; break;
1277d1b3437eSSakari Ailus 	case V4L2_PIX_FMT_SRGGB12:	descr = "12-bit Bayer RGRG/GBGB"; break;
1278d1b3437eSSakari Ailus 	case V4L2_PIX_FMT_SBGGR12P:	descr = "12-bit Bayer BGBG/GRGR Packed"; break;
1279d1b3437eSSakari Ailus 	case V4L2_PIX_FMT_SGBRG12P:	descr = "12-bit Bayer GBGB/RGRG Packed"; break;
1280d1b3437eSSakari Ailus 	case V4L2_PIX_FMT_SGRBG12P:	descr = "12-bit Bayer GRGR/BGBG Packed"; break;
1281d1b3437eSSakari Ailus 	case V4L2_PIX_FMT_SRGGB12P:	descr = "12-bit Bayer RGRG/GBGB Packed"; break;
128283b15832SSakari Ailus 	case V4L2_PIX_FMT_SBGGR14P:	descr = "14-bit Bayer BGBG/GRGR Packed"; break;
128383b15832SSakari Ailus 	case V4L2_PIX_FMT_SGBRG14P:	descr = "14-bit Bayer GBGB/RGRG Packed"; break;
128483b15832SSakari Ailus 	case V4L2_PIX_FMT_SGRBG14P:	descr = "14-bit Bayer GRGR/BGBG Packed"; break;
128583b15832SSakari Ailus 	case V4L2_PIX_FMT_SRGGB14P:	descr = "14-bit Bayer RGRG/GBGB Packed"; break;
1286b9a4b13cSSakari Ailus 	case V4L2_PIX_FMT_SBGGR16:	descr = "16-bit Bayer BGBG/GRGR"; break;
1287b9a4b13cSSakari Ailus 	case V4L2_PIX_FMT_SGBRG16:	descr = "16-bit Bayer GBGB/RGRG"; break;
1288b9a4b13cSSakari Ailus 	case V4L2_PIX_FMT_SGRBG16:	descr = "16-bit Bayer GRGR/BGBG"; break;
1289b9a4b13cSSakari Ailus 	case V4L2_PIX_FMT_SRGGB16:	descr = "16-bit Bayer RGRG/GBGB"; break;
129099b74277SMauro Carvalho Chehab 	case V4L2_PIX_FMT_SN9C20X_I420:	descr = "GSPCA SN9C20X I420"; break;
1291ba300204SHans Verkuil 	case V4L2_PIX_FMT_SPCA501:	descr = "GSPCA SPCA501"; break;
1292ba300204SHans Verkuil 	case V4L2_PIX_FMT_SPCA505:	descr = "GSPCA SPCA505"; break;
1293ba300204SHans Verkuil 	case V4L2_PIX_FMT_SPCA508:	descr = "GSPCA SPCA508"; break;
1294ba300204SHans Verkuil 	case V4L2_PIX_FMT_STV0680:	descr = "GSPCA STV0680"; break;
1295ba300204SHans Verkuil 	case V4L2_PIX_FMT_TM6000:	descr = "A/V + VBI Mux Packet"; break;
1296ba300204SHans Verkuil 	case V4L2_PIX_FMT_CIT_YYVYUY:	descr = "GSPCA CIT YYVYUY"; break;
1297ba300204SHans Verkuil 	case V4L2_PIX_FMT_KONICA420:	descr = "GSPCA KONICA420"; break;
129866b2ab27SRicardo Ribalda Delgado 	case V4L2_PIX_FMT_HSV24:	descr = "24-bit HSV 8-8-8"; break;
129966b2ab27SRicardo Ribalda Delgado 	case V4L2_PIX_FMT_HSV32:	descr = "32-bit XHSV 8-8-8-8"; break;
130048fc10aaSAntti Palosaari 	case V4L2_SDR_FMT_CU8:		descr = "Complex U8"; break;
130148fc10aaSAntti Palosaari 	case V4L2_SDR_FMT_CU16LE:	descr = "Complex U16LE"; break;
1302ba300204SHans Verkuil 	case V4L2_SDR_FMT_CS8:		descr = "Complex S8"; break;
1303ba300204SHans Verkuil 	case V4L2_SDR_FMT_CS14LE:	descr = "Complex S14LE"; break;
1304ba300204SHans Verkuil 	case V4L2_SDR_FMT_RU12LE:	descr = "Real U12LE"; break;
1305c28f2118SRamesh Shanmugasundaram 	case V4L2_SDR_FMT_PCU16BE:	descr = "Planar Complex U16BE"; break;
1306c28f2118SRamesh Shanmugasundaram 	case V4L2_SDR_FMT_PCU18BE:	descr = "Planar Complex U18BE"; break;
1307c28f2118SRamesh Shanmugasundaram 	case V4L2_SDR_FMT_PCU20BE:	descr = "Planar Complex U20BE"; break;
1308b2fe22d0SNick Dyer 	case V4L2_TCH_FMT_DELTA_TD16:	descr = "16-bit signed deltas"; break;
1309b2fe22d0SNick Dyer 	case V4L2_TCH_FMT_DELTA_TD08:	descr = "8-bit signed deltas"; break;
1310b2fe22d0SNick Dyer 	case V4L2_TCH_FMT_TU16:		descr = "16-bit unsigned touch data"; break;
1311b2fe22d0SNick Dyer 	case V4L2_TCH_FMT_TU08:		descr = "8-bit unsigned touch data"; break;
131214d66538SLaurent Pinchart 	case V4L2_META_FMT_VSP1_HGO:	descr = "R-Car VSP1 1-D Histogram"; break;
13135deb1c04SNiklas Söderlund 	case V4L2_META_FMT_VSP1_HGT:	descr = "R-Car VSP1 2-D Histogram"; break;
1314563a01e1SGuennadi Liakhovetski 	case V4L2_META_FMT_UVC:		descr = "UVC payload header metadata"; break;
1315ba300204SHans Verkuil 
1316ba300204SHans Verkuil 	default:
1317ba300204SHans Verkuil 		/* Compressed formats */
1318ba300204SHans Verkuil 		flags = V4L2_FMT_FLAG_COMPRESSED;
1319ba300204SHans Verkuil 		switch (fmt->pixelformat) {
1320ba300204SHans Verkuil 		/* Max description length mask:	descr = "0123456789012345678901234567890" */
1321ba300204SHans Verkuil 		case V4L2_PIX_FMT_MJPEG:	descr = "Motion-JPEG"; break;
1322ba300204SHans Verkuil 		case V4L2_PIX_FMT_JPEG:		descr = "JFIF JPEG"; break;
1323ba300204SHans Verkuil 		case V4L2_PIX_FMT_DV:		descr = "1394"; break;
1324ba300204SHans Verkuil 		case V4L2_PIX_FMT_MPEG:		descr = "MPEG-1/2/4"; break;
1325ba300204SHans Verkuil 		case V4L2_PIX_FMT_H264:		descr = "H.264"; break;
1326ba300204SHans Verkuil 		case V4L2_PIX_FMT_H264_NO_SC:	descr = "H.264 (No Start Codes)"; break;
1327ba300204SHans Verkuil 		case V4L2_PIX_FMT_H264_MVC:	descr = "H.264 MVC"; break;
1328ba300204SHans Verkuil 		case V4L2_PIX_FMT_H263:		descr = "H.263"; break;
1329ba300204SHans Verkuil 		case V4L2_PIX_FMT_MPEG1:	descr = "MPEG-1 ES"; break;
1330ba300204SHans Verkuil 		case V4L2_PIX_FMT_MPEG2:	descr = "MPEG-2 ES"; break;
1331c27bb30eSPaul Kocialkowski 		case V4L2_PIX_FMT_MPEG2_SLICE:	descr = "MPEG-2 Parsed Slice Data"; break;
1332ba300204SHans Verkuil 		case V4L2_PIX_FMT_MPEG4:	descr = "MPEG-4 part 2 ES"; break;
1333ba300204SHans Verkuil 		case V4L2_PIX_FMT_XVID:		descr = "Xvid"; break;
1334ba300204SHans Verkuil 		case V4L2_PIX_FMT_VC1_ANNEX_G:	descr = "VC-1 (SMPTE 412M Annex G)"; break;
1335ba300204SHans Verkuil 		case V4L2_PIX_FMT_VC1_ANNEX_L:	descr = "VC-1 (SMPTE 412M Annex L)"; break;
1336ba300204SHans Verkuil 		case V4L2_PIX_FMT_VP8:		descr = "VP8"; break;
1337fa14a564SWu-Cheng Li 		case V4L2_PIX_FMT_VP9:		descr = "VP9"; break;
13381c791727SSmitha T Murthy 		case V4L2_PIX_FMT_HEVC:		descr = "HEVC"; break; /* aka H.265 */
133962c3fce0SHans Verkuil 		case V4L2_PIX_FMT_FWHT:		descr = "FWHT"; break; /* used in vicodec */
1340ba300204SHans Verkuil 		case V4L2_PIX_FMT_CPIA1:	descr = "GSPCA CPiA YUV"; break;
1341ba300204SHans Verkuil 		case V4L2_PIX_FMT_WNVA:		descr = "WNVA"; break;
1342ba300204SHans Verkuil 		case V4L2_PIX_FMT_SN9C10X:	descr = "GSPCA SN9C10X"; break;
1343ba300204SHans Verkuil 		case V4L2_PIX_FMT_PWC1:		descr = "Raw Philips Webcam Type (Old)"; break;
1344ba300204SHans Verkuil 		case V4L2_PIX_FMT_PWC2:		descr = "Raw Philips Webcam Type (New)"; break;
1345ba300204SHans Verkuil 		case V4L2_PIX_FMT_ET61X251:	descr = "GSPCA ET61X251"; break;
1346ba300204SHans Verkuil 		case V4L2_PIX_FMT_SPCA561:	descr = "GSPCA SPCA561"; break;
1347ba300204SHans Verkuil 		case V4L2_PIX_FMT_PAC207:	descr = "GSPCA PAC207"; break;
1348ba300204SHans Verkuil 		case V4L2_PIX_FMT_MR97310A:	descr = "GSPCA MR97310A"; break;
1349ba300204SHans Verkuil 		case V4L2_PIX_FMT_JL2005BCD:	descr = "GSPCA JL2005BCD"; break;
1350ba300204SHans Verkuil 		case V4L2_PIX_FMT_SN9C2028:	descr = "GSPCA SN9C2028"; break;
1351ba300204SHans Verkuil 		case V4L2_PIX_FMT_SQ905C:	descr = "GSPCA SQ905C"; break;
1352ba300204SHans Verkuil 		case V4L2_PIX_FMT_PJPG:		descr = "GSPCA PJPG"; break;
1353ba300204SHans Verkuil 		case V4L2_PIX_FMT_OV511:	descr = "GSPCA OV511"; break;
1354ba300204SHans Verkuil 		case V4L2_PIX_FMT_OV518:	descr = "GSPCA OV518"; break;
1355ba300204SHans Verkuil 		case V4L2_PIX_FMT_JPGL:		descr = "JPEG Lite"; break;
1356ba300204SHans Verkuil 		case V4L2_PIX_FMT_SE401:	descr = "GSPCA SE401"; break;
1357ba300204SHans Verkuil 		case V4L2_PIX_FMT_S5C_UYVY_JPG:	descr = "S5C73MX interleaved UYVY/JPEG"; break;
1358d4de6634STiffany Lin 		case V4L2_PIX_FMT_MT21C:	descr = "Mediatek Compressed Format"; break;
135936cf35b7SPaul Kocialkowski 		case V4L2_PIX_FMT_SUNXI_TILED_NV12: descr = "Sunxi Tiled NV12 Format"; break;
1360ba300204SHans Verkuil 		default:
1361ba300204SHans Verkuil 			if (fmt->description[0])
1362ba300204SHans Verkuil 				return;
1363c2286cc0SSakari Ailus 			WARN(1, "Unknown pixelformat 0x%08x\n", fmt->pixelformat);
1364ba300204SHans Verkuil 			flags = 0;
1365ba300204SHans Verkuil 			snprintf(fmt->description, sz, "%c%c%c%c%s",
1366ba300204SHans Verkuil 					(char)(fmt->pixelformat & 0x7f),
1367ba300204SHans Verkuil 					(char)((fmt->pixelformat >> 8) & 0x7f),
1368ba300204SHans Verkuil 					(char)((fmt->pixelformat >> 16) & 0x7f),
1369ba300204SHans Verkuil 					(char)((fmt->pixelformat >> 24) & 0x7f),
1370ba300204SHans Verkuil 					(fmt->pixelformat & (1 << 31)) ? "-BE" : "");
1371ba300204SHans Verkuil 			break;
1372ba300204SHans Verkuil 		}
1373ba300204SHans Verkuil 	}
1374ba300204SHans Verkuil 
1375ba300204SHans Verkuil 	if (descr)
1376c0decac1SMauro Carvalho Chehab 		WARN_ON(strscpy(fmt->description, descr, sz) >= sz);
1377ba300204SHans Verkuil 	fmt->flags = flags;
1378ba300204SHans Verkuil }
1379ba300204SHans Verkuil 
13805bc3cb74SMauro Carvalho Chehab static int v4l_enum_fmt(const struct v4l2_ioctl_ops *ops,
13815bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
13825bc3cb74SMauro Carvalho Chehab {
13835bc3cb74SMauro Carvalho Chehab 	struct v4l2_fmtdesc *p = arg;
1384b2469c81SHans Verkuil 	int ret = check_fmt(file, p->type);
1385b2469c81SHans Verkuil 
1386b2469c81SHans Verkuil 	if (ret)
1387b2469c81SHans Verkuil 		return ret;
1388b2469c81SHans Verkuil 	ret = -EINVAL;
13895bc3cb74SMauro Carvalho Chehab 
13905bc3cb74SMauro Carvalho Chehab 	switch (p->type) {
13915bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_CAPTURE:
1392b2469c81SHans Verkuil 		if (unlikely(!ops->vidioc_enum_fmt_vid_cap))
13935bc3cb74SMauro Carvalho Chehab 			break;
1394ba300204SHans Verkuil 		ret = ops->vidioc_enum_fmt_vid_cap(file, fh, arg);
1395ba300204SHans Verkuil 		break;
13965bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
1397b2469c81SHans Verkuil 		if (unlikely(!ops->vidioc_enum_fmt_vid_cap_mplane))
13985bc3cb74SMauro Carvalho Chehab 			break;
1399ba300204SHans Verkuil 		ret = ops->vidioc_enum_fmt_vid_cap_mplane(file, fh, arg);
1400ba300204SHans Verkuil 		break;
14015bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_OVERLAY:
1402b2469c81SHans Verkuil 		if (unlikely(!ops->vidioc_enum_fmt_vid_overlay))
14035bc3cb74SMauro Carvalho Chehab 			break;
1404ba300204SHans Verkuil 		ret = ops->vidioc_enum_fmt_vid_overlay(file, fh, arg);
1405ba300204SHans Verkuil 		break;
14065bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_OUTPUT:
1407b2469c81SHans Verkuil 		if (unlikely(!ops->vidioc_enum_fmt_vid_out))
14085bc3cb74SMauro Carvalho Chehab 			break;
1409ba300204SHans Verkuil 		ret = ops->vidioc_enum_fmt_vid_out(file, fh, arg);
1410ba300204SHans Verkuil 		break;
14115bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
1412b2469c81SHans Verkuil 		if (unlikely(!ops->vidioc_enum_fmt_vid_out_mplane))
14135bc3cb74SMauro Carvalho Chehab 			break;
1414ba300204SHans Verkuil 		ret = ops->vidioc_enum_fmt_vid_out_mplane(file, fh, arg);
1415ba300204SHans Verkuil 		break;
1416582c52cbSAntti Palosaari 	case V4L2_BUF_TYPE_SDR_CAPTURE:
1417b2469c81SHans Verkuil 		if (unlikely(!ops->vidioc_enum_fmt_sdr_cap))
1418582c52cbSAntti Palosaari 			break;
1419ba300204SHans Verkuil 		ret = ops->vidioc_enum_fmt_sdr_cap(file, fh, arg);
1420ba300204SHans Verkuil 		break;
14219effc72fSAntti Palosaari 	case V4L2_BUF_TYPE_SDR_OUTPUT:
1422b2469c81SHans Verkuil 		if (unlikely(!ops->vidioc_enum_fmt_sdr_out))
14239effc72fSAntti Palosaari 			break;
14249effc72fSAntti Palosaari 		ret = ops->vidioc_enum_fmt_sdr_out(file, fh, arg);
14259effc72fSAntti Palosaari 		break;
1426fb9ffa6aSLaurent Pinchart 	case V4L2_BUF_TYPE_META_CAPTURE:
1427b2469c81SHans Verkuil 		if (unlikely(!ops->vidioc_enum_fmt_meta_cap))
1428fb9ffa6aSLaurent Pinchart 			break;
1429fb9ffa6aSLaurent Pinchart 		ret = ops->vidioc_enum_fmt_meta_cap(file, fh, arg);
1430fb9ffa6aSLaurent Pinchart 		break;
143172148d1aSSakari Ailus 	case V4L2_BUF_TYPE_META_OUTPUT:
143272148d1aSSakari Ailus 		if (unlikely(!ops->vidioc_enum_fmt_meta_out))
143372148d1aSSakari Ailus 			break;
143472148d1aSSakari Ailus 		ret = ops->vidioc_enum_fmt_meta_out(file, fh, arg);
143572148d1aSSakari Ailus 		break;
14365bc3cb74SMauro Carvalho Chehab 	}
1437ba300204SHans Verkuil 	if (ret == 0)
1438ba300204SHans Verkuil 		v4l_fill_fmtdesc(p);
1439ba300204SHans Verkuil 	return ret;
14405bc3cb74SMauro Carvalho Chehab }
14415bc3cb74SMauro Carvalho Chehab 
14425bc3cb74SMauro Carvalho Chehab static int v4l_g_fmt(const struct v4l2_ioctl_ops *ops,
14435bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
14445bc3cb74SMauro Carvalho Chehab {
14455bc3cb74SMauro Carvalho Chehab 	struct v4l2_format *p = arg;
1446b2469c81SHans Verkuil 	int ret = check_fmt(file, p->type);
1447b2469c81SHans Verkuil 
1448b2469c81SHans Verkuil 	if (ret)
1449b2469c81SHans Verkuil 		return ret;
1450d52e2381SLaurent Pinchart 
1451e5ce558aSHans Verkuil 	/*
1452e5ce558aSHans Verkuil 	 * fmt can't be cleared for these overlay types due to the 'clips'
1453e5ce558aSHans Verkuil 	 * 'clipcount' and 'bitmap' pointers in struct v4l2_window.
1454e5ce558aSHans Verkuil 	 * Those are provided by the user. So handle these two overlay types
1455e5ce558aSHans Verkuil 	 * first, and then just do a simple memset for the other types.
1456e5ce558aSHans Verkuil 	 */
1457e5ce558aSHans Verkuil 	switch (p->type) {
1458e5ce558aSHans Verkuil 	case V4L2_BUF_TYPE_VIDEO_OVERLAY:
1459e5ce558aSHans Verkuil 	case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY: {
14604d1afa51SHans Verkuil 		struct v4l2_clip __user *clips = p->fmt.win.clips;
1461e5ce558aSHans Verkuil 		u32 clipcount = p->fmt.win.clipcount;
14624d1afa51SHans Verkuil 		void __user *bitmap = p->fmt.win.bitmap;
1463e5ce558aSHans Verkuil 
1464e5ce558aSHans Verkuil 		memset(&p->fmt, 0, sizeof(p->fmt));
1465e5ce558aSHans Verkuil 		p->fmt.win.clips = clips;
1466e5ce558aSHans Verkuil 		p->fmt.win.clipcount = clipcount;
1467e5ce558aSHans Verkuil 		p->fmt.win.bitmap = bitmap;
1468e5ce558aSHans Verkuil 		break;
1469e5ce558aSHans Verkuil 	}
1470e5ce558aSHans Verkuil 	default:
1471e5ce558aSHans Verkuil 		memset(&p->fmt, 0, sizeof(p->fmt));
1472e5ce558aSHans Verkuil 		break;
1473e5ce558aSHans Verkuil 	}
1474e5ce558aSHans Verkuil 
14755bc3cb74SMauro Carvalho Chehab 	switch (p->type) {
14765bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_CAPTURE:
1477b2469c81SHans Verkuil 		if (unlikely(!ops->vidioc_g_fmt_vid_cap))
14785bc3cb74SMauro Carvalho Chehab 			break;
147948f2650aSHans Verkuil 		p->fmt.pix.priv = V4L2_PIX_FMT_PRIV_MAGIC;
1480d52e2381SLaurent Pinchart 		ret = ops->vidioc_g_fmt_vid_cap(file, fh, arg);
148148f2650aSHans Verkuil 		/* just in case the driver zeroed it again */
1482d52e2381SLaurent Pinchart 		p->fmt.pix.priv = V4L2_PIX_FMT_PRIV_MAGIC;
1483d52e2381SLaurent Pinchart 		return ret;
14845bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
14855bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_g_fmt_vid_cap_mplane(file, fh, arg);
14865bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_OVERLAY:
14875bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_g_fmt_vid_overlay(file, fh, arg);
14884b20259fSHans Verkuil 	case V4L2_BUF_TYPE_VBI_CAPTURE:
14894b20259fSHans Verkuil 		return ops->vidioc_g_fmt_vbi_cap(file, fh, arg);
14904b20259fSHans Verkuil 	case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
14914b20259fSHans Verkuil 		return ops->vidioc_g_fmt_sliced_vbi_cap(file, fh, arg);
14925bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_OUTPUT:
1493b2469c81SHans Verkuil 		if (unlikely(!ops->vidioc_g_fmt_vid_out))
14945bc3cb74SMauro Carvalho Chehab 			break;
149548f2650aSHans Verkuil 		p->fmt.pix.priv = V4L2_PIX_FMT_PRIV_MAGIC;
1496d52e2381SLaurent Pinchart 		ret = ops->vidioc_g_fmt_vid_out(file, fh, arg);
149748f2650aSHans Verkuil 		/* just in case the driver zeroed it again */
1498d52e2381SLaurent Pinchart 		p->fmt.pix.priv = V4L2_PIX_FMT_PRIV_MAGIC;
1499d52e2381SLaurent Pinchart 		return ret;
15005bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
15015bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_g_fmt_vid_out_mplane(file, fh, arg);
15025bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
15035bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_g_fmt_vid_out_overlay(file, fh, arg);
15045bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VBI_OUTPUT:
15055bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_g_fmt_vbi_out(file, fh, arg);
15065bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
15075bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_g_fmt_sliced_vbi_out(file, fh, arg);
1508582c52cbSAntti Palosaari 	case V4L2_BUF_TYPE_SDR_CAPTURE:
1509582c52cbSAntti Palosaari 		return ops->vidioc_g_fmt_sdr_cap(file, fh, arg);
15109effc72fSAntti Palosaari 	case V4L2_BUF_TYPE_SDR_OUTPUT:
15119effc72fSAntti Palosaari 		return ops->vidioc_g_fmt_sdr_out(file, fh, arg);
1512fb9ffa6aSLaurent Pinchart 	case V4L2_BUF_TYPE_META_CAPTURE:
1513fb9ffa6aSLaurent Pinchart 		return ops->vidioc_g_fmt_meta_cap(file, fh, arg);
151472148d1aSSakari Ailus 	case V4L2_BUF_TYPE_META_OUTPUT:
151572148d1aSSakari Ailus 		return ops->vidioc_g_fmt_meta_out(file, fh, arg);
15165bc3cb74SMauro Carvalho Chehab 	}
15175bc3cb74SMauro Carvalho Chehab 	return -EINVAL;
15185bc3cb74SMauro Carvalho Chehab }
15195bc3cb74SMauro Carvalho Chehab 
1520b2fe22d0SNick Dyer static void v4l_pix_format_touch(struct v4l2_pix_format *p)
1521b2fe22d0SNick Dyer {
1522b2fe22d0SNick Dyer 	/*
1523b2fe22d0SNick Dyer 	 * The v4l2_pix_format structure contains fields that make no sense for
1524b2fe22d0SNick Dyer 	 * touch. Set them to default values in this case.
1525b2fe22d0SNick Dyer 	 */
1526b2fe22d0SNick Dyer 
1527b2fe22d0SNick Dyer 	p->field = V4L2_FIELD_NONE;
1528b2fe22d0SNick Dyer 	p->colorspace = V4L2_COLORSPACE_RAW;
1529b2fe22d0SNick Dyer 	p->flags = 0;
1530b2fe22d0SNick Dyer 	p->ycbcr_enc = 0;
1531b2fe22d0SNick Dyer 	p->quantization = 0;
1532b2fe22d0SNick Dyer 	p->xfer_func = 0;
1533b2fe22d0SNick Dyer }
1534b2fe22d0SNick Dyer 
15355bc3cb74SMauro Carvalho Chehab static int v4l_s_fmt(const struct v4l2_ioctl_ops *ops,
15365bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
15375bc3cb74SMauro Carvalho Chehab {
15385bc3cb74SMauro Carvalho Chehab 	struct v4l2_format *p = arg;
15394b20259fSHans Verkuil 	struct video_device *vfd = video_devdata(file);
1540b2469c81SHans Verkuil 	int ret = check_fmt(file, p->type);
15414e1e0eb0SEzequiel Garcia 	unsigned int i;
1542b2469c81SHans Verkuil 
1543b2469c81SHans Verkuil 	if (ret)
1544b2469c81SHans Verkuil 		return ret;
15455bc3cb74SMauro Carvalho Chehab 
154677fa4e07SShuah Khan 	ret = v4l_enable_media_source(vfd);
154777fa4e07SShuah Khan 	if (ret)
154877fa4e07SShuah Khan 		return ret;
1549d52e2381SLaurent Pinchart 	v4l_sanitize_format(p);
1550d52e2381SLaurent Pinchart 
15515bc3cb74SMauro Carvalho Chehab 	switch (p->type) {
15525bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_CAPTURE:
1553b2469c81SHans Verkuil 		if (unlikely(!ops->vidioc_s_fmt_vid_cap))
15545bc3cb74SMauro Carvalho Chehab 			break;
15555bc3cb74SMauro Carvalho Chehab 		CLEAR_AFTER_FIELD(p, fmt.pix);
155648f2650aSHans Verkuil 		ret = ops->vidioc_s_fmt_vid_cap(file, fh, arg);
155748f2650aSHans Verkuil 		/* just in case the driver zeroed it again */
155848f2650aSHans Verkuil 		p->fmt.pix.priv = V4L2_PIX_FMT_PRIV_MAGIC;
1559b2469c81SHans Verkuil 		if (vfd->vfl_type == VFL_TYPE_TOUCH)
1560b2fe22d0SNick Dyer 			v4l_pix_format_touch(&p->fmt.pix);
156148f2650aSHans Verkuil 		return ret;
15625bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
1563b2469c81SHans Verkuil 		if (unlikely(!ops->vidioc_s_fmt_vid_cap_mplane))
15645bc3cb74SMauro Carvalho Chehab 			break;
1565c49148e8SLaurent Pinchart 		CLEAR_AFTER_FIELD(p, fmt.pix_mp.xfer_func);
15664e1e0eb0SEzequiel Garcia 		for (i = 0; i < p->fmt.pix_mp.num_planes; i++)
1567dd91642aSThierry Reding 			CLEAR_AFTER_FIELD(&p->fmt.pix_mp.plane_fmt[i],
1568dd91642aSThierry Reding 					  bytesperline);
15695bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_s_fmt_vid_cap_mplane(file, fh, arg);
15705bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_OVERLAY:
1571b2469c81SHans Verkuil 		if (unlikely(!ops->vidioc_s_fmt_vid_overlay))
15725bc3cb74SMauro Carvalho Chehab 			break;
15735bc3cb74SMauro Carvalho Chehab 		CLEAR_AFTER_FIELD(p, fmt.win);
15745bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_s_fmt_vid_overlay(file, fh, arg);
15754b20259fSHans Verkuil 	case V4L2_BUF_TYPE_VBI_CAPTURE:
1576b2469c81SHans Verkuil 		if (unlikely(!ops->vidioc_s_fmt_vbi_cap))
15774b20259fSHans Verkuil 			break;
15784b20259fSHans Verkuil 		CLEAR_AFTER_FIELD(p, fmt.vbi);
15794b20259fSHans Verkuil 		return ops->vidioc_s_fmt_vbi_cap(file, fh, arg);
15804b20259fSHans Verkuil 	case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
1581b2469c81SHans Verkuil 		if (unlikely(!ops->vidioc_s_fmt_sliced_vbi_cap))
15824b20259fSHans Verkuil 			break;
15834b20259fSHans Verkuil 		CLEAR_AFTER_FIELD(p, fmt.sliced);
15844b20259fSHans Verkuil 		return ops->vidioc_s_fmt_sliced_vbi_cap(file, fh, arg);
15855bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_OUTPUT:
1586b2469c81SHans Verkuil 		if (unlikely(!ops->vidioc_s_fmt_vid_out))
15875bc3cb74SMauro Carvalho Chehab 			break;
15885bc3cb74SMauro Carvalho Chehab 		CLEAR_AFTER_FIELD(p, fmt.pix);
158948f2650aSHans Verkuil 		ret = ops->vidioc_s_fmt_vid_out(file, fh, arg);
159048f2650aSHans Verkuil 		/* just in case the driver zeroed it again */
159148f2650aSHans Verkuil 		p->fmt.pix.priv = V4L2_PIX_FMT_PRIV_MAGIC;
159248f2650aSHans Verkuil 		return ret;
15935bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
1594b2469c81SHans Verkuil 		if (unlikely(!ops->vidioc_s_fmt_vid_out_mplane))
15955bc3cb74SMauro Carvalho Chehab 			break;
1596c49148e8SLaurent Pinchart 		CLEAR_AFTER_FIELD(p, fmt.pix_mp.xfer_func);
15974e1e0eb0SEzequiel Garcia 		for (i = 0; i < p->fmt.pix_mp.num_planes; i++)
1598dd91642aSThierry Reding 			CLEAR_AFTER_FIELD(&p->fmt.pix_mp.plane_fmt[i],
1599dd91642aSThierry Reding 					  bytesperline);
16005bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_s_fmt_vid_out_mplane(file, fh, arg);
16015bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
1602b2469c81SHans Verkuil 		if (unlikely(!ops->vidioc_s_fmt_vid_out_overlay))
16035bc3cb74SMauro Carvalho Chehab 			break;
16045bc3cb74SMauro Carvalho Chehab 		CLEAR_AFTER_FIELD(p, fmt.win);
16055bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_s_fmt_vid_out_overlay(file, fh, arg);
16065bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VBI_OUTPUT:
1607b2469c81SHans Verkuil 		if (unlikely(!ops->vidioc_s_fmt_vbi_out))
16085bc3cb74SMauro Carvalho Chehab 			break;
16095bc3cb74SMauro Carvalho Chehab 		CLEAR_AFTER_FIELD(p, fmt.vbi);
16105bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_s_fmt_vbi_out(file, fh, arg);
16115bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
1612b2469c81SHans Verkuil 		if (unlikely(!ops->vidioc_s_fmt_sliced_vbi_out))
16135bc3cb74SMauro Carvalho Chehab 			break;
16145bc3cb74SMauro Carvalho Chehab 		CLEAR_AFTER_FIELD(p, fmt.sliced);
16155bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_s_fmt_sliced_vbi_out(file, fh, arg);
1616582c52cbSAntti Palosaari 	case V4L2_BUF_TYPE_SDR_CAPTURE:
1617b2469c81SHans Verkuil 		if (unlikely(!ops->vidioc_s_fmt_sdr_cap))
1618582c52cbSAntti Palosaari 			break;
1619582c52cbSAntti Palosaari 		CLEAR_AFTER_FIELD(p, fmt.sdr);
1620582c52cbSAntti Palosaari 		return ops->vidioc_s_fmt_sdr_cap(file, fh, arg);
16219effc72fSAntti Palosaari 	case V4L2_BUF_TYPE_SDR_OUTPUT:
1622b2469c81SHans Verkuil 		if (unlikely(!ops->vidioc_s_fmt_sdr_out))
16239effc72fSAntti Palosaari 			break;
16249effc72fSAntti Palosaari 		CLEAR_AFTER_FIELD(p, fmt.sdr);
16259effc72fSAntti Palosaari 		return ops->vidioc_s_fmt_sdr_out(file, fh, arg);
1626fb9ffa6aSLaurent Pinchart 	case V4L2_BUF_TYPE_META_CAPTURE:
1627b2469c81SHans Verkuil 		if (unlikely(!ops->vidioc_s_fmt_meta_cap))
1628fb9ffa6aSLaurent Pinchart 			break;
1629fb9ffa6aSLaurent Pinchart 		CLEAR_AFTER_FIELD(p, fmt.meta);
1630fb9ffa6aSLaurent Pinchart 		return ops->vidioc_s_fmt_meta_cap(file, fh, arg);
163172148d1aSSakari Ailus 	case V4L2_BUF_TYPE_META_OUTPUT:
163272148d1aSSakari Ailus 		if (unlikely(!ops->vidioc_s_fmt_meta_out))
163372148d1aSSakari Ailus 			break;
163472148d1aSSakari Ailus 		CLEAR_AFTER_FIELD(p, fmt.meta);
163572148d1aSSakari Ailus 		return ops->vidioc_s_fmt_meta_out(file, fh, arg);
16365bc3cb74SMauro Carvalho Chehab 	}
16375bc3cb74SMauro Carvalho Chehab 	return -EINVAL;
16385bc3cb74SMauro Carvalho Chehab }
16395bc3cb74SMauro Carvalho Chehab 
16405bc3cb74SMauro Carvalho Chehab static int v4l_try_fmt(const struct v4l2_ioctl_ops *ops,
16415bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
16425bc3cb74SMauro Carvalho Chehab {
16435bc3cb74SMauro Carvalho Chehab 	struct v4l2_format *p = arg;
1644b2469c81SHans Verkuil 	int ret = check_fmt(file, p->type);
16454e1e0eb0SEzequiel Garcia 	unsigned int i;
1646b2469c81SHans Verkuil 
1647b2469c81SHans Verkuil 	if (ret)
1648b2469c81SHans Verkuil 		return ret;
16495bc3cb74SMauro Carvalho Chehab 
1650d52e2381SLaurent Pinchart 	v4l_sanitize_format(p);
1651d52e2381SLaurent Pinchart 
16525bc3cb74SMauro Carvalho Chehab 	switch (p->type) {
16535bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_CAPTURE:
1654b2469c81SHans Verkuil 		if (unlikely(!ops->vidioc_try_fmt_vid_cap))
16555bc3cb74SMauro Carvalho Chehab 			break;
16565bc3cb74SMauro Carvalho Chehab 		CLEAR_AFTER_FIELD(p, fmt.pix);
165748f2650aSHans Verkuil 		ret = ops->vidioc_try_fmt_vid_cap(file, fh, arg);
165848f2650aSHans Verkuil 		/* just in case the driver zeroed it again */
165948f2650aSHans Verkuil 		p->fmt.pix.priv = V4L2_PIX_FMT_PRIV_MAGIC;
166048f2650aSHans Verkuil 		return ret;
16615bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
1662b2469c81SHans Verkuil 		if (unlikely(!ops->vidioc_try_fmt_vid_cap_mplane))
16635bc3cb74SMauro Carvalho Chehab 			break;
1664c49148e8SLaurent Pinchart 		CLEAR_AFTER_FIELD(p, fmt.pix_mp.xfer_func);
16654e1e0eb0SEzequiel Garcia 		for (i = 0; i < p->fmt.pix_mp.num_planes; i++)
1666dd91642aSThierry Reding 			CLEAR_AFTER_FIELD(&p->fmt.pix_mp.plane_fmt[i],
1667dd91642aSThierry Reding 					  bytesperline);
16685bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_try_fmt_vid_cap_mplane(file, fh, arg);
16695bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_OVERLAY:
1670b2469c81SHans Verkuil 		if (unlikely(!ops->vidioc_try_fmt_vid_overlay))
16715bc3cb74SMauro Carvalho Chehab 			break;
16725bc3cb74SMauro Carvalho Chehab 		CLEAR_AFTER_FIELD(p, fmt.win);
16735bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_try_fmt_vid_overlay(file, fh, arg);
16744b20259fSHans Verkuil 	case V4L2_BUF_TYPE_VBI_CAPTURE:
1675b2469c81SHans Verkuil 		if (unlikely(!ops->vidioc_try_fmt_vbi_cap))
16764b20259fSHans Verkuil 			break;
16774b20259fSHans Verkuil 		CLEAR_AFTER_FIELD(p, fmt.vbi);
16784b20259fSHans Verkuil 		return ops->vidioc_try_fmt_vbi_cap(file, fh, arg);
16794b20259fSHans Verkuil 	case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
1680b2469c81SHans Verkuil 		if (unlikely(!ops->vidioc_try_fmt_sliced_vbi_cap))
16814b20259fSHans Verkuil 			break;
16824b20259fSHans Verkuil 		CLEAR_AFTER_FIELD(p, fmt.sliced);
16834b20259fSHans Verkuil 		return ops->vidioc_try_fmt_sliced_vbi_cap(file, fh, arg);
16845bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_OUTPUT:
1685b2469c81SHans Verkuil 		if (unlikely(!ops->vidioc_try_fmt_vid_out))
16865bc3cb74SMauro Carvalho Chehab 			break;
16875bc3cb74SMauro Carvalho Chehab 		CLEAR_AFTER_FIELD(p, fmt.pix);
168848f2650aSHans Verkuil 		ret = ops->vidioc_try_fmt_vid_out(file, fh, arg);
168948f2650aSHans Verkuil 		/* just in case the driver zeroed it again */
169048f2650aSHans Verkuil 		p->fmt.pix.priv = V4L2_PIX_FMT_PRIV_MAGIC;
169148f2650aSHans Verkuil 		return ret;
16925bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
1693b2469c81SHans Verkuil 		if (unlikely(!ops->vidioc_try_fmt_vid_out_mplane))
16945bc3cb74SMauro Carvalho Chehab 			break;
1695c49148e8SLaurent Pinchart 		CLEAR_AFTER_FIELD(p, fmt.pix_mp.xfer_func);
16964e1e0eb0SEzequiel Garcia 		for (i = 0; i < p->fmt.pix_mp.num_planes; i++)
1697dd91642aSThierry Reding 			CLEAR_AFTER_FIELD(&p->fmt.pix_mp.plane_fmt[i],
1698dd91642aSThierry Reding 					  bytesperline);
16995bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_try_fmt_vid_out_mplane(file, fh, arg);
17005bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
1701b2469c81SHans Verkuil 		if (unlikely(!ops->vidioc_try_fmt_vid_out_overlay))
17025bc3cb74SMauro Carvalho Chehab 			break;
17035bc3cb74SMauro Carvalho Chehab 		CLEAR_AFTER_FIELD(p, fmt.win);
17045bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_try_fmt_vid_out_overlay(file, fh, arg);
17055bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VBI_OUTPUT:
1706b2469c81SHans Verkuil 		if (unlikely(!ops->vidioc_try_fmt_vbi_out))
17075bc3cb74SMauro Carvalho Chehab 			break;
17085bc3cb74SMauro Carvalho Chehab 		CLEAR_AFTER_FIELD(p, fmt.vbi);
17095bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_try_fmt_vbi_out(file, fh, arg);
17105bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
1711b2469c81SHans Verkuil 		if (unlikely(!ops->vidioc_try_fmt_sliced_vbi_out))
17125bc3cb74SMauro Carvalho Chehab 			break;
17135bc3cb74SMauro Carvalho Chehab 		CLEAR_AFTER_FIELD(p, fmt.sliced);
17145bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_try_fmt_sliced_vbi_out(file, fh, arg);
1715582c52cbSAntti Palosaari 	case V4L2_BUF_TYPE_SDR_CAPTURE:
1716b2469c81SHans Verkuil 		if (unlikely(!ops->vidioc_try_fmt_sdr_cap))
1717582c52cbSAntti Palosaari 			break;
1718582c52cbSAntti Palosaari 		CLEAR_AFTER_FIELD(p, fmt.sdr);
1719582c52cbSAntti Palosaari 		return ops->vidioc_try_fmt_sdr_cap(file, fh, arg);
17209effc72fSAntti Palosaari 	case V4L2_BUF_TYPE_SDR_OUTPUT:
1721b2469c81SHans Verkuil 		if (unlikely(!ops->vidioc_try_fmt_sdr_out))
17229effc72fSAntti Palosaari 			break;
17239effc72fSAntti Palosaari 		CLEAR_AFTER_FIELD(p, fmt.sdr);
17249effc72fSAntti Palosaari 		return ops->vidioc_try_fmt_sdr_out(file, fh, arg);
1725fb9ffa6aSLaurent Pinchart 	case V4L2_BUF_TYPE_META_CAPTURE:
1726b2469c81SHans Verkuil 		if (unlikely(!ops->vidioc_try_fmt_meta_cap))
1727fb9ffa6aSLaurent Pinchart 			break;
1728fb9ffa6aSLaurent Pinchart 		CLEAR_AFTER_FIELD(p, fmt.meta);
1729fb9ffa6aSLaurent Pinchart 		return ops->vidioc_try_fmt_meta_cap(file, fh, arg);
173072148d1aSSakari Ailus 	case V4L2_BUF_TYPE_META_OUTPUT:
173172148d1aSSakari Ailus 		if (unlikely(!ops->vidioc_try_fmt_meta_out))
173272148d1aSSakari Ailus 			break;
173372148d1aSSakari Ailus 		CLEAR_AFTER_FIELD(p, fmt.meta);
173472148d1aSSakari Ailus 		return ops->vidioc_try_fmt_meta_out(file, fh, arg);
17355bc3cb74SMauro Carvalho Chehab 	}
17365bc3cb74SMauro Carvalho Chehab 	return -EINVAL;
17375bc3cb74SMauro Carvalho Chehab }
17385bc3cb74SMauro Carvalho Chehab 
17395bc3cb74SMauro Carvalho Chehab static int v4l_streamon(const struct v4l2_ioctl_ops *ops,
17405bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
17415bc3cb74SMauro Carvalho Chehab {
17425bc3cb74SMauro Carvalho Chehab 	return ops->vidioc_streamon(file, fh, *(unsigned int *)arg);
17435bc3cb74SMauro Carvalho Chehab }
17445bc3cb74SMauro Carvalho Chehab 
17455bc3cb74SMauro Carvalho Chehab static int v4l_streamoff(const struct v4l2_ioctl_ops *ops,
17465bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
17475bc3cb74SMauro Carvalho Chehab {
17485bc3cb74SMauro Carvalho Chehab 	return ops->vidioc_streamoff(file, fh, *(unsigned int *)arg);
17495bc3cb74SMauro Carvalho Chehab }
17505bc3cb74SMauro Carvalho Chehab 
17515bc3cb74SMauro Carvalho Chehab static int v4l_g_tuner(const struct v4l2_ioctl_ops *ops,
17525bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
17535bc3cb74SMauro Carvalho Chehab {
17545bc3cb74SMauro Carvalho Chehab 	struct video_device *vfd = video_devdata(file);
17555bc3cb74SMauro Carvalho Chehab 	struct v4l2_tuner *p = arg;
17565bc3cb74SMauro Carvalho Chehab 	int err;
17575bc3cb74SMauro Carvalho Chehab 
17585bc3cb74SMauro Carvalho Chehab 	p->type = (vfd->vfl_type == VFL_TYPE_RADIO) ?
17595bc3cb74SMauro Carvalho Chehab 			V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV;
17605bc3cb74SMauro Carvalho Chehab 	err = ops->vidioc_g_tuner(file, fh, p);
17615bc3cb74SMauro Carvalho Chehab 	if (!err)
17625bc3cb74SMauro Carvalho Chehab 		p->capability |= V4L2_TUNER_CAP_FREQ_BANDS;
17635bc3cb74SMauro Carvalho Chehab 	return err;
17645bc3cb74SMauro Carvalho Chehab }
17655bc3cb74SMauro Carvalho Chehab 
17665bc3cb74SMauro Carvalho Chehab static int v4l_s_tuner(const struct v4l2_ioctl_ops *ops,
17675bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
17685bc3cb74SMauro Carvalho Chehab {
17695bc3cb74SMauro Carvalho Chehab 	struct video_device *vfd = video_devdata(file);
17705bc3cb74SMauro Carvalho Chehab 	struct v4l2_tuner *p = arg;
177177fa4e07SShuah Khan 	int ret;
17725bc3cb74SMauro Carvalho Chehab 
177377fa4e07SShuah Khan 	ret = v4l_enable_media_source(vfd);
177477fa4e07SShuah Khan 	if (ret)
177577fa4e07SShuah Khan 		return ret;
17765bc3cb74SMauro Carvalho Chehab 	p->type = (vfd->vfl_type == VFL_TYPE_RADIO) ?
17775bc3cb74SMauro Carvalho Chehab 			V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV;
17785bc3cb74SMauro Carvalho Chehab 	return ops->vidioc_s_tuner(file, fh, p);
17795bc3cb74SMauro Carvalho Chehab }
17805bc3cb74SMauro Carvalho Chehab 
17815bc3cb74SMauro Carvalho Chehab static int v4l_g_modulator(const struct v4l2_ioctl_ops *ops,
17825bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
17835bc3cb74SMauro Carvalho Chehab {
17844124a3c4SAntti Palosaari 	struct video_device *vfd = video_devdata(file);
17855bc3cb74SMauro Carvalho Chehab 	struct v4l2_modulator *p = arg;
17865bc3cb74SMauro Carvalho Chehab 	int err;
17875bc3cb74SMauro Carvalho Chehab 
17884124a3c4SAntti Palosaari 	if (vfd->vfl_type == VFL_TYPE_RADIO)
17894124a3c4SAntti Palosaari 		p->type = V4L2_TUNER_RADIO;
17904124a3c4SAntti Palosaari 
17915bc3cb74SMauro Carvalho Chehab 	err = ops->vidioc_g_modulator(file, fh, p);
17925bc3cb74SMauro Carvalho Chehab 	if (!err)
17935bc3cb74SMauro Carvalho Chehab 		p->capability |= V4L2_TUNER_CAP_FREQ_BANDS;
17945bc3cb74SMauro Carvalho Chehab 	return err;
17955bc3cb74SMauro Carvalho Chehab }
17965bc3cb74SMauro Carvalho Chehab 
17974124a3c4SAntti Palosaari static int v4l_s_modulator(const struct v4l2_ioctl_ops *ops,
17984124a3c4SAntti Palosaari 				struct file *file, void *fh, void *arg)
17994124a3c4SAntti Palosaari {
18004124a3c4SAntti Palosaari 	struct video_device *vfd = video_devdata(file);
18014124a3c4SAntti Palosaari 	struct v4l2_modulator *p = arg;
18024124a3c4SAntti Palosaari 
18034124a3c4SAntti Palosaari 	if (vfd->vfl_type == VFL_TYPE_RADIO)
18044124a3c4SAntti Palosaari 		p->type = V4L2_TUNER_RADIO;
18054124a3c4SAntti Palosaari 
18064124a3c4SAntti Palosaari 	return ops->vidioc_s_modulator(file, fh, p);
18074124a3c4SAntti Palosaari }
18084124a3c4SAntti Palosaari 
18095bc3cb74SMauro Carvalho Chehab static int v4l_g_frequency(const struct v4l2_ioctl_ops *ops,
18105bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
18115bc3cb74SMauro Carvalho Chehab {
18125bc3cb74SMauro Carvalho Chehab 	struct video_device *vfd = video_devdata(file);
18135bc3cb74SMauro Carvalho Chehab 	struct v4l2_frequency *p = arg;
18145bc3cb74SMauro Carvalho Chehab 
181584099a28SAntti Palosaari 	if (vfd->vfl_type == VFL_TYPE_SDR)
1816f3c3ececSAntti Palosaari 		p->type = V4L2_TUNER_SDR;
181784099a28SAntti Palosaari 	else
18185bc3cb74SMauro Carvalho Chehab 		p->type = (vfd->vfl_type == VFL_TYPE_RADIO) ?
18195bc3cb74SMauro Carvalho Chehab 				V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV;
18205bc3cb74SMauro Carvalho Chehab 	return ops->vidioc_g_frequency(file, fh, p);
18215bc3cb74SMauro Carvalho Chehab }
18225bc3cb74SMauro Carvalho Chehab 
18235bc3cb74SMauro Carvalho Chehab static int v4l_s_frequency(const struct v4l2_ioctl_ops *ops,
18245bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
18255bc3cb74SMauro Carvalho Chehab {
18265bc3cb74SMauro Carvalho Chehab 	struct video_device *vfd = video_devdata(file);
1827b530a447SHans Verkuil 	const struct v4l2_frequency *p = arg;
18285bc3cb74SMauro Carvalho Chehab 	enum v4l2_tuner_type type;
182977fa4e07SShuah Khan 	int ret;
18305bc3cb74SMauro Carvalho Chehab 
183177fa4e07SShuah Khan 	ret = v4l_enable_media_source(vfd);
183277fa4e07SShuah Khan 	if (ret)
183377fa4e07SShuah Khan 		return ret;
183484099a28SAntti Palosaari 	if (vfd->vfl_type == VFL_TYPE_SDR) {
1835f3c3ececSAntti Palosaari 		if (p->type != V4L2_TUNER_SDR && p->type != V4L2_TUNER_RF)
183684099a28SAntti Palosaari 			return -EINVAL;
183784099a28SAntti Palosaari 	} else {
18385bc3cb74SMauro Carvalho Chehab 		type = (vfd->vfl_type == VFL_TYPE_RADIO) ?
18395bc3cb74SMauro Carvalho Chehab 				V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV;
184084099a28SAntti Palosaari 		if (type != p->type)
18415bc3cb74SMauro Carvalho Chehab 			return -EINVAL;
184284099a28SAntti Palosaari 	}
18435bc3cb74SMauro Carvalho Chehab 	return ops->vidioc_s_frequency(file, fh, p);
18445bc3cb74SMauro Carvalho Chehab }
18455bc3cb74SMauro Carvalho Chehab 
18465bc3cb74SMauro Carvalho Chehab static int v4l_enumstd(const struct v4l2_ioctl_ops *ops,
18475bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
18485bc3cb74SMauro Carvalho Chehab {
18495bc3cb74SMauro Carvalho Chehab 	struct video_device *vfd = video_devdata(file);
18505bc3cb74SMauro Carvalho Chehab 	struct v4l2_standard *p = arg;
18515bc3cb74SMauro Carvalho Chehab 
1852aa2f8871SNiklas Söderlund 	return v4l_video_std_enumstd(p, vfd->tvnorms);
18535bc3cb74SMauro Carvalho Chehab }
18545bc3cb74SMauro Carvalho Chehab 
18555bc3cb74SMauro Carvalho Chehab static int v4l_s_std(const struct v4l2_ioctl_ops *ops,
18565bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
18575bc3cb74SMauro Carvalho Chehab {
18585bc3cb74SMauro Carvalho Chehab 	struct video_device *vfd = video_devdata(file);
1859314527acSHans Verkuil 	v4l2_std_id id = *(v4l2_std_id *)arg, norm;
186077fa4e07SShuah Khan 	int ret;
18615bc3cb74SMauro Carvalho Chehab 
186277fa4e07SShuah Khan 	ret = v4l_enable_media_source(vfd);
186377fa4e07SShuah Khan 	if (ret)
186477fa4e07SShuah Khan 		return ret;
1865314527acSHans Verkuil 	norm = id & vfd->tvnorms;
18665bc3cb74SMauro Carvalho Chehab 	if (vfd->tvnorms && !norm)	/* Check if std is supported */
18675bc3cb74SMauro Carvalho Chehab 		return -EINVAL;
18685bc3cb74SMauro Carvalho Chehab 
18695bc3cb74SMauro Carvalho Chehab 	/* Calls the specific handler */
1870ca371575SHans Verkuil 	return ops->vidioc_s_std(file, fh, norm);
18715bc3cb74SMauro Carvalho Chehab }
18725bc3cb74SMauro Carvalho Chehab 
18735bc3cb74SMauro Carvalho Chehab static int v4l_querystd(const struct v4l2_ioctl_ops *ops,
18745bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
18755bc3cb74SMauro Carvalho Chehab {
18765bc3cb74SMauro Carvalho Chehab 	struct video_device *vfd = video_devdata(file);
18775bc3cb74SMauro Carvalho Chehab 	v4l2_std_id *p = arg;
187877fa4e07SShuah Khan 	int ret;
18795bc3cb74SMauro Carvalho Chehab 
188077fa4e07SShuah Khan 	ret = v4l_enable_media_source(vfd);
188177fa4e07SShuah Khan 	if (ret)
188277fa4e07SShuah Khan 		return ret;
18835bc3cb74SMauro Carvalho Chehab 	/*
18841a2c6866SHans Verkuil 	 * If no signal is detected, then the driver should return
18851a2c6866SHans Verkuil 	 * V4L2_STD_UNKNOWN. Otherwise it should return tvnorms with
18861a2c6866SHans Verkuil 	 * any standards that do not apply removed.
18871a2c6866SHans Verkuil 	 *
18885bc3cb74SMauro Carvalho Chehab 	 * This means that tuners, audio and video decoders can join
18895bc3cb74SMauro Carvalho Chehab 	 * their efforts to improve the standards detection.
18905bc3cb74SMauro Carvalho Chehab 	 */
18915bc3cb74SMauro Carvalho Chehab 	*p = vfd->tvnorms;
18925bc3cb74SMauro Carvalho Chehab 	return ops->vidioc_querystd(file, fh, arg);
18935bc3cb74SMauro Carvalho Chehab }
18945bc3cb74SMauro Carvalho Chehab 
18955bc3cb74SMauro Carvalho Chehab static int v4l_s_hw_freq_seek(const struct v4l2_ioctl_ops *ops,
18965bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
18975bc3cb74SMauro Carvalho Chehab {
18985bc3cb74SMauro Carvalho Chehab 	struct video_device *vfd = video_devdata(file);
18995bc3cb74SMauro Carvalho Chehab 	struct v4l2_hw_freq_seek *p = arg;
19005bc3cb74SMauro Carvalho Chehab 	enum v4l2_tuner_type type;
190177fa4e07SShuah Khan 	int ret;
19025bc3cb74SMauro Carvalho Chehab 
190377fa4e07SShuah Khan 	ret = v4l_enable_media_source(vfd);
190477fa4e07SShuah Khan 	if (ret)
190577fa4e07SShuah Khan 		return ret;
190684099a28SAntti Palosaari 	/* s_hw_freq_seek is not supported for SDR for now */
190784099a28SAntti Palosaari 	if (vfd->vfl_type == VFL_TYPE_SDR)
190884099a28SAntti Palosaari 		return -EINVAL;
190984099a28SAntti Palosaari 
19105bc3cb74SMauro Carvalho Chehab 	type = (vfd->vfl_type == VFL_TYPE_RADIO) ?
19115bc3cb74SMauro Carvalho Chehab 		V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV;
19125bc3cb74SMauro Carvalho Chehab 	if (p->type != type)
19135bc3cb74SMauro Carvalho Chehab 		return -EINVAL;
19145bc3cb74SMauro Carvalho Chehab 	return ops->vidioc_s_hw_freq_seek(file, fh, p);
19155bc3cb74SMauro Carvalho Chehab }
19165bc3cb74SMauro Carvalho Chehab 
1917737c097bSHans Verkuil static int v4l_overlay(const struct v4l2_ioctl_ops *ops,
1918737c097bSHans Verkuil 				struct file *file, void *fh, void *arg)
1919737c097bSHans Verkuil {
1920737c097bSHans Verkuil 	return ops->vidioc_overlay(file, fh, *(unsigned int *)arg);
1921737c097bSHans Verkuil }
1922737c097bSHans Verkuil 
19235bc3cb74SMauro Carvalho Chehab static int v4l_reqbufs(const struct v4l2_ioctl_ops *ops,
19245bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
19255bc3cb74SMauro Carvalho Chehab {
19265bc3cb74SMauro Carvalho Chehab 	struct v4l2_requestbuffers *p = arg;
19274b20259fSHans Verkuil 	int ret = check_fmt(file, p->type);
19285bc3cb74SMauro Carvalho Chehab 
19295bc3cb74SMauro Carvalho Chehab 	if (ret)
19305bc3cb74SMauro Carvalho Chehab 		return ret;
19315bc3cb74SMauro Carvalho Chehab 
1932e5079cf1SHans Verkuil 	CLEAR_AFTER_FIELD(p, capabilities);
19335bc3cb74SMauro Carvalho Chehab 
19345bc3cb74SMauro Carvalho Chehab 	return ops->vidioc_reqbufs(file, fh, p);
19355bc3cb74SMauro Carvalho Chehab }
19365bc3cb74SMauro Carvalho Chehab 
19375bc3cb74SMauro Carvalho Chehab static int v4l_querybuf(const struct v4l2_ioctl_ops *ops,
19385bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
19395bc3cb74SMauro Carvalho Chehab {
19405bc3cb74SMauro Carvalho Chehab 	struct v4l2_buffer *p = arg;
19414b20259fSHans Verkuil 	int ret = check_fmt(file, p->type);
19425bc3cb74SMauro Carvalho Chehab 
19435bc3cb74SMauro Carvalho Chehab 	return ret ? ret : ops->vidioc_querybuf(file, fh, p);
19445bc3cb74SMauro Carvalho Chehab }
19455bc3cb74SMauro Carvalho Chehab 
19465bc3cb74SMauro Carvalho Chehab static int v4l_qbuf(const struct v4l2_ioctl_ops *ops,
19475bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
19485bc3cb74SMauro Carvalho Chehab {
19495bc3cb74SMauro Carvalho Chehab 	struct v4l2_buffer *p = arg;
19504b20259fSHans Verkuil 	int ret = check_fmt(file, p->type);
19515bc3cb74SMauro Carvalho Chehab 
19525bc3cb74SMauro Carvalho Chehab 	return ret ? ret : ops->vidioc_qbuf(file, fh, p);
19535bc3cb74SMauro Carvalho Chehab }
19545bc3cb74SMauro Carvalho Chehab 
19555bc3cb74SMauro Carvalho Chehab static int v4l_dqbuf(const struct v4l2_ioctl_ops *ops,
19565bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
19575bc3cb74SMauro Carvalho Chehab {
19585bc3cb74SMauro Carvalho Chehab 	struct v4l2_buffer *p = arg;
19594b20259fSHans Verkuil 	int ret = check_fmt(file, p->type);
19605bc3cb74SMauro Carvalho Chehab 
19615bc3cb74SMauro Carvalho Chehab 	return ret ? ret : ops->vidioc_dqbuf(file, fh, p);
19625bc3cb74SMauro Carvalho Chehab }
19635bc3cb74SMauro Carvalho Chehab 
19645bc3cb74SMauro Carvalho Chehab static int v4l_create_bufs(const struct v4l2_ioctl_ops *ops,
19655bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
19665bc3cb74SMauro Carvalho Chehab {
19675bc3cb74SMauro Carvalho Chehab 	struct v4l2_create_buffers *create = arg;
19684b20259fSHans Verkuil 	int ret = check_fmt(file, create->format.type);
19695bc3cb74SMauro Carvalho Chehab 
1970d52e2381SLaurent Pinchart 	if (ret)
1971d52e2381SLaurent Pinchart 		return ret;
1972d52e2381SLaurent Pinchart 
1973e5079cf1SHans Verkuil 	CLEAR_AFTER_FIELD(create, capabilities);
19745d351251SHans Verkuil 
1975d52e2381SLaurent Pinchart 	v4l_sanitize_format(&create->format);
1976d52e2381SLaurent Pinchart 
1977d52e2381SLaurent Pinchart 	ret = ops->vidioc_create_bufs(file, fh, create);
1978d52e2381SLaurent Pinchart 
1979d52e2381SLaurent Pinchart 	if (create->format.type == V4L2_BUF_TYPE_VIDEO_CAPTURE ||
1980d52e2381SLaurent Pinchart 	    create->format.type == V4L2_BUF_TYPE_VIDEO_OUTPUT)
1981d52e2381SLaurent Pinchart 		create->format.fmt.pix.priv = V4L2_PIX_FMT_PRIV_MAGIC;
1982d52e2381SLaurent Pinchart 
1983d52e2381SLaurent Pinchart 	return ret;
19845bc3cb74SMauro Carvalho Chehab }
19855bc3cb74SMauro Carvalho Chehab 
19865bc3cb74SMauro Carvalho Chehab static int v4l_prepare_buf(const struct v4l2_ioctl_ops *ops,
19875bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
19885bc3cb74SMauro Carvalho Chehab {
19895bc3cb74SMauro Carvalho Chehab 	struct v4l2_buffer *b = arg;
19904b20259fSHans Verkuil 	int ret = check_fmt(file, b->type);
19915bc3cb74SMauro Carvalho Chehab 
19925bc3cb74SMauro Carvalho Chehab 	return ret ? ret : ops->vidioc_prepare_buf(file, fh, b);
19935bc3cb74SMauro Carvalho Chehab }
19945bc3cb74SMauro Carvalho Chehab 
19955bc3cb74SMauro Carvalho Chehab static int v4l_g_parm(const struct v4l2_ioctl_ops *ops,
19965bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
19975bc3cb74SMauro Carvalho Chehab {
19985bc3cb74SMauro Carvalho Chehab 	struct v4l2_streamparm *p = arg;
19995bc3cb74SMauro Carvalho Chehab 	v4l2_std_id std;
20004b20259fSHans Verkuil 	int ret = check_fmt(file, p->type);
20015bc3cb74SMauro Carvalho Chehab 
20025bc3cb74SMauro Carvalho Chehab 	if (ret)
20035bc3cb74SMauro Carvalho Chehab 		return ret;
20045bc3cb74SMauro Carvalho Chehab 	if (ops->vidioc_g_parm)
20055bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_g_parm(file, fh, p);
20065bc3cb74SMauro Carvalho Chehab 	if (p->type != V4L2_BUF_TYPE_VIDEO_CAPTURE &&
20075bc3cb74SMauro Carvalho Chehab 	    p->type != V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
20085bc3cb74SMauro Carvalho Chehab 		return -EINVAL;
20095bc3cb74SMauro Carvalho Chehab 	p->parm.capture.readbuffers = 2;
20105bc3cb74SMauro Carvalho Chehab 	ret = ops->vidioc_g_std(file, fh, &std);
20115bc3cb74SMauro Carvalho Chehab 	if (ret == 0)
2012ca371575SHans Verkuil 		v4l2_video_std_frame_period(std, &p->parm.capture.timeperframe);
20135bc3cb74SMauro Carvalho Chehab 	return ret;
20145bc3cb74SMauro Carvalho Chehab }
20155bc3cb74SMauro Carvalho Chehab 
20165bc3cb74SMauro Carvalho Chehab static int v4l_s_parm(const struct v4l2_ioctl_ops *ops,
20175bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
20185bc3cb74SMauro Carvalho Chehab {
20195bc3cb74SMauro Carvalho Chehab 	struct v4l2_streamparm *p = arg;
20204b20259fSHans Verkuil 	int ret = check_fmt(file, p->type);
20215bc3cb74SMauro Carvalho Chehab 
20228a7c5594SHans Verkuil 	if (ret)
20238a7c5594SHans Verkuil 		return ret;
20248a7c5594SHans Verkuil 
20258a7c5594SHans Verkuil 	/* Note: extendedmode is never used in drivers */
20268a7c5594SHans Verkuil 	if (V4L2_TYPE_IS_OUTPUT(p->type)) {
20278a7c5594SHans Verkuil 		memset(p->parm.output.reserved, 0,
20288a7c5594SHans Verkuil 		       sizeof(p->parm.output.reserved));
20298a7c5594SHans Verkuil 		p->parm.output.extendedmode = 0;
20308a7c5594SHans Verkuil 		p->parm.output.outputmode &= V4L2_MODE_HIGHQUALITY;
20318a7c5594SHans Verkuil 	} else {
20328a7c5594SHans Verkuil 		memset(p->parm.capture.reserved, 0,
20338a7c5594SHans Verkuil 		       sizeof(p->parm.capture.reserved));
20348a7c5594SHans Verkuil 		p->parm.capture.extendedmode = 0;
20358a7c5594SHans Verkuil 		p->parm.capture.capturemode &= V4L2_MODE_HIGHQUALITY;
20368a7c5594SHans Verkuil 	}
20378a7c5594SHans Verkuil 	return ops->vidioc_s_parm(file, fh, p);
20385bc3cb74SMauro Carvalho Chehab }
20395bc3cb74SMauro Carvalho Chehab 
20405bc3cb74SMauro Carvalho Chehab static int v4l_queryctrl(const struct v4l2_ioctl_ops *ops,
20415bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
20425bc3cb74SMauro Carvalho Chehab {
20435bc3cb74SMauro Carvalho Chehab 	struct video_device *vfd = video_devdata(file);
20445bc3cb74SMauro Carvalho Chehab 	struct v4l2_queryctrl *p = arg;
20455bc3cb74SMauro Carvalho Chehab 	struct v4l2_fh *vfh =
20465bc3cb74SMauro Carvalho Chehab 		test_bit(V4L2_FL_USES_V4L2_FH, &vfd->flags) ? fh : NULL;
20475bc3cb74SMauro Carvalho Chehab 
20485bc3cb74SMauro Carvalho Chehab 	if (vfh && vfh->ctrl_handler)
20495bc3cb74SMauro Carvalho Chehab 		return v4l2_queryctrl(vfh->ctrl_handler, p);
20505bc3cb74SMauro Carvalho Chehab 	if (vfd->ctrl_handler)
20515bc3cb74SMauro Carvalho Chehab 		return v4l2_queryctrl(vfd->ctrl_handler, p);
20525bc3cb74SMauro Carvalho Chehab 	if (ops->vidioc_queryctrl)
20535bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_queryctrl(file, fh, p);
20545bc3cb74SMauro Carvalho Chehab 	return -ENOTTY;
20555bc3cb74SMauro Carvalho Chehab }
20565bc3cb74SMauro Carvalho Chehab 
2057e6bee368SHans Verkuil static int v4l_query_ext_ctrl(const struct v4l2_ioctl_ops *ops,
2058e6bee368SHans Verkuil 				struct file *file, void *fh, void *arg)
2059e6bee368SHans Verkuil {
2060e6bee368SHans Verkuil 	struct video_device *vfd = video_devdata(file);
2061e6bee368SHans Verkuil 	struct v4l2_query_ext_ctrl *p = arg;
2062e6bee368SHans Verkuil 	struct v4l2_fh *vfh =
2063e6bee368SHans Verkuil 		test_bit(V4L2_FL_USES_V4L2_FH, &vfd->flags) ? fh : NULL;
2064e6bee368SHans Verkuil 
2065e6bee368SHans Verkuil 	if (vfh && vfh->ctrl_handler)
2066e6bee368SHans Verkuil 		return v4l2_query_ext_ctrl(vfh->ctrl_handler, p);
2067e6bee368SHans Verkuil 	if (vfd->ctrl_handler)
2068e6bee368SHans Verkuil 		return v4l2_query_ext_ctrl(vfd->ctrl_handler, p);
2069e6bee368SHans Verkuil 	if (ops->vidioc_query_ext_ctrl)
2070e6bee368SHans Verkuil 		return ops->vidioc_query_ext_ctrl(file, fh, p);
2071e6bee368SHans Verkuil 	return -ENOTTY;
2072e6bee368SHans Verkuil }
2073e6bee368SHans Verkuil 
20745bc3cb74SMauro Carvalho Chehab static int v4l_querymenu(const struct v4l2_ioctl_ops *ops,
20755bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
20765bc3cb74SMauro Carvalho Chehab {
20775bc3cb74SMauro Carvalho Chehab 	struct video_device *vfd = video_devdata(file);
20785bc3cb74SMauro Carvalho Chehab 	struct v4l2_querymenu *p = arg;
20795bc3cb74SMauro Carvalho Chehab 	struct v4l2_fh *vfh =
20805bc3cb74SMauro Carvalho Chehab 		test_bit(V4L2_FL_USES_V4L2_FH, &vfd->flags) ? fh : NULL;
20815bc3cb74SMauro Carvalho Chehab 
20825bc3cb74SMauro Carvalho Chehab 	if (vfh && vfh->ctrl_handler)
20835bc3cb74SMauro Carvalho Chehab 		return v4l2_querymenu(vfh->ctrl_handler, p);
20845bc3cb74SMauro Carvalho Chehab 	if (vfd->ctrl_handler)
20855bc3cb74SMauro Carvalho Chehab 		return v4l2_querymenu(vfd->ctrl_handler, p);
20865bc3cb74SMauro Carvalho Chehab 	if (ops->vidioc_querymenu)
20875bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_querymenu(file, fh, p);
20885bc3cb74SMauro Carvalho Chehab 	return -ENOTTY;
20895bc3cb74SMauro Carvalho Chehab }
20905bc3cb74SMauro Carvalho Chehab 
20915bc3cb74SMauro Carvalho Chehab static int v4l_g_ctrl(const struct v4l2_ioctl_ops *ops,
20925bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
20935bc3cb74SMauro Carvalho Chehab {
20945bc3cb74SMauro Carvalho Chehab 	struct video_device *vfd = video_devdata(file);
20955bc3cb74SMauro Carvalho Chehab 	struct v4l2_control *p = arg;
20965bc3cb74SMauro Carvalho Chehab 	struct v4l2_fh *vfh =
20975bc3cb74SMauro Carvalho Chehab 		test_bit(V4L2_FL_USES_V4L2_FH, &vfd->flags) ? fh : NULL;
20985bc3cb74SMauro Carvalho Chehab 	struct v4l2_ext_controls ctrls;
20995bc3cb74SMauro Carvalho Chehab 	struct v4l2_ext_control ctrl;
21005bc3cb74SMauro Carvalho Chehab 
21015bc3cb74SMauro Carvalho Chehab 	if (vfh && vfh->ctrl_handler)
21025bc3cb74SMauro Carvalho Chehab 		return v4l2_g_ctrl(vfh->ctrl_handler, p);
21035bc3cb74SMauro Carvalho Chehab 	if (vfd->ctrl_handler)
21045bc3cb74SMauro Carvalho Chehab 		return v4l2_g_ctrl(vfd->ctrl_handler, p);
21055bc3cb74SMauro Carvalho Chehab 	if (ops->vidioc_g_ctrl)
21065bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_g_ctrl(file, fh, p);
21075bc3cb74SMauro Carvalho Chehab 	if (ops->vidioc_g_ext_ctrls == NULL)
21085bc3cb74SMauro Carvalho Chehab 		return -ENOTTY;
21095bc3cb74SMauro Carvalho Chehab 
21100f8017beSRicardo Ribalda 	ctrls.which = V4L2_CTRL_ID2WHICH(p->id);
21115bc3cb74SMauro Carvalho Chehab 	ctrls.count = 1;
21125bc3cb74SMauro Carvalho Chehab 	ctrls.controls = &ctrl;
21135bc3cb74SMauro Carvalho Chehab 	ctrl.id = p->id;
21145bc3cb74SMauro Carvalho Chehab 	ctrl.value = p->value;
21155bc3cb74SMauro Carvalho Chehab 	if (check_ext_ctrls(&ctrls, 1)) {
21165bc3cb74SMauro Carvalho Chehab 		int ret = ops->vidioc_g_ext_ctrls(file, fh, &ctrls);
21175bc3cb74SMauro Carvalho Chehab 
21185bc3cb74SMauro Carvalho Chehab 		if (ret == 0)
21195bc3cb74SMauro Carvalho Chehab 			p->value = ctrl.value;
21205bc3cb74SMauro Carvalho Chehab 		return ret;
21215bc3cb74SMauro Carvalho Chehab 	}
21225bc3cb74SMauro Carvalho Chehab 	return -EINVAL;
21235bc3cb74SMauro Carvalho Chehab }
21245bc3cb74SMauro Carvalho Chehab 
21255bc3cb74SMauro Carvalho Chehab static int v4l_s_ctrl(const struct v4l2_ioctl_ops *ops,
21265bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
21275bc3cb74SMauro Carvalho Chehab {
21285bc3cb74SMauro Carvalho Chehab 	struct video_device *vfd = video_devdata(file);
21295bc3cb74SMauro Carvalho Chehab 	struct v4l2_control *p = arg;
21305bc3cb74SMauro Carvalho Chehab 	struct v4l2_fh *vfh =
21315bc3cb74SMauro Carvalho Chehab 		test_bit(V4L2_FL_USES_V4L2_FH, &vfd->flags) ? fh : NULL;
21325bc3cb74SMauro Carvalho Chehab 	struct v4l2_ext_controls ctrls;
21335bc3cb74SMauro Carvalho Chehab 	struct v4l2_ext_control ctrl;
21345bc3cb74SMauro Carvalho Chehab 
21355bc3cb74SMauro Carvalho Chehab 	if (vfh && vfh->ctrl_handler)
21365bc3cb74SMauro Carvalho Chehab 		return v4l2_s_ctrl(vfh, vfh->ctrl_handler, p);
21375bc3cb74SMauro Carvalho Chehab 	if (vfd->ctrl_handler)
21385bc3cb74SMauro Carvalho Chehab 		return v4l2_s_ctrl(NULL, vfd->ctrl_handler, p);
21395bc3cb74SMauro Carvalho Chehab 	if (ops->vidioc_s_ctrl)
21405bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_s_ctrl(file, fh, p);
21415bc3cb74SMauro Carvalho Chehab 	if (ops->vidioc_s_ext_ctrls == NULL)
21425bc3cb74SMauro Carvalho Chehab 		return -ENOTTY;
21435bc3cb74SMauro Carvalho Chehab 
21440f8017beSRicardo Ribalda 	ctrls.which = V4L2_CTRL_ID2WHICH(p->id);
21455bc3cb74SMauro Carvalho Chehab 	ctrls.count = 1;
21465bc3cb74SMauro Carvalho Chehab 	ctrls.controls = &ctrl;
21475bc3cb74SMauro Carvalho Chehab 	ctrl.id = p->id;
21485bc3cb74SMauro Carvalho Chehab 	ctrl.value = p->value;
21495bc3cb74SMauro Carvalho Chehab 	if (check_ext_ctrls(&ctrls, 1))
21505bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_s_ext_ctrls(file, fh, &ctrls);
21515bc3cb74SMauro Carvalho Chehab 	return -EINVAL;
21525bc3cb74SMauro Carvalho Chehab }
21535bc3cb74SMauro Carvalho Chehab 
21545bc3cb74SMauro Carvalho Chehab static int v4l_g_ext_ctrls(const struct v4l2_ioctl_ops *ops,
21555bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
21565bc3cb74SMauro Carvalho Chehab {
21575bc3cb74SMauro Carvalho Chehab 	struct video_device *vfd = video_devdata(file);
21585bc3cb74SMauro Carvalho Chehab 	struct v4l2_ext_controls *p = arg;
21595bc3cb74SMauro Carvalho Chehab 	struct v4l2_fh *vfh =
21605bc3cb74SMauro Carvalho Chehab 		test_bit(V4L2_FL_USES_V4L2_FH, &vfd->flags) ? fh : NULL;
21615bc3cb74SMauro Carvalho Chehab 
21625bc3cb74SMauro Carvalho Chehab 	p->error_idx = p->count;
21635bc3cb74SMauro Carvalho Chehab 	if (vfh && vfh->ctrl_handler)
2164c41e9cffSHans Verkuil 		return v4l2_g_ext_ctrls(vfh->ctrl_handler, vfd->v4l2_dev->mdev, p);
21655bc3cb74SMauro Carvalho Chehab 	if (vfd->ctrl_handler)
2166c41e9cffSHans Verkuil 		return v4l2_g_ext_ctrls(vfd->ctrl_handler, vfd->v4l2_dev->mdev, p);
21675bc3cb74SMauro Carvalho Chehab 	if (ops->vidioc_g_ext_ctrls == NULL)
21685bc3cb74SMauro Carvalho Chehab 		return -ENOTTY;
21695bc3cb74SMauro Carvalho Chehab 	return check_ext_ctrls(p, 0) ? ops->vidioc_g_ext_ctrls(file, fh, p) :
21705bc3cb74SMauro Carvalho Chehab 					-EINVAL;
21715bc3cb74SMauro Carvalho Chehab }
21725bc3cb74SMauro Carvalho Chehab 
21735bc3cb74SMauro Carvalho Chehab static int v4l_s_ext_ctrls(const struct v4l2_ioctl_ops *ops,
21745bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
21755bc3cb74SMauro Carvalho Chehab {
21765bc3cb74SMauro Carvalho Chehab 	struct video_device *vfd = video_devdata(file);
21775bc3cb74SMauro Carvalho Chehab 	struct v4l2_ext_controls *p = arg;
21785bc3cb74SMauro Carvalho Chehab 	struct v4l2_fh *vfh =
21795bc3cb74SMauro Carvalho Chehab 		test_bit(V4L2_FL_USES_V4L2_FH, &vfd->flags) ? fh : NULL;
21805bc3cb74SMauro Carvalho Chehab 
21815bc3cb74SMauro Carvalho Chehab 	p->error_idx = p->count;
21825bc3cb74SMauro Carvalho Chehab 	if (vfh && vfh->ctrl_handler)
2183c41e9cffSHans Verkuil 		return v4l2_s_ext_ctrls(vfh, vfh->ctrl_handler, vfd->v4l2_dev->mdev, p);
21845bc3cb74SMauro Carvalho Chehab 	if (vfd->ctrl_handler)
2185c41e9cffSHans Verkuil 		return v4l2_s_ext_ctrls(NULL, vfd->ctrl_handler, vfd->v4l2_dev->mdev, p);
21865bc3cb74SMauro Carvalho Chehab 	if (ops->vidioc_s_ext_ctrls == NULL)
21875bc3cb74SMauro Carvalho Chehab 		return -ENOTTY;
21885bc3cb74SMauro Carvalho Chehab 	return check_ext_ctrls(p, 0) ? ops->vidioc_s_ext_ctrls(file, fh, p) :
21895bc3cb74SMauro Carvalho Chehab 					-EINVAL;
21905bc3cb74SMauro Carvalho Chehab }
21915bc3cb74SMauro Carvalho Chehab 
21925bc3cb74SMauro Carvalho Chehab static int v4l_try_ext_ctrls(const struct v4l2_ioctl_ops *ops,
21935bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
21945bc3cb74SMauro Carvalho Chehab {
21955bc3cb74SMauro Carvalho Chehab 	struct video_device *vfd = video_devdata(file);
21965bc3cb74SMauro Carvalho Chehab 	struct v4l2_ext_controls *p = arg;
21975bc3cb74SMauro Carvalho Chehab 	struct v4l2_fh *vfh =
21985bc3cb74SMauro Carvalho Chehab 		test_bit(V4L2_FL_USES_V4L2_FH, &vfd->flags) ? fh : NULL;
21995bc3cb74SMauro Carvalho Chehab 
22005bc3cb74SMauro Carvalho Chehab 	p->error_idx = p->count;
22015bc3cb74SMauro Carvalho Chehab 	if (vfh && vfh->ctrl_handler)
2202c41e9cffSHans Verkuil 		return v4l2_try_ext_ctrls(vfh->ctrl_handler, vfd->v4l2_dev->mdev, p);
22035bc3cb74SMauro Carvalho Chehab 	if (vfd->ctrl_handler)
2204c41e9cffSHans Verkuil 		return v4l2_try_ext_ctrls(vfd->ctrl_handler, vfd->v4l2_dev->mdev, p);
22055bc3cb74SMauro Carvalho Chehab 	if (ops->vidioc_try_ext_ctrls == NULL)
22065bc3cb74SMauro Carvalho Chehab 		return -ENOTTY;
22075bc3cb74SMauro Carvalho Chehab 	return check_ext_ctrls(p, 0) ? ops->vidioc_try_ext_ctrls(file, fh, p) :
22085bc3cb74SMauro Carvalho Chehab 					-EINVAL;
22095bc3cb74SMauro Carvalho Chehab }
22105bc3cb74SMauro Carvalho Chehab 
2211eaec420fSHans Verkuil /*
2212eaec420fSHans Verkuil  * The selection API specified originally that the _MPLANE buffer types
2213eaec420fSHans Verkuil  * shouldn't be used. The reasons for this are lost in the mists of time
2214eaec420fSHans Verkuil  * (or just really crappy memories). Regardless, this is really annoying
2215eaec420fSHans Verkuil  * for userspace. So to keep things simple we map _MPLANE buffer types
2216eaec420fSHans Verkuil  * to their 'regular' counterparts before calling the driver. And we
2217eaec420fSHans Verkuil  * restore it afterwards. This way applications can use either buffer
2218eaec420fSHans Verkuil  * type and drivers don't need to check for both.
2219eaec420fSHans Verkuil  */
2220eaec420fSHans Verkuil static int v4l_g_selection(const struct v4l2_ioctl_ops *ops,
2221eaec420fSHans Verkuil 			   struct file *file, void *fh, void *arg)
2222eaec420fSHans Verkuil {
2223eaec420fSHans Verkuil 	struct v4l2_selection *p = arg;
2224eaec420fSHans Verkuil 	u32 old_type = p->type;
2225eaec420fSHans Verkuil 	int ret;
2226eaec420fSHans Verkuil 
2227eaec420fSHans Verkuil 	if (p->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
2228eaec420fSHans Verkuil 		p->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
2229eaec420fSHans Verkuil 	else if (p->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)
2230eaec420fSHans Verkuil 		p->type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
2231eaec420fSHans Verkuil 	ret = ops->vidioc_g_selection(file, fh, p);
2232eaec420fSHans Verkuil 	p->type = old_type;
2233eaec420fSHans Verkuil 	return ret;
2234eaec420fSHans Verkuil }
2235eaec420fSHans Verkuil 
2236eaec420fSHans Verkuil static int v4l_s_selection(const struct v4l2_ioctl_ops *ops,
2237eaec420fSHans Verkuil 			   struct file *file, void *fh, void *arg)
2238eaec420fSHans Verkuil {
2239eaec420fSHans Verkuil 	struct v4l2_selection *p = arg;
2240eaec420fSHans Verkuil 	u32 old_type = p->type;
2241eaec420fSHans Verkuil 	int ret;
2242eaec420fSHans Verkuil 
2243eaec420fSHans Verkuil 	if (p->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
2244eaec420fSHans Verkuil 		p->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
2245eaec420fSHans Verkuil 	else if (p->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)
2246eaec420fSHans Verkuil 		p->type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
2247eaec420fSHans Verkuil 	ret = ops->vidioc_s_selection(file, fh, p);
2248eaec420fSHans Verkuil 	p->type = old_type;
2249eaec420fSHans Verkuil 	return ret;
2250eaec420fSHans Verkuil }
2251eaec420fSHans Verkuil 
22525bc3cb74SMauro Carvalho Chehab static int v4l_g_crop(const struct v4l2_ioctl_ops *ops,
22535bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
22545bc3cb74SMauro Carvalho Chehab {
22558cbd94bdSHans Verkuil 	struct video_device *vfd = video_devdata(file);
22565bc3cb74SMauro Carvalho Chehab 	struct v4l2_crop *p = arg;
22575bc3cb74SMauro Carvalho Chehab 	struct v4l2_selection s = {
22585bc3cb74SMauro Carvalho Chehab 		.type = p->type,
22595bc3cb74SMauro Carvalho Chehab 	};
22605bc3cb74SMauro Carvalho Chehab 	int ret;
22615bc3cb74SMauro Carvalho Chehab 
22625bc3cb74SMauro Carvalho Chehab 	/* simulate capture crop using selection api */
22635bc3cb74SMauro Carvalho Chehab 
22645bc3cb74SMauro Carvalho Chehab 	/* crop means compose for output devices */
22655bc3cb74SMauro Carvalho Chehab 	if (V4L2_TYPE_IS_OUTPUT(p->type))
22665b79da06SHans Verkuil 		s.target = V4L2_SEL_TGT_COMPOSE;
22675bc3cb74SMauro Carvalho Chehab 	else
22685b79da06SHans Verkuil 		s.target = V4L2_SEL_TGT_CROP;
22695bc3cb74SMauro Carvalho Chehab 
22708cbd94bdSHans Verkuil 	if (test_bit(V4L2_FL_QUIRK_INVERTED_CROP, &vfd->flags))
22718cbd94bdSHans Verkuil 		s.target = s.target == V4L2_SEL_TGT_COMPOSE ?
22728cbd94bdSHans Verkuil 			V4L2_SEL_TGT_CROP : V4L2_SEL_TGT_COMPOSE;
22738cbd94bdSHans Verkuil 
2274eaec420fSHans Verkuil 	ret = v4l_g_selection(ops, file, fh, &s);
22755bc3cb74SMauro Carvalho Chehab 
22765bc3cb74SMauro Carvalho Chehab 	/* copying results to old structure on success */
22775bc3cb74SMauro Carvalho Chehab 	if (!ret)
22785bc3cb74SMauro Carvalho Chehab 		p->c = s.r;
22795bc3cb74SMauro Carvalho Chehab 	return ret;
22805bc3cb74SMauro Carvalho Chehab }
22815bc3cb74SMauro Carvalho Chehab 
22825bc3cb74SMauro Carvalho Chehab static int v4l_s_crop(const struct v4l2_ioctl_ops *ops,
22835bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
22845bc3cb74SMauro Carvalho Chehab {
22858cbd94bdSHans Verkuil 	struct video_device *vfd = video_devdata(file);
22865bc3cb74SMauro Carvalho Chehab 	struct v4l2_crop *p = arg;
22875bc3cb74SMauro Carvalho Chehab 	struct v4l2_selection s = {
22885bc3cb74SMauro Carvalho Chehab 		.type = p->type,
22895bc3cb74SMauro Carvalho Chehab 		.r = p->c,
22905bc3cb74SMauro Carvalho Chehab 	};
22915bc3cb74SMauro Carvalho Chehab 
22925bc3cb74SMauro Carvalho Chehab 	/* simulate capture crop using selection api */
22935bc3cb74SMauro Carvalho Chehab 
22945bc3cb74SMauro Carvalho Chehab 	/* crop means compose for output devices */
22955bc3cb74SMauro Carvalho Chehab 	if (V4L2_TYPE_IS_OUTPUT(p->type))
22965b79da06SHans Verkuil 		s.target = V4L2_SEL_TGT_COMPOSE;
22975bc3cb74SMauro Carvalho Chehab 	else
22985b79da06SHans Verkuil 		s.target = V4L2_SEL_TGT_CROP;
22995bc3cb74SMauro Carvalho Chehab 
23008cbd94bdSHans Verkuil 	if (test_bit(V4L2_FL_QUIRK_INVERTED_CROP, &vfd->flags))
23018cbd94bdSHans Verkuil 		s.target = s.target == V4L2_SEL_TGT_COMPOSE ?
23028cbd94bdSHans Verkuil 			V4L2_SEL_TGT_CROP : V4L2_SEL_TGT_COMPOSE;
23038cbd94bdSHans Verkuil 
2304eaec420fSHans Verkuil 	return v4l_s_selection(ops, file, fh, &s);
23055bc3cb74SMauro Carvalho Chehab }
23065bc3cb74SMauro Carvalho Chehab 
23075bc3cb74SMauro Carvalho Chehab static int v4l_cropcap(const struct v4l2_ioctl_ops *ops,
23085bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
23095bc3cb74SMauro Carvalho Chehab {
23108cbd94bdSHans Verkuil 	struct video_device *vfd = video_devdata(file);
23115bc3cb74SMauro Carvalho Chehab 	struct v4l2_cropcap *p = arg;
23125bc3cb74SMauro Carvalho Chehab 	struct v4l2_selection s = { .type = p->type };
231395dd7b7eSHans Verkuil 	int ret = 0;
231495dd7b7eSHans Verkuil 
231595dd7b7eSHans Verkuil 	/* setting trivial pixelaspect */
231695dd7b7eSHans Verkuil 	p->pixelaspect.numerator = 1;
231795dd7b7eSHans Verkuil 	p->pixelaspect.denominator = 1;
231895dd7b7eSHans Verkuil 
23195200ab6aSHans Verkuil 	if (s.type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
23205200ab6aSHans Verkuil 		s.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
23215200ab6aSHans Verkuil 	else if (s.type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)
23225200ab6aSHans Verkuil 		s.type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
23235200ab6aSHans Verkuil 
232495dd7b7eSHans Verkuil 	/*
232595dd7b7eSHans Verkuil 	 * The determine_valid_ioctls() call already should ensure
232695dd7b7eSHans Verkuil 	 * that this can never happen, but just in case...
232795dd7b7eSHans Verkuil 	 */
23285200ab6aSHans Verkuil 	if (WARN_ON(!ops->vidioc_g_selection))
232995dd7b7eSHans Verkuil 		return -ENOTTY;
233095dd7b7eSHans Verkuil 
23315200ab6aSHans Verkuil 	if (ops->vidioc_g_pixelaspect)
23325200ab6aSHans Verkuil 		ret = ops->vidioc_g_pixelaspect(file, fh, s.type,
23335200ab6aSHans Verkuil 						&p->pixelaspect);
233495dd7b7eSHans Verkuil 
233595dd7b7eSHans Verkuil 	/*
233695dd7b7eSHans Verkuil 	 * Ignore ENOTTY or ENOIOCTLCMD error returns, just use the
233795dd7b7eSHans Verkuil 	 * square pixel aspect ratio in that case.
233895dd7b7eSHans Verkuil 	 */
233995dd7b7eSHans Verkuil 	if (ret && ret != -ENOTTY && ret != -ENOIOCTLCMD)
234095dd7b7eSHans Verkuil 		return ret;
234195dd7b7eSHans Verkuil 
234295dd7b7eSHans Verkuil 	/* Use g_selection() to fill in the bounds and defrect rectangles */
23435bc3cb74SMauro Carvalho Chehab 
23445bc3cb74SMauro Carvalho Chehab 	/* obtaining bounds */
23455bc3cb74SMauro Carvalho Chehab 	if (V4L2_TYPE_IS_OUTPUT(p->type))
23465bc3cb74SMauro Carvalho Chehab 		s.target = V4L2_SEL_TGT_COMPOSE_BOUNDS;
23475bc3cb74SMauro Carvalho Chehab 	else
23485bc3cb74SMauro Carvalho Chehab 		s.target = V4L2_SEL_TGT_CROP_BOUNDS;
23495bc3cb74SMauro Carvalho Chehab 
23508cbd94bdSHans Verkuil 	if (test_bit(V4L2_FL_QUIRK_INVERTED_CROP, &vfd->flags))
23518cbd94bdSHans Verkuil 		s.target = s.target == V4L2_SEL_TGT_COMPOSE_BOUNDS ?
23528cbd94bdSHans Verkuil 			V4L2_SEL_TGT_CROP_BOUNDS : V4L2_SEL_TGT_COMPOSE_BOUNDS;
23538cbd94bdSHans Verkuil 
2354eaec420fSHans Verkuil 	ret = v4l_g_selection(ops, file, fh, &s);
23555bc3cb74SMauro Carvalho Chehab 	if (ret)
23565bc3cb74SMauro Carvalho Chehab 		return ret;
23575bc3cb74SMauro Carvalho Chehab 	p->bounds = s.r;
23585bc3cb74SMauro Carvalho Chehab 
23595bc3cb74SMauro Carvalho Chehab 	/* obtaining defrect */
23608cbd94bdSHans Verkuil 	if (s.target == V4L2_SEL_TGT_COMPOSE_BOUNDS)
23615bc3cb74SMauro Carvalho Chehab 		s.target = V4L2_SEL_TGT_COMPOSE_DEFAULT;
23625bc3cb74SMauro Carvalho Chehab 	else
23635bc3cb74SMauro Carvalho Chehab 		s.target = V4L2_SEL_TGT_CROP_DEFAULT;
23645bc3cb74SMauro Carvalho Chehab 
2365eaec420fSHans Verkuil 	ret = v4l_g_selection(ops, file, fh, &s);
23665bc3cb74SMauro Carvalho Chehab 	if (ret)
23675bc3cb74SMauro Carvalho Chehab 		return ret;
23685bc3cb74SMauro Carvalho Chehab 	p->defrect = s.r;
23699409945cSHans Verkuil 
23705bc3cb74SMauro Carvalho Chehab 	return 0;
23715bc3cb74SMauro Carvalho Chehab }
23725bc3cb74SMauro Carvalho Chehab 
23735bc3cb74SMauro Carvalho Chehab static int v4l_log_status(const struct v4l2_ioctl_ops *ops,
23745bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
23755bc3cb74SMauro Carvalho Chehab {
23765bc3cb74SMauro Carvalho Chehab 	struct video_device *vfd = video_devdata(file);
23775bc3cb74SMauro Carvalho Chehab 	int ret;
23785bc3cb74SMauro Carvalho Chehab 
23795bc3cb74SMauro Carvalho Chehab 	if (vfd->v4l2_dev)
23805bc3cb74SMauro Carvalho Chehab 		pr_info("%s: =================  START STATUS  =================\n",
23815bc3cb74SMauro Carvalho Chehab 			vfd->v4l2_dev->name);
23825bc3cb74SMauro Carvalho Chehab 	ret = ops->vidioc_log_status(file, fh);
23835bc3cb74SMauro Carvalho Chehab 	if (vfd->v4l2_dev)
23845bc3cb74SMauro Carvalho Chehab 		pr_info("%s: ==================  END STATUS  ==================\n",
23855bc3cb74SMauro Carvalho Chehab 			vfd->v4l2_dev->name);
23865bc3cb74SMauro Carvalho Chehab 	return ret;
23875bc3cb74SMauro Carvalho Chehab }
23885bc3cb74SMauro Carvalho Chehab 
23895bc3cb74SMauro Carvalho Chehab static int v4l_dbg_g_register(const struct v4l2_ioctl_ops *ops,
23905bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
23915bc3cb74SMauro Carvalho Chehab {
23925bc3cb74SMauro Carvalho Chehab #ifdef CONFIG_VIDEO_ADV_DEBUG
23935bc3cb74SMauro Carvalho Chehab 	struct v4l2_dbg_register *p = arg;
239479b0c640SHans Verkuil 	struct video_device *vfd = video_devdata(file);
239579b0c640SHans Verkuil 	struct v4l2_subdev *sd;
239679b0c640SHans Verkuil 	int idx = 0;
23975bc3cb74SMauro Carvalho Chehab 
23985bc3cb74SMauro Carvalho Chehab 	if (!capable(CAP_SYS_ADMIN))
23995bc3cb74SMauro Carvalho Chehab 		return -EPERM;
24003eef2510SHans Verkuil 	if (p->match.type == V4L2_CHIP_MATCH_SUBDEV) {
240179b0c640SHans Verkuil 		if (vfd->v4l2_dev == NULL)
240279b0c640SHans Verkuil 			return -EINVAL;
24033eef2510SHans Verkuil 		v4l2_device_for_each_subdev(sd, vfd->v4l2_dev)
24043eef2510SHans Verkuil 			if (p->match.addr == idx++)
240579b0c640SHans Verkuil 				return v4l2_subdev_call(sd, core, g_register, p);
240679b0c640SHans Verkuil 		return -EINVAL;
240779b0c640SHans Verkuil 	}
2408191b79b0SHans Verkuil 	if (ops->vidioc_g_register && p->match.type == V4L2_CHIP_MATCH_BRIDGE &&
2409191b79b0SHans Verkuil 	    (ops->vidioc_g_chip_info || p->match.addr == 0))
24105bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_g_register(file, fh, p);
241179b0c640SHans Verkuil 	return -EINVAL;
24125bc3cb74SMauro Carvalho Chehab #else
24135bc3cb74SMauro Carvalho Chehab 	return -ENOTTY;
24145bc3cb74SMauro Carvalho Chehab #endif
24155bc3cb74SMauro Carvalho Chehab }
24165bc3cb74SMauro Carvalho Chehab 
24175bc3cb74SMauro Carvalho Chehab static int v4l_dbg_s_register(const struct v4l2_ioctl_ops *ops,
24185bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
24195bc3cb74SMauro Carvalho Chehab {
24205bc3cb74SMauro Carvalho Chehab #ifdef CONFIG_VIDEO_ADV_DEBUG
2421977ba3b1SHans Verkuil 	const struct v4l2_dbg_register *p = arg;
242279b0c640SHans Verkuil 	struct video_device *vfd = video_devdata(file);
242379b0c640SHans Verkuil 	struct v4l2_subdev *sd;
242479b0c640SHans Verkuil 	int idx = 0;
24255bc3cb74SMauro Carvalho Chehab 
24265bc3cb74SMauro Carvalho Chehab 	if (!capable(CAP_SYS_ADMIN))
24275bc3cb74SMauro Carvalho Chehab 		return -EPERM;
24283eef2510SHans Verkuil 	if (p->match.type == V4L2_CHIP_MATCH_SUBDEV) {
242979b0c640SHans Verkuil 		if (vfd->v4l2_dev == NULL)
243079b0c640SHans Verkuil 			return -EINVAL;
24313eef2510SHans Verkuil 		v4l2_device_for_each_subdev(sd, vfd->v4l2_dev)
24323eef2510SHans Verkuil 			if (p->match.addr == idx++)
243379b0c640SHans Verkuil 				return v4l2_subdev_call(sd, core, s_register, p);
243479b0c640SHans Verkuil 		return -EINVAL;
243579b0c640SHans Verkuil 	}
2436191b79b0SHans Verkuil 	if (ops->vidioc_s_register && p->match.type == V4L2_CHIP_MATCH_BRIDGE &&
2437191b79b0SHans Verkuil 	    (ops->vidioc_g_chip_info || p->match.addr == 0))
24385bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_s_register(file, fh, p);
243979b0c640SHans Verkuil 	return -EINVAL;
24405bc3cb74SMauro Carvalho Chehab #else
24415bc3cb74SMauro Carvalho Chehab 	return -ENOTTY;
24425bc3cb74SMauro Carvalho Chehab #endif
24435bc3cb74SMauro Carvalho Chehab }
24445bc3cb74SMauro Carvalho Chehab 
244596b03d2aSHans Verkuil static int v4l_dbg_g_chip_info(const struct v4l2_ioctl_ops *ops,
244679b0c640SHans Verkuil 				struct file *file, void *fh, void *arg)
244779b0c640SHans Verkuil {
2448cd634f1bSHans Verkuil #ifdef CONFIG_VIDEO_ADV_DEBUG
244979b0c640SHans Verkuil 	struct video_device *vfd = video_devdata(file);
245096b03d2aSHans Verkuil 	struct v4l2_dbg_chip_info *p = arg;
245179b0c640SHans Verkuil 	struct v4l2_subdev *sd;
245279b0c640SHans Verkuil 	int idx = 0;
245379b0c640SHans Verkuil 
245479b0c640SHans Verkuil 	switch (p->match.type) {
245579b0c640SHans Verkuil 	case V4L2_CHIP_MATCH_BRIDGE:
245679b0c640SHans Verkuil 		if (ops->vidioc_s_register)
245779b0c640SHans Verkuil 			p->flags |= V4L2_CHIP_FL_WRITABLE;
245879b0c640SHans Verkuil 		if (ops->vidioc_g_register)
245979b0c640SHans Verkuil 			p->flags |= V4L2_CHIP_FL_READABLE;
2460c0decac1SMauro Carvalho Chehab 		strscpy(p->name, vfd->v4l2_dev->name, sizeof(p->name));
246196b03d2aSHans Verkuil 		if (ops->vidioc_g_chip_info)
246296b03d2aSHans Verkuil 			return ops->vidioc_g_chip_info(file, fh, arg);
24630f0fe4b9SHans Verkuil 		if (p->match.addr)
24640f0fe4b9SHans Verkuil 			return -EINVAL;
246579b0c640SHans Verkuil 		return 0;
246679b0c640SHans Verkuil 
24673eef2510SHans Verkuil 	case V4L2_CHIP_MATCH_SUBDEV:
246879b0c640SHans Verkuil 		if (vfd->v4l2_dev == NULL)
246979b0c640SHans Verkuil 			break;
247079b0c640SHans Verkuil 		v4l2_device_for_each_subdev(sd, vfd->v4l2_dev) {
24713eef2510SHans Verkuil 			if (p->match.addr != idx++)
24723eef2510SHans Verkuil 				continue;
247379b0c640SHans Verkuil 			if (sd->ops->core && sd->ops->core->s_register)
247479b0c640SHans Verkuil 				p->flags |= V4L2_CHIP_FL_WRITABLE;
247579b0c640SHans Verkuil 			if (sd->ops->core && sd->ops->core->g_register)
247679b0c640SHans Verkuil 				p->flags |= V4L2_CHIP_FL_READABLE;
2477c0decac1SMauro Carvalho Chehab 			strscpy(p->name, sd->name, sizeof(p->name));
247879b0c640SHans Verkuil 			return 0;
247979b0c640SHans Verkuil 		}
248079b0c640SHans Verkuil 		break;
248179b0c640SHans Verkuil 	}
248279b0c640SHans Verkuil 	return -EINVAL;
2483cd634f1bSHans Verkuil #else
2484cd634f1bSHans Verkuil 	return -ENOTTY;
2485cd634f1bSHans Verkuil #endif
248679b0c640SHans Verkuil }
248779b0c640SHans Verkuil 
24885bc3cb74SMauro Carvalho Chehab static int v4l_dqevent(const struct v4l2_ioctl_ops *ops,
24895bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
24905bc3cb74SMauro Carvalho Chehab {
24915bc3cb74SMauro Carvalho Chehab 	return v4l2_event_dequeue(fh, arg, file->f_flags & O_NONBLOCK);
24925bc3cb74SMauro Carvalho Chehab }
24935bc3cb74SMauro Carvalho Chehab 
24945bc3cb74SMauro Carvalho Chehab static int v4l_subscribe_event(const struct v4l2_ioctl_ops *ops,
24955bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
24965bc3cb74SMauro Carvalho Chehab {
24975bc3cb74SMauro Carvalho Chehab 	return ops->vidioc_subscribe_event(fh, arg);
24985bc3cb74SMauro Carvalho Chehab }
24995bc3cb74SMauro Carvalho Chehab 
25005bc3cb74SMauro Carvalho Chehab static int v4l_unsubscribe_event(const struct v4l2_ioctl_ops *ops,
25015bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
25025bc3cb74SMauro Carvalho Chehab {
25035bc3cb74SMauro Carvalho Chehab 	return ops->vidioc_unsubscribe_event(fh, arg);
25045bc3cb74SMauro Carvalho Chehab }
25055bc3cb74SMauro Carvalho Chehab 
25065bc3cb74SMauro Carvalho Chehab static int v4l_g_sliced_vbi_cap(const struct v4l2_ioctl_ops *ops,
25075bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
25085bc3cb74SMauro Carvalho Chehab {
25095bc3cb74SMauro Carvalho Chehab 	struct v4l2_sliced_vbi_cap *p = arg;
25104b20259fSHans Verkuil 	int ret = check_fmt(file, p->type);
25114b20259fSHans Verkuil 
25124b20259fSHans Verkuil 	if (ret)
25134b20259fSHans Verkuil 		return ret;
25145bc3cb74SMauro Carvalho Chehab 
25155bc3cb74SMauro Carvalho Chehab 	/* Clear up to type, everything after type is zeroed already */
25165bc3cb74SMauro Carvalho Chehab 	memset(p, 0, offsetof(struct v4l2_sliced_vbi_cap, type));
25175bc3cb74SMauro Carvalho Chehab 
25185bc3cb74SMauro Carvalho Chehab 	return ops->vidioc_g_sliced_vbi_cap(file, fh, p);
25195bc3cb74SMauro Carvalho Chehab }
25205bc3cb74SMauro Carvalho Chehab 
25215bc3cb74SMauro Carvalho Chehab static int v4l_enum_freq_bands(const struct v4l2_ioctl_ops *ops,
25225bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
25235bc3cb74SMauro Carvalho Chehab {
25245bc3cb74SMauro Carvalho Chehab 	struct video_device *vfd = video_devdata(file);
25255bc3cb74SMauro Carvalho Chehab 	struct v4l2_frequency_band *p = arg;
25265bc3cb74SMauro Carvalho Chehab 	enum v4l2_tuner_type type;
25275bc3cb74SMauro Carvalho Chehab 	int err;
25285bc3cb74SMauro Carvalho Chehab 
252984099a28SAntti Palosaari 	if (vfd->vfl_type == VFL_TYPE_SDR) {
2530f3c3ececSAntti Palosaari 		if (p->type != V4L2_TUNER_SDR && p->type != V4L2_TUNER_RF)
253184099a28SAntti Palosaari 			return -EINVAL;
253284099a28SAntti Palosaari 		type = p->type;
253384099a28SAntti Palosaari 	} else {
25345bc3cb74SMauro Carvalho Chehab 		type = (vfd->vfl_type == VFL_TYPE_RADIO) ?
25355bc3cb74SMauro Carvalho Chehab 				V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV;
25365bc3cb74SMauro Carvalho Chehab 		if (type != p->type)
25375bc3cb74SMauro Carvalho Chehab 			return -EINVAL;
253884099a28SAntti Palosaari 	}
2539a7f404afSHans Verkuil 	if (ops->vidioc_enum_freq_bands) {
2540a7f404afSHans Verkuil 		err = ops->vidioc_enum_freq_bands(file, fh, p);
2541a7f404afSHans Verkuil 		if (err != -ENOTTY)
2542a7f404afSHans Verkuil 			return err;
2543a7f404afSHans Verkuil 	}
254473f35418SHans Verkuil 	if (is_valid_ioctl(vfd, VIDIOC_G_TUNER)) {
25455bc3cb74SMauro Carvalho Chehab 		struct v4l2_tuner t = {
25465bc3cb74SMauro Carvalho Chehab 			.index = p->tuner,
25475bc3cb74SMauro Carvalho Chehab 			.type = type,
25485bc3cb74SMauro Carvalho Chehab 		};
25495bc3cb74SMauro Carvalho Chehab 
255079e8c7beSMauro Carvalho Chehab 		if (p->index)
255179e8c7beSMauro Carvalho Chehab 			return -EINVAL;
25525bc3cb74SMauro Carvalho Chehab 		err = ops->vidioc_g_tuner(file, fh, &t);
25535bc3cb74SMauro Carvalho Chehab 		if (err)
25545bc3cb74SMauro Carvalho Chehab 			return err;
25555bc3cb74SMauro Carvalho Chehab 		p->capability = t.capability | V4L2_TUNER_CAP_FREQ_BANDS;
25565bc3cb74SMauro Carvalho Chehab 		p->rangelow = t.rangelow;
25575bc3cb74SMauro Carvalho Chehab 		p->rangehigh = t.rangehigh;
25585bc3cb74SMauro Carvalho Chehab 		p->modulation = (type == V4L2_TUNER_RADIO) ?
25595bc3cb74SMauro Carvalho Chehab 			V4L2_BAND_MODULATION_FM : V4L2_BAND_MODULATION_VSB;
25605bc3cb74SMauro Carvalho Chehab 		return 0;
25615bc3cb74SMauro Carvalho Chehab 	}
256273f35418SHans Verkuil 	if (is_valid_ioctl(vfd, VIDIOC_G_MODULATOR)) {
25635bc3cb74SMauro Carvalho Chehab 		struct v4l2_modulator m = {
25645bc3cb74SMauro Carvalho Chehab 			.index = p->tuner,
25655bc3cb74SMauro Carvalho Chehab 		};
25665bc3cb74SMauro Carvalho Chehab 
25675bc3cb74SMauro Carvalho Chehab 		if (type != V4L2_TUNER_RADIO)
25685bc3cb74SMauro Carvalho Chehab 			return -EINVAL;
256979e8c7beSMauro Carvalho Chehab 		if (p->index)
257079e8c7beSMauro Carvalho Chehab 			return -EINVAL;
25715bc3cb74SMauro Carvalho Chehab 		err = ops->vidioc_g_modulator(file, fh, &m);
25725bc3cb74SMauro Carvalho Chehab 		if (err)
25735bc3cb74SMauro Carvalho Chehab 			return err;
25745bc3cb74SMauro Carvalho Chehab 		p->capability = m.capability | V4L2_TUNER_CAP_FREQ_BANDS;
25755bc3cb74SMauro Carvalho Chehab 		p->rangelow = m.rangelow;
25765bc3cb74SMauro Carvalho Chehab 		p->rangehigh = m.rangehigh;
25775bc3cb74SMauro Carvalho Chehab 		p->modulation = (type == V4L2_TUNER_RADIO) ?
25785bc3cb74SMauro Carvalho Chehab 			V4L2_BAND_MODULATION_FM : V4L2_BAND_MODULATION_VSB;
25795bc3cb74SMauro Carvalho Chehab 		return 0;
25805bc3cb74SMauro Carvalho Chehab 	}
25815bc3cb74SMauro Carvalho Chehab 	return -ENOTTY;
25825bc3cb74SMauro Carvalho Chehab }
25835bc3cb74SMauro Carvalho Chehab 
25845bc3cb74SMauro Carvalho Chehab struct v4l2_ioctl_info {
25855bc3cb74SMauro Carvalho Chehab 	unsigned int ioctl;
25865bc3cb74SMauro Carvalho Chehab 	u32 flags;
25875bc3cb74SMauro Carvalho Chehab 	const char * const name;
25883ad3b7a2SSami Tolvanen 	int (*func)(const struct v4l2_ioctl_ops *ops, struct file *file,
25893ad3b7a2SSami Tolvanen 		    void *fh, void *p);
25905bc3cb74SMauro Carvalho Chehab 	void (*debug)(const void *arg, bool write_only);
25915bc3cb74SMauro Carvalho Chehab };
25925bc3cb74SMauro Carvalho Chehab 
25935bc3cb74SMauro Carvalho Chehab /* This control needs a priority check */
25945bc3cb74SMauro Carvalho Chehab #define INFO_FL_PRIO		(1 << 0)
25955bc3cb74SMauro Carvalho Chehab /* This control can be valid if the filehandle passes a control handler. */
25965bc3cb74SMauro Carvalho Chehab #define INFO_FL_CTRL		(1 << 1)
25975bc3cb74SMauro Carvalho Chehab /* Queuing ioctl */
25983ad3b7a2SSami Tolvanen #define INFO_FL_QUEUE		(1 << 2)
2599043f77edSHans Verkuil /* Always copy back result, even on error */
26003ad3b7a2SSami Tolvanen #define INFO_FL_ALWAYS_COPY	(1 << 3)
26015bc3cb74SMauro Carvalho Chehab /* Zero struct from after the field to the end */
26025bc3cb74SMauro Carvalho Chehab #define INFO_FL_CLEAR(v4l2_struct, field)			\
26035bc3cb74SMauro Carvalho Chehab 	((offsetof(struct v4l2_struct, field) +			\
26045bc3cb74SMauro Carvalho Chehab 	  sizeof(((struct v4l2_struct *)0)->field)) << 16)
26055bc3cb74SMauro Carvalho Chehab #define INFO_FL_CLEAR_MASK	(_IOC_SIZEMASK << 16)
26065bc3cb74SMauro Carvalho Chehab 
26073ad3b7a2SSami Tolvanen #define DEFINE_V4L_STUB_FUNC(_vidioc)				\
26083ad3b7a2SSami Tolvanen 	static int v4l_stub_ ## _vidioc(			\
26093ad3b7a2SSami Tolvanen 			const struct v4l2_ioctl_ops *ops,	\
26103ad3b7a2SSami Tolvanen 			struct file *file, void *fh, void *p)	\
26113ad3b7a2SSami Tolvanen 	{							\
26123ad3b7a2SSami Tolvanen 		return ops->vidioc_ ## _vidioc(file, fh, p);	\
26133ad3b7a2SSami Tolvanen 	}
26143ad3b7a2SSami Tolvanen 
26153ad3b7a2SSami Tolvanen #define IOCTL_INFO(_ioctl, _func, _debug, _flags)		\
26165bc3cb74SMauro Carvalho Chehab 	[_IOC_NR(_ioctl)] = {					\
26175bc3cb74SMauro Carvalho Chehab 		.ioctl = _ioctl,				\
26183ad3b7a2SSami Tolvanen 		.flags = _flags,				\
26195bc3cb74SMauro Carvalho Chehab 		.name = #_ioctl,				\
26203ad3b7a2SSami Tolvanen 		.func = _func,					\
26215bc3cb74SMauro Carvalho Chehab 		.debug = _debug,				\
26225bc3cb74SMauro Carvalho Chehab 	}
26235bc3cb74SMauro Carvalho Chehab 
26243ad3b7a2SSami Tolvanen DEFINE_V4L_STUB_FUNC(g_fbuf)
26253ad3b7a2SSami Tolvanen DEFINE_V4L_STUB_FUNC(s_fbuf)
26263ad3b7a2SSami Tolvanen DEFINE_V4L_STUB_FUNC(expbuf)
26273ad3b7a2SSami Tolvanen DEFINE_V4L_STUB_FUNC(g_std)
26283ad3b7a2SSami Tolvanen DEFINE_V4L_STUB_FUNC(g_audio)
26293ad3b7a2SSami Tolvanen DEFINE_V4L_STUB_FUNC(s_audio)
26303ad3b7a2SSami Tolvanen DEFINE_V4L_STUB_FUNC(g_input)
26313ad3b7a2SSami Tolvanen DEFINE_V4L_STUB_FUNC(g_edid)
26323ad3b7a2SSami Tolvanen DEFINE_V4L_STUB_FUNC(s_edid)
26333ad3b7a2SSami Tolvanen DEFINE_V4L_STUB_FUNC(g_output)
26343ad3b7a2SSami Tolvanen DEFINE_V4L_STUB_FUNC(g_audout)
26353ad3b7a2SSami Tolvanen DEFINE_V4L_STUB_FUNC(s_audout)
26363ad3b7a2SSami Tolvanen DEFINE_V4L_STUB_FUNC(g_jpegcomp)
26373ad3b7a2SSami Tolvanen DEFINE_V4L_STUB_FUNC(s_jpegcomp)
26383ad3b7a2SSami Tolvanen DEFINE_V4L_STUB_FUNC(enumaudio)
26393ad3b7a2SSami Tolvanen DEFINE_V4L_STUB_FUNC(enumaudout)
26403ad3b7a2SSami Tolvanen DEFINE_V4L_STUB_FUNC(enum_framesizes)
26413ad3b7a2SSami Tolvanen DEFINE_V4L_STUB_FUNC(enum_frameintervals)
26423ad3b7a2SSami Tolvanen DEFINE_V4L_STUB_FUNC(g_enc_index)
26433ad3b7a2SSami Tolvanen DEFINE_V4L_STUB_FUNC(encoder_cmd)
26443ad3b7a2SSami Tolvanen DEFINE_V4L_STUB_FUNC(try_encoder_cmd)
26453ad3b7a2SSami Tolvanen DEFINE_V4L_STUB_FUNC(decoder_cmd)
26463ad3b7a2SSami Tolvanen DEFINE_V4L_STUB_FUNC(try_decoder_cmd)
26473ad3b7a2SSami Tolvanen DEFINE_V4L_STUB_FUNC(s_dv_timings)
26483ad3b7a2SSami Tolvanen DEFINE_V4L_STUB_FUNC(g_dv_timings)
26493ad3b7a2SSami Tolvanen DEFINE_V4L_STUB_FUNC(enum_dv_timings)
26503ad3b7a2SSami Tolvanen DEFINE_V4L_STUB_FUNC(query_dv_timings)
26513ad3b7a2SSami Tolvanen DEFINE_V4L_STUB_FUNC(dv_timings_cap)
26525bc3cb74SMauro Carvalho Chehab 
26537c91d0a4SEric Biggers static const struct v4l2_ioctl_info v4l2_ioctls[] = {
26543ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_QUERYCAP, v4l_querycap, v4l_print_querycap, 0),
26553ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_ENUM_FMT, v4l_enum_fmt, v4l_print_fmtdesc, INFO_FL_CLEAR(v4l2_fmtdesc, type)),
26563ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_G_FMT, v4l_g_fmt, v4l_print_format, 0),
26573ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_S_FMT, v4l_s_fmt, v4l_print_format, INFO_FL_PRIO),
26583ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_REQBUFS, v4l_reqbufs, v4l_print_requestbuffers, INFO_FL_PRIO | INFO_FL_QUEUE),
26593ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_QUERYBUF, v4l_querybuf, v4l_print_buffer, INFO_FL_QUEUE | INFO_FL_CLEAR(v4l2_buffer, length)),
26603ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_G_FBUF, v4l_stub_g_fbuf, v4l_print_framebuffer, 0),
26613ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_S_FBUF, v4l_stub_s_fbuf, v4l_print_framebuffer, INFO_FL_PRIO),
26623ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_OVERLAY, v4l_overlay, v4l_print_u32, INFO_FL_PRIO),
26633ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_QBUF, v4l_qbuf, v4l_print_buffer, INFO_FL_QUEUE),
26643ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_EXPBUF, v4l_stub_expbuf, v4l_print_exportbuffer, INFO_FL_QUEUE | INFO_FL_CLEAR(v4l2_exportbuffer, flags)),
26653ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_DQBUF, v4l_dqbuf, v4l_print_buffer, INFO_FL_QUEUE),
26663ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_STREAMON, v4l_streamon, v4l_print_buftype, INFO_FL_PRIO | INFO_FL_QUEUE),
26673ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_STREAMOFF, v4l_streamoff, v4l_print_buftype, INFO_FL_PRIO | INFO_FL_QUEUE),
26683ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_G_PARM, v4l_g_parm, v4l_print_streamparm, INFO_FL_CLEAR(v4l2_streamparm, type)),
26693ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_S_PARM, v4l_s_parm, v4l_print_streamparm, INFO_FL_PRIO),
26703ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_G_STD, v4l_stub_g_std, v4l_print_std, 0),
26713ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_S_STD, v4l_s_std, v4l_print_std, INFO_FL_PRIO),
26723ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_ENUMSTD, v4l_enumstd, v4l_print_standard, INFO_FL_CLEAR(v4l2_standard, index)),
26733ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_ENUMINPUT, v4l_enuminput, v4l_print_enuminput, INFO_FL_CLEAR(v4l2_input, index)),
26743ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_G_CTRL, v4l_g_ctrl, v4l_print_control, INFO_FL_CTRL | INFO_FL_CLEAR(v4l2_control, id)),
26753ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_S_CTRL, v4l_s_ctrl, v4l_print_control, INFO_FL_PRIO | INFO_FL_CTRL),
26763ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_G_TUNER, v4l_g_tuner, v4l_print_tuner, INFO_FL_CLEAR(v4l2_tuner, index)),
26773ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_S_TUNER, v4l_s_tuner, v4l_print_tuner, INFO_FL_PRIO),
26783ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_G_AUDIO, v4l_stub_g_audio, v4l_print_audio, 0),
26793ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_S_AUDIO, v4l_stub_s_audio, v4l_print_audio, INFO_FL_PRIO),
26803ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_QUERYCTRL, v4l_queryctrl, v4l_print_queryctrl, INFO_FL_CTRL | INFO_FL_CLEAR(v4l2_queryctrl, id)),
26813ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_QUERYMENU, v4l_querymenu, v4l_print_querymenu, INFO_FL_CTRL | INFO_FL_CLEAR(v4l2_querymenu, index)),
26823ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_G_INPUT, v4l_stub_g_input, v4l_print_u32, 0),
26833ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_S_INPUT, v4l_s_input, v4l_print_u32, INFO_FL_PRIO),
26843ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_G_EDID, v4l_stub_g_edid, v4l_print_edid, INFO_FL_ALWAYS_COPY),
26853ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_S_EDID, v4l_stub_s_edid, v4l_print_edid, INFO_FL_PRIO | INFO_FL_ALWAYS_COPY),
26863ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_G_OUTPUT, v4l_stub_g_output, v4l_print_u32, 0),
26873ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_S_OUTPUT, v4l_s_output, v4l_print_u32, INFO_FL_PRIO),
26883ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_ENUMOUTPUT, v4l_enumoutput, v4l_print_enumoutput, INFO_FL_CLEAR(v4l2_output, index)),
26893ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_G_AUDOUT, v4l_stub_g_audout, v4l_print_audioout, 0),
26903ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_S_AUDOUT, v4l_stub_s_audout, v4l_print_audioout, INFO_FL_PRIO),
26913ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_G_MODULATOR, v4l_g_modulator, v4l_print_modulator, INFO_FL_CLEAR(v4l2_modulator, index)),
26923ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_S_MODULATOR, v4l_s_modulator, v4l_print_modulator, INFO_FL_PRIO),
26933ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_G_FREQUENCY, v4l_g_frequency, v4l_print_frequency, INFO_FL_CLEAR(v4l2_frequency, tuner)),
26943ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_S_FREQUENCY, v4l_s_frequency, v4l_print_frequency, INFO_FL_PRIO),
26953ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_CROPCAP, v4l_cropcap, v4l_print_cropcap, INFO_FL_CLEAR(v4l2_cropcap, type)),
26963ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_G_CROP, v4l_g_crop, v4l_print_crop, INFO_FL_CLEAR(v4l2_crop, type)),
26973ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_S_CROP, v4l_s_crop, v4l_print_crop, INFO_FL_PRIO),
26983ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_G_SELECTION, v4l_g_selection, v4l_print_selection, INFO_FL_CLEAR(v4l2_selection, r)),
26993ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_S_SELECTION, v4l_s_selection, v4l_print_selection, INFO_FL_PRIO | INFO_FL_CLEAR(v4l2_selection, r)),
27003ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_G_JPEGCOMP, v4l_stub_g_jpegcomp, v4l_print_jpegcompression, 0),
27013ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_S_JPEGCOMP, v4l_stub_s_jpegcomp, v4l_print_jpegcompression, INFO_FL_PRIO),
27023ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_QUERYSTD, v4l_querystd, v4l_print_std, 0),
27033ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_TRY_FMT, v4l_try_fmt, v4l_print_format, 0),
27043ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_ENUMAUDIO, v4l_stub_enumaudio, v4l_print_audio, INFO_FL_CLEAR(v4l2_audio, index)),
27053ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_ENUMAUDOUT, v4l_stub_enumaudout, v4l_print_audioout, INFO_FL_CLEAR(v4l2_audioout, index)),
27063ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_G_PRIORITY, v4l_g_priority, v4l_print_u32, 0),
27073ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_S_PRIORITY, v4l_s_priority, v4l_print_u32, INFO_FL_PRIO),
27083ad3b7a2SSami 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)),
27093ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_LOG_STATUS, v4l_log_status, v4l_print_newline, 0),
27103ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_G_EXT_CTRLS, v4l_g_ext_ctrls, v4l_print_ext_controls, INFO_FL_CTRL),
27113ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_S_EXT_CTRLS, v4l_s_ext_ctrls, v4l_print_ext_controls, INFO_FL_PRIO | INFO_FL_CTRL),
27123ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_TRY_EXT_CTRLS, v4l_try_ext_ctrls, v4l_print_ext_controls, INFO_FL_CTRL),
27133ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_ENUM_FRAMESIZES, v4l_stub_enum_framesizes, v4l_print_frmsizeenum, INFO_FL_CLEAR(v4l2_frmsizeenum, pixel_format)),
27143ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_ENUM_FRAMEINTERVALS, v4l_stub_enum_frameintervals, v4l_print_frmivalenum, INFO_FL_CLEAR(v4l2_frmivalenum, height)),
27153ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_G_ENC_INDEX, v4l_stub_g_enc_index, v4l_print_enc_idx, 0),
27163ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_ENCODER_CMD, v4l_stub_encoder_cmd, v4l_print_encoder_cmd, INFO_FL_PRIO | INFO_FL_CLEAR(v4l2_encoder_cmd, flags)),
27173ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_TRY_ENCODER_CMD, v4l_stub_try_encoder_cmd, v4l_print_encoder_cmd, INFO_FL_CLEAR(v4l2_encoder_cmd, flags)),
27183ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_DECODER_CMD, v4l_stub_decoder_cmd, v4l_print_decoder_cmd, INFO_FL_PRIO),
27193ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_TRY_DECODER_CMD, v4l_stub_try_decoder_cmd, v4l_print_decoder_cmd, 0),
27203ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_DBG_S_REGISTER, v4l_dbg_s_register, v4l_print_dbg_register, 0),
27213ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_DBG_G_REGISTER, v4l_dbg_g_register, v4l_print_dbg_register, 0),
27223ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_S_HW_FREQ_SEEK, v4l_s_hw_freq_seek, v4l_print_hw_freq_seek, INFO_FL_PRIO),
27233ad3b7a2SSami 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)),
27243ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_G_DV_TIMINGS, v4l_stub_g_dv_timings, v4l_print_dv_timings, 0),
27253ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_DQEVENT, v4l_dqevent, v4l_print_event, 0),
27263ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_SUBSCRIBE_EVENT, v4l_subscribe_event, v4l_print_event_subscription, 0),
27273ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_UNSUBSCRIBE_EVENT, v4l_unsubscribe_event, v4l_print_event_subscription, 0),
27283ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_CREATE_BUFS, v4l_create_bufs, v4l_print_create_buffers, INFO_FL_PRIO | INFO_FL_QUEUE),
27293ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_PREPARE_BUF, v4l_prepare_buf, v4l_print_buffer, INFO_FL_QUEUE),
27303ad3b7a2SSami 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)),
27313ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_QUERY_DV_TIMINGS, v4l_stub_query_dv_timings, v4l_print_dv_timings, INFO_FL_ALWAYS_COPY),
27323ad3b7a2SSami 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)),
27333ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_ENUM_FREQ_BANDS, v4l_enum_freq_bands, v4l_print_freq_band, 0),
27343ad3b7a2SSami 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)),
27353ad3b7a2SSami 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)),
27365bc3cb74SMauro Carvalho Chehab };
27375bc3cb74SMauro Carvalho Chehab #define V4L2_IOCTLS ARRAY_SIZE(v4l2_ioctls)
27385bc3cb74SMauro Carvalho Chehab 
273973a11062SHans Verkuil static bool v4l2_is_known_ioctl(unsigned int cmd)
27405bc3cb74SMauro Carvalho Chehab {
27415bc3cb74SMauro Carvalho Chehab 	if (_IOC_NR(cmd) >= V4L2_IOCTLS)
27425bc3cb74SMauro Carvalho Chehab 		return false;
27435bc3cb74SMauro Carvalho Chehab 	return v4l2_ioctls[_IOC_NR(cmd)].ioctl == cmd;
27445bc3cb74SMauro Carvalho Chehab }
27455bc3cb74SMauro Carvalho Chehab 
274673a11062SHans Verkuil static struct mutex *v4l2_ioctl_get_lock(struct video_device *vdev,
2747d862bc08SHans Verkuil 					 struct v4l2_fh *vfh, unsigned int cmd,
2748d862bc08SHans Verkuil 					 void *arg)
27495bc3cb74SMauro Carvalho Chehab {
27505bc3cb74SMauro Carvalho Chehab 	if (_IOC_NR(cmd) >= V4L2_IOCTLS)
27515bc3cb74SMauro Carvalho Chehab 		return vdev->lock;
2752d862bc08SHans Verkuil #if IS_ENABLED(CONFIG_V4L2_MEM2MEM_DEV)
2753d862bc08SHans Verkuil 	if (vfh && vfh->m2m_ctx &&
2754d862bc08SHans Verkuil 	    (v4l2_ioctls[_IOC_NR(cmd)].flags & INFO_FL_QUEUE)) {
2755542a522dSEzequiel Garcia 		if (vfh->m2m_ctx->q_lock)
2756542a522dSEzequiel Garcia 			return vfh->m2m_ctx->q_lock;
2757d862bc08SHans Verkuil 	}
2758d862bc08SHans Verkuil #endif
27595bc3cb74SMauro Carvalho Chehab 	if (vdev->queue && vdev->queue->lock &&
27605bc3cb74SMauro Carvalho Chehab 			(v4l2_ioctls[_IOC_NR(cmd)].flags & INFO_FL_QUEUE))
27615bc3cb74SMauro Carvalho Chehab 		return vdev->queue->lock;
27625bc3cb74SMauro Carvalho Chehab 	return vdev->lock;
27635bc3cb74SMauro Carvalho Chehab }
27645bc3cb74SMauro Carvalho Chehab 
27655bc3cb74SMauro Carvalho Chehab /* Common ioctl debug function. This function can be used by
27665bc3cb74SMauro Carvalho Chehab    external ioctl messages as well as internal V4L ioctl */
27675bc3cb74SMauro Carvalho Chehab void v4l_printk_ioctl(const char *prefix, unsigned int cmd)
27685bc3cb74SMauro Carvalho Chehab {
27695bc3cb74SMauro Carvalho Chehab 	const char *dir, *type;
27705bc3cb74SMauro Carvalho Chehab 
27715bc3cb74SMauro Carvalho Chehab 	if (prefix)
27725bc3cb74SMauro Carvalho Chehab 		printk(KERN_DEBUG "%s: ", prefix);
27735bc3cb74SMauro Carvalho Chehab 
27745bc3cb74SMauro Carvalho Chehab 	switch (_IOC_TYPE(cmd)) {
27755bc3cb74SMauro Carvalho Chehab 	case 'd':
27765bc3cb74SMauro Carvalho Chehab 		type = "v4l2_int";
27775bc3cb74SMauro Carvalho Chehab 		break;
27785bc3cb74SMauro Carvalho Chehab 	case 'V':
27795bc3cb74SMauro Carvalho Chehab 		if (_IOC_NR(cmd) >= V4L2_IOCTLS) {
27805bc3cb74SMauro Carvalho Chehab 			type = "v4l2";
27815bc3cb74SMauro Carvalho Chehab 			break;
27825bc3cb74SMauro Carvalho Chehab 		}
27835bc3cb74SMauro Carvalho Chehab 		pr_cont("%s", v4l2_ioctls[_IOC_NR(cmd)].name);
27845bc3cb74SMauro Carvalho Chehab 		return;
27855bc3cb74SMauro Carvalho Chehab 	default:
27865bc3cb74SMauro Carvalho Chehab 		type = "unknown";
27875bc3cb74SMauro Carvalho Chehab 		break;
27885bc3cb74SMauro Carvalho Chehab 	}
27895bc3cb74SMauro Carvalho Chehab 
27905bc3cb74SMauro Carvalho Chehab 	switch (_IOC_DIR(cmd)) {
27915bc3cb74SMauro Carvalho Chehab 	case _IOC_NONE:              dir = "--"; break;
27925bc3cb74SMauro Carvalho Chehab 	case _IOC_READ:              dir = "r-"; break;
27935bc3cb74SMauro Carvalho Chehab 	case _IOC_WRITE:             dir = "-w"; break;
27945bc3cb74SMauro Carvalho Chehab 	case _IOC_READ | _IOC_WRITE: dir = "rw"; break;
27955bc3cb74SMauro Carvalho Chehab 	default:                     dir = "*ERR*"; break;
27965bc3cb74SMauro Carvalho Chehab 	}
27975bc3cb74SMauro Carvalho Chehab 	pr_cont("%s ioctl '%c', dir=%s, #%d (0x%08x)",
27985bc3cb74SMauro Carvalho Chehab 		type, _IOC_TYPE(cmd), dir, _IOC_NR(cmd), cmd);
27995bc3cb74SMauro Carvalho Chehab }
28005bc3cb74SMauro Carvalho Chehab EXPORT_SYMBOL(v4l_printk_ioctl);
28015bc3cb74SMauro Carvalho Chehab 
28025bc3cb74SMauro Carvalho Chehab static long __video_do_ioctl(struct file *file,
28035bc3cb74SMauro Carvalho Chehab 		unsigned int cmd, void *arg)
28045bc3cb74SMauro Carvalho Chehab {
28055bc3cb74SMauro Carvalho Chehab 	struct video_device *vfd = video_devdata(file);
2806cc6eddcdSHans Verkuil 	struct mutex *req_queue_lock = NULL;
280773a11062SHans Verkuil 	struct mutex *lock; /* ioctl serialization mutex */
28085bc3cb74SMauro Carvalho Chehab 	const struct v4l2_ioctl_ops *ops = vfd->ioctl_ops;
28095bc3cb74SMauro Carvalho Chehab 	bool write_only = false;
28105bc3cb74SMauro Carvalho Chehab 	struct v4l2_ioctl_info default_info;
28115bc3cb74SMauro Carvalho Chehab 	const struct v4l2_ioctl_info *info;
28125bc3cb74SMauro Carvalho Chehab 	void *fh = file->private_data;
28135bc3cb74SMauro Carvalho Chehab 	struct v4l2_fh *vfh = NULL;
281417028cdbSHans Verkuil 	int dev_debug = vfd->dev_debug;
28155bc3cb74SMauro Carvalho Chehab 	long ret = -ENOTTY;
28165bc3cb74SMauro Carvalho Chehab 
28175bc3cb74SMauro Carvalho Chehab 	if (ops == NULL) {
28185bc3cb74SMauro Carvalho Chehab 		pr_warn("%s: has no ioctl_ops.\n",
28195bc3cb74SMauro Carvalho Chehab 				video_device_node_name(vfd));
28205bc3cb74SMauro Carvalho Chehab 		return ret;
28215bc3cb74SMauro Carvalho Chehab 	}
28225bc3cb74SMauro Carvalho Chehab 
2823b7284bb0SRamakrishnan Muthukrishnan 	if (test_bit(V4L2_FL_USES_V4L2_FH, &vfd->flags))
28245bc3cb74SMauro Carvalho Chehab 		vfh = file->private_data;
28255bc3cb74SMauro Carvalho Chehab 
2826cc6eddcdSHans Verkuil 	/*
2827cc6eddcdSHans Verkuil 	 * We need to serialize streamon/off with queueing new requests.
2828cc6eddcdSHans Verkuil 	 * These ioctls may trigger the cancellation of a streaming
2829cc6eddcdSHans Verkuil 	 * operation, and that should not be mixed with queueing a new
2830cc6eddcdSHans Verkuil 	 * request at the same time.
2831cc6eddcdSHans Verkuil 	 */
2832cc6eddcdSHans Verkuil 	if (v4l2_device_supports_requests(vfd->v4l2_dev) &&
2833cc6eddcdSHans Verkuil 	    (cmd == VIDIOC_STREAMON || cmd == VIDIOC_STREAMOFF)) {
2834cc6eddcdSHans Verkuil 		req_queue_lock = &vfd->v4l2_dev->mdev->req_queue_mutex;
2835cc6eddcdSHans Verkuil 
2836cc6eddcdSHans Verkuil 		if (mutex_lock_interruptible(req_queue_lock))
2837cc6eddcdSHans Verkuil 			return -ERESTARTSYS;
2838cc6eddcdSHans Verkuil 	}
2839cc6eddcdSHans Verkuil 
2840d862bc08SHans Verkuil 	lock = v4l2_ioctl_get_lock(vfd, vfh, cmd, arg);
284173a11062SHans Verkuil 
2842cc6eddcdSHans Verkuil 	if (lock && mutex_lock_interruptible(lock)) {
2843cc6eddcdSHans Verkuil 		if (req_queue_lock)
2844cc6eddcdSHans Verkuil 			mutex_unlock(req_queue_lock);
284573a11062SHans Verkuil 		return -ERESTARTSYS;
2846cc6eddcdSHans Verkuil 	}
284773a11062SHans Verkuil 
284873a11062SHans Verkuil 	if (!video_is_registered(vfd)) {
284973a11062SHans Verkuil 		ret = -ENODEV;
285073a11062SHans Verkuil 		goto unlock;
285173a11062SHans Verkuil 	}
285273a11062SHans Verkuil 
28535bc3cb74SMauro Carvalho Chehab 	if (v4l2_is_known_ioctl(cmd)) {
28545bc3cb74SMauro Carvalho Chehab 		info = &v4l2_ioctls[_IOC_NR(cmd)];
28555bc3cb74SMauro Carvalho Chehab 
28565bc3cb74SMauro Carvalho Chehab 		if (!test_bit(_IOC_NR(cmd), vfd->valid_ioctls) &&
28575bc3cb74SMauro Carvalho Chehab 		    !((info->flags & INFO_FL_CTRL) && vfh && vfh->ctrl_handler))
28585bc3cb74SMauro Carvalho Chehab 			goto done;
28595bc3cb74SMauro Carvalho Chehab 
2860b7284bb0SRamakrishnan Muthukrishnan 		if (vfh && (info->flags & INFO_FL_PRIO)) {
28615bc3cb74SMauro Carvalho Chehab 			ret = v4l2_prio_check(vfd->prio, vfh->prio);
28625bc3cb74SMauro Carvalho Chehab 			if (ret)
28635bc3cb74SMauro Carvalho Chehab 				goto done;
28645bc3cb74SMauro Carvalho Chehab 		}
28655bc3cb74SMauro Carvalho Chehab 	} else {
28665bc3cb74SMauro Carvalho Chehab 		default_info.ioctl = cmd;
28675bc3cb74SMauro Carvalho Chehab 		default_info.flags = 0;
28685bc3cb74SMauro Carvalho Chehab 		default_info.debug = v4l_print_default;
28695bc3cb74SMauro Carvalho Chehab 		info = &default_info;
28705bc3cb74SMauro Carvalho Chehab 	}
28715bc3cb74SMauro Carvalho Chehab 
28725bc3cb74SMauro Carvalho Chehab 	write_only = _IOC_DIR(cmd) == _IOC_WRITE;
28733ad3b7a2SSami Tolvanen 	if (info != &default_info) {
28743ad3b7a2SSami Tolvanen 		ret = info->func(ops, file, fh, arg);
28755bc3cb74SMauro Carvalho Chehab 	} else if (!ops->vidioc_default) {
28765bc3cb74SMauro Carvalho Chehab 		ret = -ENOTTY;
28775bc3cb74SMauro Carvalho Chehab 	} else {
28785bc3cb74SMauro Carvalho Chehab 		ret = ops->vidioc_default(file, fh,
2879b7284bb0SRamakrishnan Muthukrishnan 			vfh ? v4l2_prio_check(vfd->prio, vfh->prio) >= 0 : 0,
28805bc3cb74SMauro Carvalho Chehab 			cmd, arg);
28815bc3cb74SMauro Carvalho Chehab 	}
28825bc3cb74SMauro Carvalho Chehab 
28835bc3cb74SMauro Carvalho Chehab done:
288417028cdbSHans Verkuil 	if (dev_debug & (V4L2_DEV_DEBUG_IOCTL | V4L2_DEV_DEBUG_IOCTL_ARG)) {
288517028cdbSHans Verkuil 		if (!(dev_debug & V4L2_DEV_DEBUG_STREAMING) &&
288617028cdbSHans Verkuil 		    (cmd == VIDIOC_QBUF || cmd == VIDIOC_DQBUF))
28875983d3bcSHans Verkuil 			goto unlock;
288817028cdbSHans Verkuil 
28895bc3cb74SMauro Carvalho Chehab 		v4l_printk_ioctl(video_device_node_name(vfd), cmd);
28905bc3cb74SMauro Carvalho Chehab 		if (ret < 0)
2891505d04bdSHans Verkuil 			pr_cont(": error %ld", ret);
289217028cdbSHans Verkuil 		if (!(dev_debug & V4L2_DEV_DEBUG_IOCTL_ARG))
28935bc3cb74SMauro Carvalho Chehab 			pr_cont("\n");
28945bc3cb74SMauro Carvalho Chehab 		else if (_IOC_DIR(cmd) == _IOC_NONE)
28955bc3cb74SMauro Carvalho Chehab 			info->debug(arg, write_only);
28965bc3cb74SMauro Carvalho Chehab 		else {
28975bc3cb74SMauro Carvalho Chehab 			pr_cont(": ");
28985bc3cb74SMauro Carvalho Chehab 			info->debug(arg, write_only);
28995bc3cb74SMauro Carvalho Chehab 		}
29005bc3cb74SMauro Carvalho Chehab 	}
29015bc3cb74SMauro Carvalho Chehab 
290273a11062SHans Verkuil unlock:
290373a11062SHans Verkuil 	if (lock)
290473a11062SHans Verkuil 		mutex_unlock(lock);
2905cc6eddcdSHans Verkuil 	if (req_queue_lock)
2906cc6eddcdSHans Verkuil 		mutex_unlock(req_queue_lock);
29075bc3cb74SMauro Carvalho Chehab 	return ret;
29085bc3cb74SMauro Carvalho Chehab }
29095bc3cb74SMauro Carvalho Chehab 
29105bc3cb74SMauro Carvalho Chehab static int check_array_args(unsigned int cmd, void *parg, size_t *array_size,
2911ba2d35c1SHans Verkuil 			    void __user **user_ptr, void ***kernel_ptr)
29125bc3cb74SMauro Carvalho Chehab {
29135bc3cb74SMauro Carvalho Chehab 	int ret = 0;
29145bc3cb74SMauro Carvalho Chehab 
29155bc3cb74SMauro Carvalho Chehab 	switch (cmd) {
291696b1a702SHans Verkuil 	case VIDIOC_PREPARE_BUF:
29175bc3cb74SMauro Carvalho Chehab 	case VIDIOC_QUERYBUF:
29185bc3cb74SMauro Carvalho Chehab 	case VIDIOC_QBUF:
29195bc3cb74SMauro Carvalho Chehab 	case VIDIOC_DQBUF: {
29205bc3cb74SMauro Carvalho Chehab 		struct v4l2_buffer *buf = parg;
29215bc3cb74SMauro Carvalho Chehab 
29225bc3cb74SMauro Carvalho Chehab 		if (V4L2_TYPE_IS_MULTIPLANAR(buf->type) && buf->length > 0) {
29235bc3cb74SMauro Carvalho Chehab 			if (buf->length > VIDEO_MAX_PLANES) {
29245bc3cb74SMauro Carvalho Chehab 				ret = -EINVAL;
29255bc3cb74SMauro Carvalho Chehab 				break;
29265bc3cb74SMauro Carvalho Chehab 			}
29275bc3cb74SMauro Carvalho Chehab 			*user_ptr = (void __user *)buf->m.planes;
2928ba2d35c1SHans Verkuil 			*kernel_ptr = (void **)&buf->m.planes;
29295bc3cb74SMauro Carvalho Chehab 			*array_size = sizeof(struct v4l2_plane) * buf->length;
29305bc3cb74SMauro Carvalho Chehab 			ret = 1;
29315bc3cb74SMauro Carvalho Chehab 		}
29325bc3cb74SMauro Carvalho Chehab 		break;
29335bc3cb74SMauro Carvalho Chehab 	}
29345bc3cb74SMauro Carvalho Chehab 
2935dd519bb3SHans Verkuil 	case VIDIOC_G_EDID:
2936dd519bb3SHans Verkuil 	case VIDIOC_S_EDID: {
2937dd519bb3SHans Verkuil 		struct v4l2_edid *edid = parg;
2938ed45ce2cSHans Verkuil 
2939ed45ce2cSHans Verkuil 		if (edid->blocks) {
29401b8b10ccSHans Verkuil 			if (edid->blocks > 256) {
29411b8b10ccSHans Verkuil 				ret = -EINVAL;
29421b8b10ccSHans Verkuil 				break;
29431b8b10ccSHans Verkuil 			}
2944ed45ce2cSHans Verkuil 			*user_ptr = (void __user *)edid->edid;
2945ba2d35c1SHans Verkuil 			*kernel_ptr = (void **)&edid->edid;
2946ed45ce2cSHans Verkuil 			*array_size = edid->blocks * 128;
2947ed45ce2cSHans Verkuil 			ret = 1;
2948ed45ce2cSHans Verkuil 		}
2949ed45ce2cSHans Verkuil 		break;
2950ed45ce2cSHans Verkuil 	}
2951ed45ce2cSHans Verkuil 
29525bc3cb74SMauro Carvalho Chehab 	case VIDIOC_S_EXT_CTRLS:
29535bc3cb74SMauro Carvalho Chehab 	case VIDIOC_G_EXT_CTRLS:
29545bc3cb74SMauro Carvalho Chehab 	case VIDIOC_TRY_EXT_CTRLS: {
29555bc3cb74SMauro Carvalho Chehab 		struct v4l2_ext_controls *ctrls = parg;
29565bc3cb74SMauro Carvalho Chehab 
29575bc3cb74SMauro Carvalho Chehab 		if (ctrls->count != 0) {
29585bc3cb74SMauro Carvalho Chehab 			if (ctrls->count > V4L2_CID_MAX_CTRLS) {
29595bc3cb74SMauro Carvalho Chehab 				ret = -EINVAL;
29605bc3cb74SMauro Carvalho Chehab 				break;
29615bc3cb74SMauro Carvalho Chehab 			}
29625bc3cb74SMauro Carvalho Chehab 			*user_ptr = (void __user *)ctrls->controls;
2963ba2d35c1SHans Verkuil 			*kernel_ptr = (void **)&ctrls->controls;
29645bc3cb74SMauro Carvalho Chehab 			*array_size = sizeof(struct v4l2_ext_control)
29655bc3cb74SMauro Carvalho Chehab 				    * ctrls->count;
29665bc3cb74SMauro Carvalho Chehab 			ret = 1;
29675bc3cb74SMauro Carvalho Chehab 		}
29685bc3cb74SMauro Carvalho Chehab 		break;
29695bc3cb74SMauro Carvalho Chehab 	}
29705bc3cb74SMauro Carvalho Chehab 	}
29715bc3cb74SMauro Carvalho Chehab 
29725bc3cb74SMauro Carvalho Chehab 	return ret;
29735bc3cb74SMauro Carvalho Chehab }
29745bc3cb74SMauro Carvalho Chehab 
29755bc3cb74SMauro Carvalho Chehab long
29765bc3cb74SMauro Carvalho Chehab video_usercopy(struct file *file, unsigned int cmd, unsigned long arg,
29775bc3cb74SMauro Carvalho Chehab 	       v4l2_kioctl func)
29785bc3cb74SMauro Carvalho Chehab {
29795bc3cb74SMauro Carvalho Chehab 	char	sbuf[128];
29805bc3cb74SMauro Carvalho Chehab 	void    *mbuf = NULL;
29815bc3cb74SMauro Carvalho Chehab 	void	*parg = (void *)arg;
29825bc3cb74SMauro Carvalho Chehab 	long	err  = -EINVAL;
29835bc3cb74SMauro Carvalho Chehab 	bool	has_array_args;
2984043f77edSHans Verkuil 	bool	always_copy = false;
29855bc3cb74SMauro Carvalho Chehab 	size_t  array_size = 0;
29865bc3cb74SMauro Carvalho Chehab 	void __user *user_ptr = NULL;
29875bc3cb74SMauro Carvalho Chehab 	void	**kernel_ptr = NULL;
2988f8a695c4SMauro Carvalho Chehab 	const size_t ioc_size = _IOC_SIZE(cmd);
29895bc3cb74SMauro Carvalho Chehab 
29905bc3cb74SMauro Carvalho Chehab 	/*  Copy arguments into temp kernel buffer  */
29915bc3cb74SMauro Carvalho Chehab 	if (_IOC_DIR(cmd) != _IOC_NONE) {
2992f8a695c4SMauro Carvalho Chehab 		if (ioc_size <= sizeof(sbuf)) {
29935bc3cb74SMauro Carvalho Chehab 			parg = sbuf;
29945bc3cb74SMauro Carvalho Chehab 		} else {
29955bc3cb74SMauro Carvalho Chehab 			/* too big to allocate from stack */
2996f8a695c4SMauro Carvalho Chehab 			mbuf = kvmalloc(ioc_size, GFP_KERNEL);
29975bc3cb74SMauro Carvalho Chehab 			if (NULL == mbuf)
29985bc3cb74SMauro Carvalho Chehab 				return -ENOMEM;
29995bc3cb74SMauro Carvalho Chehab 			parg = mbuf;
30005bc3cb74SMauro Carvalho Chehab 		}
30015bc3cb74SMauro Carvalho Chehab 
30025bc3cb74SMauro Carvalho Chehab 		err = -EFAULT;
30035bc3cb74SMauro Carvalho Chehab 		if (_IOC_DIR(cmd) & _IOC_WRITE) {
3004f8a695c4SMauro Carvalho Chehab 			unsigned int n = ioc_size;
30055bc3cb74SMauro Carvalho Chehab 
30065bc3cb74SMauro Carvalho Chehab 			/*
30075bc3cb74SMauro Carvalho Chehab 			 * In some cases, only a few fields are used as input,
30085bc3cb74SMauro Carvalho Chehab 			 * i.e. when the app sets "index" and then the driver
30095bc3cb74SMauro Carvalho Chehab 			 * fills in the rest of the structure for the thing
30105bc3cb74SMauro Carvalho Chehab 			 * with that index.  We only need to copy up the first
30115bc3cb74SMauro Carvalho Chehab 			 * non-input field.
30125bc3cb74SMauro Carvalho Chehab 			 */
30135bc3cb74SMauro Carvalho Chehab 			if (v4l2_is_known_ioctl(cmd)) {
30145bc3cb74SMauro Carvalho Chehab 				u32 flags = v4l2_ioctls[_IOC_NR(cmd)].flags;
3015043f77edSHans Verkuil 
30165bc3cb74SMauro Carvalho Chehab 				if (flags & INFO_FL_CLEAR_MASK)
30175bc3cb74SMauro Carvalho Chehab 					n = (flags & INFO_FL_CLEAR_MASK) >> 16;
3018043f77edSHans Verkuil 				always_copy = flags & INFO_FL_ALWAYS_COPY;
30195bc3cb74SMauro Carvalho Chehab 			}
30205bc3cb74SMauro Carvalho Chehab 
30215bc3cb74SMauro Carvalho Chehab 			if (copy_from_user(parg, (void __user *)arg, n))
30225bc3cb74SMauro Carvalho Chehab 				goto out;
30235bc3cb74SMauro Carvalho Chehab 
30245bc3cb74SMauro Carvalho Chehab 			/* zero out anything we don't copy from userspace */
3025f8a695c4SMauro Carvalho Chehab 			if (n < ioc_size)
3026f8a695c4SMauro Carvalho Chehab 				memset((u8 *)parg + n, 0, ioc_size - n);
30275bc3cb74SMauro Carvalho Chehab 		} else {
30285bc3cb74SMauro Carvalho Chehab 			/* read-only ioctl */
3029f8a695c4SMauro Carvalho Chehab 			memset(parg, 0, ioc_size);
30305bc3cb74SMauro Carvalho Chehab 		}
30315bc3cb74SMauro Carvalho Chehab 	}
30325bc3cb74SMauro Carvalho Chehab 
30335bc3cb74SMauro Carvalho Chehab 	err = check_array_args(cmd, parg, &array_size, &user_ptr, &kernel_ptr);
30345bc3cb74SMauro Carvalho Chehab 	if (err < 0)
30355bc3cb74SMauro Carvalho Chehab 		goto out;
30365bc3cb74SMauro Carvalho Chehab 	has_array_args = err;
30375bc3cb74SMauro Carvalho Chehab 
30385bc3cb74SMauro Carvalho Chehab 	if (has_array_args) {
30395bc3cb74SMauro Carvalho Chehab 		/*
30405bc3cb74SMauro Carvalho Chehab 		 * When adding new types of array args, make sure that the
30415bc3cb74SMauro Carvalho Chehab 		 * parent argument to ioctl (which contains the pointer to the
30425bc3cb74SMauro Carvalho Chehab 		 * array) fits into sbuf (so that mbuf will still remain
30435bc3cb74SMauro Carvalho Chehab 		 * unused up to here).
30445bc3cb74SMauro Carvalho Chehab 		 */
3045758d90e1STomasz Figa 		mbuf = kvmalloc(array_size, GFP_KERNEL);
30465bc3cb74SMauro Carvalho Chehab 		err = -ENOMEM;
30475bc3cb74SMauro Carvalho Chehab 		if (NULL == mbuf)
30485bc3cb74SMauro Carvalho Chehab 			goto out_array_args;
30495bc3cb74SMauro Carvalho Chehab 		err = -EFAULT;
30505bc3cb74SMauro Carvalho Chehab 		if (copy_from_user(mbuf, user_ptr, array_size))
30515bc3cb74SMauro Carvalho Chehab 			goto out_array_args;
30525bc3cb74SMauro Carvalho Chehab 		*kernel_ptr = mbuf;
30535bc3cb74SMauro Carvalho Chehab 	}
30545bc3cb74SMauro Carvalho Chehab 
30555bc3cb74SMauro Carvalho Chehab 	/* Handles IOCTL */
30565bc3cb74SMauro Carvalho Chehab 	err = func(file, cmd, parg);
3057181a4a2dSHans Verkuil 	if (err == -ENOTTY || err == -ENOIOCTLCMD) {
30585bc3cb74SMauro Carvalho Chehab 		err = -ENOTTY;
3059181a4a2dSHans Verkuil 		goto out;
3060181a4a2dSHans Verkuil 	}
3061181a4a2dSHans Verkuil 
3062aa32f4c0SHans Verkuil 	if (err == 0) {
3063aa32f4c0SHans Verkuil 		if (cmd == VIDIOC_DQBUF)
3064aa32f4c0SHans Verkuil 			trace_v4l2_dqbuf(video_devdata(file)->minor, parg);
3065aa32f4c0SHans Verkuil 		else if (cmd == VIDIOC_QBUF)
3066aa32f4c0SHans Verkuil 			trace_v4l2_qbuf(video_devdata(file)->minor, parg);
3067aa32f4c0SHans Verkuil 	}
30685bc3cb74SMauro Carvalho Chehab 
30695bc3cb74SMauro Carvalho Chehab 	if (has_array_args) {
3070ba2d35c1SHans Verkuil 		*kernel_ptr = (void __force *)user_ptr;
30715bc3cb74SMauro Carvalho Chehab 		if (copy_to_user(user_ptr, mbuf, array_size))
30725bc3cb74SMauro Carvalho Chehab 			err = -EFAULT;
30735bc3cb74SMauro Carvalho Chehab 		goto out_array_args;
30745bc3cb74SMauro Carvalho Chehab 	}
3075043f77edSHans Verkuil 	/*
3076043f77edSHans Verkuil 	 * Some ioctls can return an error, but still have valid
3077043f77edSHans Verkuil 	 * results that must be returned.
3078043f77edSHans Verkuil 	 */
3079043f77edSHans Verkuil 	if (err < 0 && !always_copy)
30805bc3cb74SMauro Carvalho Chehab 		goto out;
30815bc3cb74SMauro Carvalho Chehab 
30825bc3cb74SMauro Carvalho Chehab out_array_args:
30835bc3cb74SMauro Carvalho Chehab 	/*  Copy results into user buffer  */
30845bc3cb74SMauro Carvalho Chehab 	switch (_IOC_DIR(cmd)) {
30855bc3cb74SMauro Carvalho Chehab 	case _IOC_READ:
30865bc3cb74SMauro Carvalho Chehab 	case (_IOC_WRITE | _IOC_READ):
3087f8a695c4SMauro Carvalho Chehab 		if (copy_to_user((void __user *)arg, parg, ioc_size))
30885bc3cb74SMauro Carvalho Chehab 			err = -EFAULT;
30895bc3cb74SMauro Carvalho Chehab 		break;
30905bc3cb74SMauro Carvalho Chehab 	}
30915bc3cb74SMauro Carvalho Chehab 
30925bc3cb74SMauro Carvalho Chehab out:
3093758d90e1STomasz Figa 	kvfree(mbuf);
30945bc3cb74SMauro Carvalho Chehab 	return err;
30955bc3cb74SMauro Carvalho Chehab }
30965bc3cb74SMauro Carvalho Chehab 
30975bc3cb74SMauro Carvalho Chehab long video_ioctl2(struct file *file,
30985bc3cb74SMauro Carvalho Chehab 	       unsigned int cmd, unsigned long arg)
30995bc3cb74SMauro Carvalho Chehab {
31005bc3cb74SMauro Carvalho Chehab 	return video_usercopy(file, cmd, arg, __video_do_ioctl);
31015bc3cb74SMauro Carvalho Chehab }
31025bc3cb74SMauro Carvalho Chehab EXPORT_SYMBOL(video_ioctl2);
3103