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
915bc3cb74SMauro Carvalho Chehab 	   64 bit comparations. 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;
1245bc3cb74SMauro Carvalho Chehab 	strlcpy(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",
1975bc3cb74SMauro Carvalho Chehab };
1985bc3cb74SMauro Carvalho Chehab EXPORT_SYMBOL(v4l2_type_names);
1995bc3cb74SMauro Carvalho Chehab 
2005bc3cb74SMauro Carvalho Chehab static const char *v4l2_memory_names[] = {
2015bc3cb74SMauro Carvalho Chehab 	[V4L2_MEMORY_MMAP]    = "mmap",
2025bc3cb74SMauro Carvalho Chehab 	[V4L2_MEMORY_USERPTR] = "userptr",
2035bc3cb74SMauro Carvalho Chehab 	[V4L2_MEMORY_OVERLAY] = "overlay",
204051c7788SSumit Semwal 	[V4L2_MEMORY_DMABUF] = "dmabuf",
2055bc3cb74SMauro Carvalho Chehab };
2065bc3cb74SMauro Carvalho Chehab 
207d9246240SHans Verkuil #define prt_names(a, arr) (((unsigned)(a)) < ARRAY_SIZE(arr) ? arr[a] : "unknown")
2085bc3cb74SMauro Carvalho Chehab 
2095bc3cb74SMauro Carvalho Chehab /* ------------------------------------------------------------------ */
2105bc3cb74SMauro Carvalho Chehab /* debug help functions                                               */
2115bc3cb74SMauro Carvalho Chehab 
2125bc3cb74SMauro Carvalho Chehab static void v4l_print_querycap(const void *arg, bool write_only)
2135bc3cb74SMauro Carvalho Chehab {
2145bc3cb74SMauro Carvalho Chehab 	const struct v4l2_capability *p = arg;
2155bc3cb74SMauro Carvalho Chehab 
2168720427cSMauro Carvalho Chehab 	pr_cont("driver=%.*s, card=%.*s, bus=%.*s, version=0x%08x, capabilities=0x%08x, device_caps=0x%08x\n",
21727d5a87cSHans Verkuil 		(int)sizeof(p->driver), p->driver,
21827d5a87cSHans Verkuil 		(int)sizeof(p->card), p->card,
21927d5a87cSHans Verkuil 		(int)sizeof(p->bus_info), p->bus_info,
2205bc3cb74SMauro Carvalho Chehab 		p->version, p->capabilities, p->device_caps);
2215bc3cb74SMauro Carvalho Chehab }
2225bc3cb74SMauro Carvalho Chehab 
2235bc3cb74SMauro Carvalho Chehab static void v4l_print_enuminput(const void *arg, bool write_only)
2245bc3cb74SMauro Carvalho Chehab {
2255bc3cb74SMauro Carvalho Chehab 	const struct v4l2_input *p = arg;
2265bc3cb74SMauro Carvalho Chehab 
2278720427cSMauro 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",
22827d5a87cSHans Verkuil 		p->index, (int)sizeof(p->name), p->name, p->type, p->audioset,
22927d5a87cSHans Verkuil 		p->tuner, (unsigned long long)p->std, p->status,
23027d5a87cSHans Verkuil 		p->capabilities);
2315bc3cb74SMauro Carvalho Chehab }
2325bc3cb74SMauro Carvalho Chehab 
2335bc3cb74SMauro Carvalho Chehab static void v4l_print_enumoutput(const void *arg, bool write_only)
2345bc3cb74SMauro Carvalho Chehab {
2355bc3cb74SMauro Carvalho Chehab 	const struct v4l2_output *p = arg;
2365bc3cb74SMauro Carvalho Chehab 
2378720427cSMauro Carvalho Chehab 	pr_cont("index=%u, name=%.*s, type=%u, audioset=0x%x, modulator=%u, std=0x%08Lx, capabilities=0x%x\n",
23827d5a87cSHans Verkuil 		p->index, (int)sizeof(p->name), p->name, p->type, p->audioset,
23927d5a87cSHans Verkuil 		p->modulator, (unsigned long long)p->std, p->capabilities);
2405bc3cb74SMauro Carvalho Chehab }
2415bc3cb74SMauro Carvalho Chehab 
2425bc3cb74SMauro Carvalho Chehab static void v4l_print_audio(const void *arg, bool write_only)
2435bc3cb74SMauro Carvalho Chehab {
2445bc3cb74SMauro Carvalho Chehab 	const struct v4l2_audio *p = arg;
2455bc3cb74SMauro Carvalho Chehab 
2465bc3cb74SMauro Carvalho Chehab 	if (write_only)
2475bc3cb74SMauro Carvalho Chehab 		pr_cont("index=%u, mode=0x%x\n", p->index, p->mode);
2485bc3cb74SMauro Carvalho Chehab 	else
24927d5a87cSHans Verkuil 		pr_cont("index=%u, name=%.*s, capability=0x%x, mode=0x%x\n",
25027d5a87cSHans Verkuil 			p->index, (int)sizeof(p->name), p->name,
25127d5a87cSHans Verkuil 			p->capability, p->mode);
2525bc3cb74SMauro Carvalho Chehab }
2535bc3cb74SMauro Carvalho Chehab 
2545bc3cb74SMauro Carvalho Chehab static void v4l_print_audioout(const void *arg, bool write_only)
2555bc3cb74SMauro Carvalho Chehab {
2565bc3cb74SMauro Carvalho Chehab 	const struct v4l2_audioout *p = arg;
2575bc3cb74SMauro Carvalho Chehab 
2585bc3cb74SMauro Carvalho Chehab 	if (write_only)
2595bc3cb74SMauro Carvalho Chehab 		pr_cont("index=%u\n", p->index);
2605bc3cb74SMauro Carvalho Chehab 	else
26127d5a87cSHans Verkuil 		pr_cont("index=%u, name=%.*s, capability=0x%x, mode=0x%x\n",
26227d5a87cSHans Verkuil 			p->index, (int)sizeof(p->name), p->name,
26327d5a87cSHans Verkuil 			p->capability, p->mode);
2645bc3cb74SMauro Carvalho Chehab }
2655bc3cb74SMauro Carvalho Chehab 
2665bc3cb74SMauro Carvalho Chehab static void v4l_print_fmtdesc(const void *arg, bool write_only)
2675bc3cb74SMauro Carvalho Chehab {
2685bc3cb74SMauro Carvalho Chehab 	const struct v4l2_fmtdesc *p = arg;
2695bc3cb74SMauro Carvalho Chehab 
27027d5a87cSHans Verkuil 	pr_cont("index=%u, type=%s, flags=0x%x, pixelformat=%c%c%c%c, description='%.*s'\n",
2715bc3cb74SMauro Carvalho Chehab 		p->index, prt_names(p->type, v4l2_type_names),
2725bc3cb74SMauro Carvalho Chehab 		p->flags, (p->pixelformat & 0xff),
2735bc3cb74SMauro Carvalho Chehab 		(p->pixelformat >>  8) & 0xff,
2745bc3cb74SMauro Carvalho Chehab 		(p->pixelformat >> 16) & 0xff,
2755bc3cb74SMauro Carvalho Chehab 		(p->pixelformat >> 24) & 0xff,
27627d5a87cSHans Verkuil 		(int)sizeof(p->description), p->description);
2775bc3cb74SMauro Carvalho Chehab }
2785bc3cb74SMauro Carvalho Chehab 
2795bc3cb74SMauro Carvalho Chehab static void v4l_print_format(const void *arg, bool write_only)
2805bc3cb74SMauro Carvalho Chehab {
2815bc3cb74SMauro Carvalho Chehab 	const struct v4l2_format *p = arg;
2825bc3cb74SMauro Carvalho Chehab 	const struct v4l2_pix_format *pix;
2835bc3cb74SMauro Carvalho Chehab 	const struct v4l2_pix_format_mplane *mp;
2845bc3cb74SMauro Carvalho Chehab 	const struct v4l2_vbi_format *vbi;
2855bc3cb74SMauro Carvalho Chehab 	const struct v4l2_sliced_vbi_format *sliced;
2865bc3cb74SMauro Carvalho Chehab 	const struct v4l2_window *win;
28787185c95SAntti Palosaari 	const struct v4l2_sdr_format *sdr;
288fb9ffa6aSLaurent Pinchart 	const struct v4l2_meta_format *meta;
2895bc3cb74SMauro Carvalho Chehab 	unsigned i;
2905bc3cb74SMauro Carvalho Chehab 
2915bc3cb74SMauro Carvalho Chehab 	pr_cont("type=%s", prt_names(p->type, v4l2_type_names));
2925bc3cb74SMauro Carvalho Chehab 	switch (p->type) {
2935bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_CAPTURE:
2945bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_OUTPUT:
2955bc3cb74SMauro Carvalho Chehab 		pix = &p->fmt.pix;
2968720427cSMauro 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",
2975bc3cb74SMauro Carvalho Chehab 			pix->width, pix->height,
2985bc3cb74SMauro Carvalho Chehab 			(pix->pixelformat & 0xff),
2995bc3cb74SMauro Carvalho Chehab 			(pix->pixelformat >>  8) & 0xff,
3005bc3cb74SMauro Carvalho Chehab 			(pix->pixelformat >> 16) & 0xff,
3015bc3cb74SMauro Carvalho Chehab 			(pix->pixelformat >> 24) & 0xff,
3025bc3cb74SMauro Carvalho Chehab 			prt_names(pix->field, v4l2_field_names),
3035bc3cb74SMauro Carvalho Chehab 			pix->bytesperline, pix->sizeimage,
304736d96b5SHans Verkuil 			pix->colorspace, pix->flags, pix->ycbcr_enc,
30574fdcb2eSHans Verkuil 			pix->quantization, pix->xfer_func);
3065bc3cb74SMauro Carvalho Chehab 		break;
3075bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
3085bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
3095bc3cb74SMauro Carvalho Chehab 		mp = &p->fmt.pix_mp;
3108720427cSMauro 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",
3115bc3cb74SMauro Carvalho Chehab 			mp->width, mp->height,
3125bc3cb74SMauro Carvalho Chehab 			(mp->pixelformat & 0xff),
3135bc3cb74SMauro Carvalho Chehab 			(mp->pixelformat >>  8) & 0xff,
3145bc3cb74SMauro Carvalho Chehab 			(mp->pixelformat >> 16) & 0xff,
3155bc3cb74SMauro Carvalho Chehab 			(mp->pixelformat >> 24) & 0xff,
3165bc3cb74SMauro Carvalho Chehab 			prt_names(mp->field, v4l2_field_names),
317736d96b5SHans Verkuil 			mp->colorspace, mp->num_planes, mp->flags,
31874fdcb2eSHans Verkuil 			mp->ycbcr_enc, mp->quantization, mp->xfer_func);
3195bc3cb74SMauro Carvalho Chehab 		for (i = 0; i < mp->num_planes; i++)
3205bc3cb74SMauro Carvalho Chehab 			printk(KERN_DEBUG "plane %u: bytesperline=%u sizeimage=%u\n", i,
3215bc3cb74SMauro Carvalho Chehab 					mp->plane_fmt[i].bytesperline,
3225bc3cb74SMauro Carvalho Chehab 					mp->plane_fmt[i].sizeimage);
3235bc3cb74SMauro Carvalho Chehab 		break;
3245bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_OVERLAY:
3255bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
3265bc3cb74SMauro Carvalho Chehab 		win = &p->fmt.win;
327560dde24SHans Verkuil 		/* Note: we can't print the clip list here since the clips
328560dde24SHans Verkuil 		 * pointer is a userspace pointer, not a kernelspace
329560dde24SHans Verkuil 		 * pointer. */
330560dde24SHans 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",
331560dde24SHans Verkuil 			win->w.width, win->w.height, win->w.left, win->w.top,
3325bc3cb74SMauro Carvalho Chehab 			prt_names(win->field, v4l2_field_names),
333560dde24SHans Verkuil 			win->chromakey, win->clipcount, win->clips,
334560dde24SHans Verkuil 			win->bitmap, win->global_alpha);
3355bc3cb74SMauro Carvalho Chehab 		break;
3365bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VBI_CAPTURE:
3375bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VBI_OUTPUT:
3385bc3cb74SMauro Carvalho Chehab 		vbi = &p->fmt.vbi;
3398720427cSMauro 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",
3405bc3cb74SMauro Carvalho Chehab 			vbi->sampling_rate, vbi->offset,
3415bc3cb74SMauro Carvalho Chehab 			vbi->samples_per_line,
3425bc3cb74SMauro Carvalho Chehab 			(vbi->sample_format & 0xff),
3435bc3cb74SMauro Carvalho Chehab 			(vbi->sample_format >>  8) & 0xff,
3445bc3cb74SMauro Carvalho Chehab 			(vbi->sample_format >> 16) & 0xff,
3455bc3cb74SMauro Carvalho Chehab 			(vbi->sample_format >> 24) & 0xff,
3465bc3cb74SMauro Carvalho Chehab 			vbi->start[0], vbi->start[1],
3475bc3cb74SMauro Carvalho Chehab 			vbi->count[0], vbi->count[1]);
3485bc3cb74SMauro Carvalho Chehab 		break;
3495bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
3505bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
3515bc3cb74SMauro Carvalho Chehab 		sliced = &p->fmt.sliced;
3525bc3cb74SMauro Carvalho Chehab 		pr_cont(", service_set=0x%08x, io_size=%d\n",
3535bc3cb74SMauro Carvalho Chehab 				sliced->service_set, sliced->io_size);
3545bc3cb74SMauro Carvalho Chehab 		for (i = 0; i < 24; i++)
3555bc3cb74SMauro Carvalho Chehab 			printk(KERN_DEBUG "line[%02u]=0x%04x, 0x%04x\n", i,
3565bc3cb74SMauro Carvalho Chehab 				sliced->service_lines[0][i],
3575bc3cb74SMauro Carvalho Chehab 				sliced->service_lines[1][i]);
3585bc3cb74SMauro Carvalho Chehab 		break;
359582c52cbSAntti Palosaari 	case V4L2_BUF_TYPE_SDR_CAPTURE:
3609effc72fSAntti Palosaari 	case V4L2_BUF_TYPE_SDR_OUTPUT:
361582c52cbSAntti Palosaari 		sdr = &p->fmt.sdr;
362582c52cbSAntti Palosaari 		pr_cont(", pixelformat=%c%c%c%c\n",
363582c52cbSAntti Palosaari 			(sdr->pixelformat >>  0) & 0xff,
364582c52cbSAntti Palosaari 			(sdr->pixelformat >>  8) & 0xff,
365582c52cbSAntti Palosaari 			(sdr->pixelformat >> 16) & 0xff,
366582c52cbSAntti Palosaari 			(sdr->pixelformat >> 24) & 0xff);
367582c52cbSAntti Palosaari 		break;
368fb9ffa6aSLaurent Pinchart 	case V4L2_BUF_TYPE_META_CAPTURE:
369fb9ffa6aSLaurent Pinchart 		meta = &p->fmt.meta;
370fb9ffa6aSLaurent Pinchart 		pr_cont(", dataformat=%c%c%c%c, buffersize=%u\n",
371fb9ffa6aSLaurent Pinchart 			(meta->dataformat >>  0) & 0xff,
372fb9ffa6aSLaurent Pinchart 			(meta->dataformat >>  8) & 0xff,
373fb9ffa6aSLaurent Pinchart 			(meta->dataformat >> 16) & 0xff,
374fb9ffa6aSLaurent Pinchart 			(meta->dataformat >> 24) & 0xff,
375fb9ffa6aSLaurent Pinchart 			meta->buffersize);
376fb9ffa6aSLaurent Pinchart 		break;
3775bc3cb74SMauro Carvalho Chehab 	}
3785bc3cb74SMauro Carvalho Chehab }
3795bc3cb74SMauro Carvalho Chehab 
3805bc3cb74SMauro Carvalho Chehab static void v4l_print_framebuffer(const void *arg, bool write_only)
3815bc3cb74SMauro Carvalho Chehab {
3825bc3cb74SMauro Carvalho Chehab 	const struct v4l2_framebuffer *p = arg;
3835bc3cb74SMauro Carvalho Chehab 
3848720427cSMauro 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",
3855bc3cb74SMauro Carvalho Chehab 			p->capability, p->flags, p->base,
3865bc3cb74SMauro Carvalho Chehab 			p->fmt.width, p->fmt.height,
3875bc3cb74SMauro Carvalho Chehab 			(p->fmt.pixelformat & 0xff),
3885bc3cb74SMauro Carvalho Chehab 			(p->fmt.pixelformat >>  8) & 0xff,
3895bc3cb74SMauro Carvalho Chehab 			(p->fmt.pixelformat >> 16) & 0xff,
3905bc3cb74SMauro Carvalho Chehab 			(p->fmt.pixelformat >> 24) & 0xff,
3915bc3cb74SMauro Carvalho Chehab 			p->fmt.bytesperline, p->fmt.sizeimage,
3925bc3cb74SMauro Carvalho Chehab 			p->fmt.colorspace);
3935bc3cb74SMauro Carvalho Chehab }
3945bc3cb74SMauro Carvalho Chehab 
3955bc3cb74SMauro Carvalho Chehab static void v4l_print_buftype(const void *arg, bool write_only)
3965bc3cb74SMauro Carvalho Chehab {
3975bc3cb74SMauro Carvalho Chehab 	pr_cont("type=%s\n", prt_names(*(u32 *)arg, v4l2_type_names));
3985bc3cb74SMauro Carvalho Chehab }
3995bc3cb74SMauro Carvalho Chehab 
4005bc3cb74SMauro Carvalho Chehab static void v4l_print_modulator(const void *arg, bool write_only)
4015bc3cb74SMauro Carvalho Chehab {
4025bc3cb74SMauro Carvalho Chehab 	const struct v4l2_modulator *p = arg;
4035bc3cb74SMauro Carvalho Chehab 
4045bc3cb74SMauro Carvalho Chehab 	if (write_only)
405560dde24SHans Verkuil 		pr_cont("index=%u, txsubchans=0x%x\n", p->index, p->txsubchans);
4065bc3cb74SMauro Carvalho Chehab 	else
4078720427cSMauro Carvalho Chehab 		pr_cont("index=%u, name=%.*s, capability=0x%x, rangelow=%u, rangehigh=%u, txsubchans=0x%x\n",
40827d5a87cSHans Verkuil 			p->index, (int)sizeof(p->name), p->name, p->capability,
4095bc3cb74SMauro Carvalho Chehab 			p->rangelow, p->rangehigh, p->txsubchans);
4105bc3cb74SMauro Carvalho Chehab }
4115bc3cb74SMauro Carvalho Chehab 
4125bc3cb74SMauro Carvalho Chehab static void v4l_print_tuner(const void *arg, bool write_only)
4135bc3cb74SMauro Carvalho Chehab {
4145bc3cb74SMauro Carvalho Chehab 	const struct v4l2_tuner *p = arg;
4155bc3cb74SMauro Carvalho Chehab 
4165bc3cb74SMauro Carvalho Chehab 	if (write_only)
4175bc3cb74SMauro Carvalho Chehab 		pr_cont("index=%u, audmode=%u\n", p->index, p->audmode);
4185bc3cb74SMauro Carvalho Chehab 	else
4198720427cSMauro 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",
42027d5a87cSHans Verkuil 			p->index, (int)sizeof(p->name), p->name, p->type,
4215bc3cb74SMauro Carvalho Chehab 			p->capability, p->rangelow,
4225bc3cb74SMauro Carvalho Chehab 			p->rangehigh, p->signal, p->afc,
4235bc3cb74SMauro Carvalho Chehab 			p->rxsubchans, p->audmode);
4245bc3cb74SMauro Carvalho Chehab }
4255bc3cb74SMauro Carvalho Chehab 
4265bc3cb74SMauro Carvalho Chehab static void v4l_print_frequency(const void *arg, bool write_only)
4275bc3cb74SMauro Carvalho Chehab {
4285bc3cb74SMauro Carvalho Chehab 	const struct v4l2_frequency *p = arg;
4295bc3cb74SMauro Carvalho Chehab 
4305bc3cb74SMauro Carvalho Chehab 	pr_cont("tuner=%u, type=%u, frequency=%u\n",
4315bc3cb74SMauro Carvalho Chehab 				p->tuner, p->type, p->frequency);
4325bc3cb74SMauro Carvalho Chehab }
4335bc3cb74SMauro Carvalho Chehab 
4345bc3cb74SMauro Carvalho Chehab static void v4l_print_standard(const void *arg, bool write_only)
4355bc3cb74SMauro Carvalho Chehab {
4365bc3cb74SMauro Carvalho Chehab 	const struct v4l2_standard *p = arg;
4375bc3cb74SMauro Carvalho Chehab 
4388720427cSMauro Carvalho Chehab 	pr_cont("index=%u, id=0x%Lx, name=%.*s, fps=%u/%u, framelines=%u\n",
4398720427cSMauro Carvalho Chehab 		p->index,
44027d5a87cSHans Verkuil 		(unsigned long long)p->id, (int)sizeof(p->name), p->name,
4415bc3cb74SMauro Carvalho Chehab 		p->frameperiod.numerator,
4425bc3cb74SMauro Carvalho Chehab 		p->frameperiod.denominator,
4435bc3cb74SMauro Carvalho Chehab 		p->framelines);
4445bc3cb74SMauro Carvalho Chehab }
4455bc3cb74SMauro Carvalho Chehab 
4465bc3cb74SMauro Carvalho Chehab static void v4l_print_std(const void *arg, bool write_only)
4475bc3cb74SMauro Carvalho Chehab {
4485bc3cb74SMauro Carvalho Chehab 	pr_cont("std=0x%08Lx\n", *(const long long unsigned *)arg);
4495bc3cb74SMauro Carvalho Chehab }
4505bc3cb74SMauro Carvalho Chehab 
4515bc3cb74SMauro Carvalho Chehab static void v4l_print_hw_freq_seek(const void *arg, bool write_only)
4525bc3cb74SMauro Carvalho Chehab {
4535bc3cb74SMauro Carvalho Chehab 	const struct v4l2_hw_freq_seek *p = arg;
4545bc3cb74SMauro Carvalho Chehab 
4558720427cSMauro Carvalho Chehab 	pr_cont("tuner=%u, type=%u, seek_upward=%u, wrap_around=%u, spacing=%u, rangelow=%u, rangehigh=%u\n",
45679e8c7beSMauro Carvalho Chehab 		p->tuner, p->type, p->seek_upward, p->wrap_around, p->spacing,
45779e8c7beSMauro Carvalho Chehab 		p->rangelow, p->rangehigh);
4585bc3cb74SMauro Carvalho Chehab }
4595bc3cb74SMauro Carvalho Chehab 
4605bc3cb74SMauro Carvalho Chehab static void v4l_print_requestbuffers(const void *arg, bool write_only)
4615bc3cb74SMauro Carvalho Chehab {
4625bc3cb74SMauro Carvalho Chehab 	const struct v4l2_requestbuffers *p = arg;
4635bc3cb74SMauro Carvalho Chehab 
4645bc3cb74SMauro Carvalho Chehab 	pr_cont("count=%d, type=%s, memory=%s\n",
4655bc3cb74SMauro Carvalho Chehab 		p->count,
4665bc3cb74SMauro Carvalho Chehab 		prt_names(p->type, v4l2_type_names),
4675bc3cb74SMauro Carvalho Chehab 		prt_names(p->memory, v4l2_memory_names));
4685bc3cb74SMauro Carvalho Chehab }
4695bc3cb74SMauro Carvalho Chehab 
4705bc3cb74SMauro Carvalho Chehab static void v4l_print_buffer(const void *arg, bool write_only)
4715bc3cb74SMauro Carvalho Chehab {
4725bc3cb74SMauro Carvalho Chehab 	const struct v4l2_buffer *p = arg;
4735bc3cb74SMauro Carvalho Chehab 	const struct v4l2_timecode *tc = &p->timecode;
4745bc3cb74SMauro Carvalho Chehab 	const struct v4l2_plane *plane;
4755bc3cb74SMauro Carvalho Chehab 	int i;
4765bc3cb74SMauro Carvalho Chehab 
4778720427cSMauro Carvalho Chehab 	pr_cont("%02ld:%02d:%02d.%08ld index=%d, type=%s, flags=0x%08x, field=%s, sequence=%d, memory=%s",
4785bc3cb74SMauro Carvalho Chehab 			p->timestamp.tv_sec / 3600,
4795bc3cb74SMauro Carvalho Chehab 			(int)(p->timestamp.tv_sec / 60) % 60,
4805bc3cb74SMauro Carvalho Chehab 			(int)(p->timestamp.tv_sec % 60),
4815bc3cb74SMauro Carvalho Chehab 			(long)p->timestamp.tv_usec,
4825bc3cb74SMauro Carvalho Chehab 			p->index,
4835bc3cb74SMauro Carvalho Chehab 			prt_names(p->type, v4l2_type_names),
4845bc3cb74SMauro Carvalho Chehab 			p->flags, prt_names(p->field, v4l2_field_names),
4855bc3cb74SMauro Carvalho Chehab 			p->sequence, prt_names(p->memory, v4l2_memory_names));
4865bc3cb74SMauro Carvalho Chehab 
4875bc3cb74SMauro Carvalho Chehab 	if (V4L2_TYPE_IS_MULTIPLANAR(p->type) && p->m.planes) {
4885bc3cb74SMauro Carvalho Chehab 		pr_cont("\n");
4895bc3cb74SMauro Carvalho Chehab 		for (i = 0; i < p->length; ++i) {
4905bc3cb74SMauro Carvalho Chehab 			plane = &p->m.planes[i];
4915bc3cb74SMauro Carvalho Chehab 			printk(KERN_DEBUG
4928720427cSMauro Carvalho Chehab 				"plane %d: bytesused=%d, data_offset=0x%08x, offset/userptr=0x%lx, length=%d\n",
4935bc3cb74SMauro Carvalho Chehab 				i, plane->bytesused, plane->data_offset,
4945bc3cb74SMauro Carvalho Chehab 				plane->m.userptr, plane->length);
4955bc3cb74SMauro Carvalho Chehab 		}
4965bc3cb74SMauro Carvalho Chehab 	} else {
497560dde24SHans Verkuil 		pr_cont(", bytesused=%d, offset/userptr=0x%lx, length=%d\n",
4985bc3cb74SMauro Carvalho Chehab 			p->bytesused, p->m.userptr, p->length);
4995bc3cb74SMauro Carvalho Chehab 	}
5005bc3cb74SMauro Carvalho Chehab 
5018720427cSMauro Carvalho Chehab 	printk(KERN_DEBUG "timecode=%02d:%02d:%02d type=%d, flags=0x%08x, frames=%d, userbits=0x%08x\n",
5025bc3cb74SMauro Carvalho Chehab 			tc->hours, tc->minutes, tc->seconds,
5035bc3cb74SMauro Carvalho Chehab 			tc->type, tc->flags, tc->frames, *(__u32 *)tc->userbits);
5045bc3cb74SMauro Carvalho Chehab }
5055bc3cb74SMauro Carvalho Chehab 
506b799d09aSTomasz Stanislawski static void v4l_print_exportbuffer(const void *arg, bool write_only)
507b799d09aSTomasz Stanislawski {
508b799d09aSTomasz Stanislawski 	const struct v4l2_exportbuffer *p = arg;
509b799d09aSTomasz Stanislawski 
510b799d09aSTomasz Stanislawski 	pr_cont("fd=%d, type=%s, index=%u, plane=%u, flags=0x%08x\n",
511b799d09aSTomasz Stanislawski 		p->fd, prt_names(p->type, v4l2_type_names),
512b799d09aSTomasz Stanislawski 		p->index, p->plane, p->flags);
513b799d09aSTomasz Stanislawski }
514b799d09aSTomasz Stanislawski 
5155bc3cb74SMauro Carvalho Chehab static void v4l_print_create_buffers(const void *arg, bool write_only)
5165bc3cb74SMauro Carvalho Chehab {
5175bc3cb74SMauro Carvalho Chehab 	const struct v4l2_create_buffers *p = arg;
5185bc3cb74SMauro Carvalho Chehab 
5195bc3cb74SMauro Carvalho Chehab 	pr_cont("index=%d, count=%d, memory=%s, ",
5205bc3cb74SMauro Carvalho Chehab 			p->index, p->count,
5215bc3cb74SMauro Carvalho Chehab 			prt_names(p->memory, v4l2_memory_names));
5225bc3cb74SMauro Carvalho Chehab 	v4l_print_format(&p->format, write_only);
5235bc3cb74SMauro Carvalho Chehab }
5245bc3cb74SMauro Carvalho Chehab 
5255bc3cb74SMauro Carvalho Chehab static void v4l_print_streamparm(const void *arg, bool write_only)
5265bc3cb74SMauro Carvalho Chehab {
5275bc3cb74SMauro Carvalho Chehab 	const struct v4l2_streamparm *p = arg;
5285bc3cb74SMauro Carvalho Chehab 
5295bc3cb74SMauro Carvalho Chehab 	pr_cont("type=%s", prt_names(p->type, v4l2_type_names));
5305bc3cb74SMauro Carvalho Chehab 
5315bc3cb74SMauro Carvalho Chehab 	if (p->type == V4L2_BUF_TYPE_VIDEO_CAPTURE ||
5325bc3cb74SMauro Carvalho Chehab 	    p->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
5335bc3cb74SMauro Carvalho Chehab 		const struct v4l2_captureparm *c = &p->parm.capture;
5345bc3cb74SMauro Carvalho Chehab 
5358720427cSMauro Carvalho Chehab 		pr_cont(", capability=0x%x, capturemode=0x%x, timeperframe=%d/%d, extendedmode=%d, readbuffers=%d\n",
5365bc3cb74SMauro Carvalho Chehab 			c->capability, c->capturemode,
5375bc3cb74SMauro Carvalho Chehab 			c->timeperframe.numerator, c->timeperframe.denominator,
5385bc3cb74SMauro Carvalho Chehab 			c->extendedmode, c->readbuffers);
5395bc3cb74SMauro Carvalho Chehab 	} else if (p->type == V4L2_BUF_TYPE_VIDEO_OUTPUT ||
5405bc3cb74SMauro Carvalho Chehab 		   p->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
5415bc3cb74SMauro Carvalho Chehab 		const struct v4l2_outputparm *c = &p->parm.output;
5425bc3cb74SMauro Carvalho Chehab 
5438720427cSMauro Carvalho Chehab 		pr_cont(", capability=0x%x, outputmode=0x%x, timeperframe=%d/%d, extendedmode=%d, writebuffers=%d\n",
5445bc3cb74SMauro Carvalho Chehab 			c->capability, c->outputmode,
5455bc3cb74SMauro Carvalho Chehab 			c->timeperframe.numerator, c->timeperframe.denominator,
5465bc3cb74SMauro Carvalho Chehab 			c->extendedmode, c->writebuffers);
547560dde24SHans Verkuil 	} else {
548560dde24SHans Verkuil 		pr_cont("\n");
5495bc3cb74SMauro Carvalho Chehab 	}
5505bc3cb74SMauro Carvalho Chehab }
5515bc3cb74SMauro Carvalho Chehab 
5525bc3cb74SMauro Carvalho Chehab static void v4l_print_queryctrl(const void *arg, bool write_only)
5535bc3cb74SMauro Carvalho Chehab {
5545bc3cb74SMauro Carvalho Chehab 	const struct v4l2_queryctrl *p = arg;
5555bc3cb74SMauro Carvalho Chehab 
5568720427cSMauro Carvalho Chehab 	pr_cont("id=0x%x, type=%d, name=%.*s, min/max=%d/%d, step=%d, default=%d, flags=0x%08x\n",
55727d5a87cSHans Verkuil 			p->id, p->type, (int)sizeof(p->name), p->name,
5585bc3cb74SMauro Carvalho Chehab 			p->minimum, p->maximum,
5595bc3cb74SMauro Carvalho Chehab 			p->step, p->default_value, p->flags);
5605bc3cb74SMauro Carvalho Chehab }
5615bc3cb74SMauro Carvalho Chehab 
562e6bee368SHans Verkuil static void v4l_print_query_ext_ctrl(const void *arg, bool write_only)
563e6bee368SHans Verkuil {
564e6bee368SHans Verkuil 	const struct v4l2_query_ext_ctrl *p = arg;
565e6bee368SHans Verkuil 
5668720427cSMauro 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",
567e6bee368SHans Verkuil 			p->id, p->type, (int)sizeof(p->name), p->name,
568e6bee368SHans Verkuil 			p->minimum, p->maximum,
569e6bee368SHans Verkuil 			p->step, p->default_value, p->flags,
570e6bee368SHans Verkuil 			p->elem_size, p->elems, p->nr_of_dims,
5710176077aSHans Verkuil 			p->dims[0], p->dims[1], p->dims[2], p->dims[3]);
572e6bee368SHans Verkuil }
573e6bee368SHans Verkuil 
5745bc3cb74SMauro Carvalho Chehab static void v4l_print_querymenu(const void *arg, bool write_only)
5755bc3cb74SMauro Carvalho Chehab {
5765bc3cb74SMauro Carvalho Chehab 	const struct v4l2_querymenu *p = arg;
5775bc3cb74SMauro Carvalho Chehab 
5785bc3cb74SMauro Carvalho Chehab 	pr_cont("id=0x%x, index=%d\n", p->id, p->index);
5795bc3cb74SMauro Carvalho Chehab }
5805bc3cb74SMauro Carvalho Chehab 
5815bc3cb74SMauro Carvalho Chehab static void v4l_print_control(const void *arg, bool write_only)
5825bc3cb74SMauro Carvalho Chehab {
5835bc3cb74SMauro Carvalho Chehab 	const struct v4l2_control *p = arg;
5845bc3cb74SMauro Carvalho Chehab 
5855bc3cb74SMauro Carvalho Chehab 	pr_cont("id=0x%x, value=%d\n", p->id, p->value);
5865bc3cb74SMauro Carvalho Chehab }
5875bc3cb74SMauro Carvalho Chehab 
5885bc3cb74SMauro Carvalho Chehab static void v4l_print_ext_controls(const void *arg, bool write_only)
5895bc3cb74SMauro Carvalho Chehab {
5905bc3cb74SMauro Carvalho Chehab 	const struct v4l2_ext_controls *p = arg;
5915bc3cb74SMauro Carvalho Chehab 	int i;
5925bc3cb74SMauro Carvalho Chehab 
5930f8017beSRicardo Ribalda 	pr_cont("which=0x%x, count=%d, error_idx=%d",
5940f8017beSRicardo Ribalda 			p->which, p->count, p->error_idx);
5955bc3cb74SMauro Carvalho Chehab 	for (i = 0; i < p->count; i++) {
596017ab36aSHans Verkuil 		if (!p->controls[i].size)
5975bc3cb74SMauro Carvalho Chehab 			pr_cont(", id/val=0x%x/0x%x",
5985bc3cb74SMauro Carvalho Chehab 				p->controls[i].id, p->controls[i].value);
5995bc3cb74SMauro Carvalho Chehab 		else
6005bc3cb74SMauro Carvalho Chehab 			pr_cont(", id/size=0x%x/%u",
6015bc3cb74SMauro Carvalho Chehab 				p->controls[i].id, p->controls[i].size);
6025bc3cb74SMauro Carvalho Chehab 	}
6035bc3cb74SMauro Carvalho Chehab 	pr_cont("\n");
6045bc3cb74SMauro Carvalho Chehab }
6055bc3cb74SMauro Carvalho Chehab 
6065bc3cb74SMauro Carvalho Chehab static void v4l_print_cropcap(const void *arg, bool write_only)
6075bc3cb74SMauro Carvalho Chehab {
6085bc3cb74SMauro Carvalho Chehab 	const struct v4l2_cropcap *p = arg;
6095bc3cb74SMauro Carvalho Chehab 
6108720427cSMauro 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",
6115bc3cb74SMauro Carvalho Chehab 		prt_names(p->type, v4l2_type_names),
6125bc3cb74SMauro Carvalho Chehab 		p->bounds.width, p->bounds.height,
6135bc3cb74SMauro Carvalho Chehab 		p->bounds.left, p->bounds.top,
6145bc3cb74SMauro Carvalho Chehab 		p->defrect.width, p->defrect.height,
6155bc3cb74SMauro Carvalho Chehab 		p->defrect.left, p->defrect.top,
6165bc3cb74SMauro Carvalho Chehab 		p->pixelaspect.numerator, p->pixelaspect.denominator);
6175bc3cb74SMauro Carvalho Chehab }
6185bc3cb74SMauro Carvalho Chehab 
6195bc3cb74SMauro Carvalho Chehab static void v4l_print_crop(const void *arg, bool write_only)
6205bc3cb74SMauro Carvalho Chehab {
6215bc3cb74SMauro Carvalho Chehab 	const struct v4l2_crop *p = arg;
6225bc3cb74SMauro Carvalho Chehab 
6235bc3cb74SMauro Carvalho Chehab 	pr_cont("type=%s, wxh=%dx%d, x,y=%d,%d\n",
6245bc3cb74SMauro Carvalho Chehab 		prt_names(p->type, v4l2_type_names),
6255bc3cb74SMauro Carvalho Chehab 		p->c.width, p->c.height,
6265bc3cb74SMauro Carvalho Chehab 		p->c.left, p->c.top);
6275bc3cb74SMauro Carvalho Chehab }
6285bc3cb74SMauro Carvalho Chehab 
6295bc3cb74SMauro Carvalho Chehab static void v4l_print_selection(const void *arg, bool write_only)
6305bc3cb74SMauro Carvalho Chehab {
6315bc3cb74SMauro Carvalho Chehab 	const struct v4l2_selection *p = arg;
6325bc3cb74SMauro Carvalho Chehab 
6335bc3cb74SMauro Carvalho Chehab 	pr_cont("type=%s, target=%d, flags=0x%x, wxh=%dx%d, x,y=%d,%d\n",
6345bc3cb74SMauro Carvalho Chehab 		prt_names(p->type, v4l2_type_names),
6355bc3cb74SMauro Carvalho Chehab 		p->target, p->flags,
6365bc3cb74SMauro Carvalho Chehab 		p->r.width, p->r.height, p->r.left, p->r.top);
6375bc3cb74SMauro Carvalho Chehab }
6385bc3cb74SMauro Carvalho Chehab 
6395bc3cb74SMauro Carvalho Chehab static void v4l_print_jpegcompression(const void *arg, bool write_only)
6405bc3cb74SMauro Carvalho Chehab {
6415bc3cb74SMauro Carvalho Chehab 	const struct v4l2_jpegcompression *p = arg;
6425bc3cb74SMauro Carvalho Chehab 
6438720427cSMauro Carvalho Chehab 	pr_cont("quality=%d, APPn=%d, APP_len=%d, COM_len=%d, jpeg_markers=0x%x\n",
6445bc3cb74SMauro Carvalho Chehab 		p->quality, p->APPn, p->APP_len,
6455bc3cb74SMauro Carvalho Chehab 		p->COM_len, p->jpeg_markers);
6465bc3cb74SMauro Carvalho Chehab }
6475bc3cb74SMauro Carvalho Chehab 
6485bc3cb74SMauro Carvalho Chehab static void v4l_print_enc_idx(const void *arg, bool write_only)
6495bc3cb74SMauro Carvalho Chehab {
6505bc3cb74SMauro Carvalho Chehab 	const struct v4l2_enc_idx *p = arg;
6515bc3cb74SMauro Carvalho Chehab 
6525bc3cb74SMauro Carvalho Chehab 	pr_cont("entries=%d, entries_cap=%d\n",
6535bc3cb74SMauro Carvalho Chehab 			p->entries, p->entries_cap);
6545bc3cb74SMauro Carvalho Chehab }
6555bc3cb74SMauro Carvalho Chehab 
6565bc3cb74SMauro Carvalho Chehab static void v4l_print_encoder_cmd(const void *arg, bool write_only)
6575bc3cb74SMauro Carvalho Chehab {
6585bc3cb74SMauro Carvalho Chehab 	const struct v4l2_encoder_cmd *p = arg;
6595bc3cb74SMauro Carvalho Chehab 
6605bc3cb74SMauro Carvalho Chehab 	pr_cont("cmd=%d, flags=0x%x\n",
6615bc3cb74SMauro Carvalho Chehab 			p->cmd, p->flags);
6625bc3cb74SMauro Carvalho Chehab }
6635bc3cb74SMauro Carvalho Chehab 
6645bc3cb74SMauro Carvalho Chehab static void v4l_print_decoder_cmd(const void *arg, bool write_only)
6655bc3cb74SMauro Carvalho Chehab {
6665bc3cb74SMauro Carvalho Chehab 	const struct v4l2_decoder_cmd *p = arg;
6675bc3cb74SMauro Carvalho Chehab 
6685bc3cb74SMauro Carvalho Chehab 	pr_cont("cmd=%d, flags=0x%x\n", p->cmd, p->flags);
6695bc3cb74SMauro Carvalho Chehab 
6705bc3cb74SMauro Carvalho Chehab 	if (p->cmd == V4L2_DEC_CMD_START)
6715bc3cb74SMauro Carvalho Chehab 		pr_info("speed=%d, format=%u\n",
6725bc3cb74SMauro Carvalho Chehab 				p->start.speed, p->start.format);
6735bc3cb74SMauro Carvalho Chehab 	else if (p->cmd == V4L2_DEC_CMD_STOP)
6745bc3cb74SMauro Carvalho Chehab 		pr_info("pts=%llu\n", p->stop.pts);
6755bc3cb74SMauro Carvalho Chehab }
6765bc3cb74SMauro Carvalho Chehab 
67796b03d2aSHans Verkuil static void v4l_print_dbg_chip_info(const void *arg, bool write_only)
67879b0c640SHans Verkuil {
67996b03d2aSHans Verkuil 	const struct v4l2_dbg_chip_info *p = arg;
68079b0c640SHans Verkuil 
68179b0c640SHans Verkuil 	pr_cont("type=%u, ", p->match.type);
6823eef2510SHans Verkuil 	if (p->match.type == V4L2_CHIP_MATCH_I2C_DRIVER)
68379b0c640SHans Verkuil 		pr_cont("name=%.*s, ",
68479b0c640SHans Verkuil 				(int)sizeof(p->match.name), p->match.name);
68579b0c640SHans Verkuil 	else
68679b0c640SHans Verkuil 		pr_cont("addr=%u, ", p->match.addr);
68779b0c640SHans Verkuil 	pr_cont("name=%.*s\n", (int)sizeof(p->name), p->name);
68879b0c640SHans Verkuil }
68979b0c640SHans Verkuil 
6905bc3cb74SMauro Carvalho Chehab static void v4l_print_dbg_register(const void *arg, bool write_only)
6915bc3cb74SMauro Carvalho Chehab {
6925bc3cb74SMauro Carvalho Chehab 	const struct v4l2_dbg_register *p = arg;
6935bc3cb74SMauro Carvalho Chehab 
6945bc3cb74SMauro Carvalho Chehab 	pr_cont("type=%u, ", p->match.type);
6953eef2510SHans Verkuil 	if (p->match.type == V4L2_CHIP_MATCH_I2C_DRIVER)
69627d5a87cSHans Verkuil 		pr_cont("name=%.*s, ",
69727d5a87cSHans Verkuil 				(int)sizeof(p->match.name), p->match.name);
6985bc3cb74SMauro Carvalho Chehab 	else
6995bc3cb74SMauro Carvalho Chehab 		pr_cont("addr=%u, ", p->match.addr);
7005bc3cb74SMauro Carvalho Chehab 	pr_cont("reg=0x%llx, val=0x%llx\n",
7015bc3cb74SMauro Carvalho Chehab 			p->reg, p->val);
7025bc3cb74SMauro Carvalho Chehab }
7035bc3cb74SMauro Carvalho Chehab 
7045bc3cb74SMauro Carvalho Chehab static void v4l_print_dv_timings(const void *arg, bool write_only)
7055bc3cb74SMauro Carvalho Chehab {
7065bc3cb74SMauro Carvalho Chehab 	const struct v4l2_dv_timings *p = arg;
7075bc3cb74SMauro Carvalho Chehab 
7085bc3cb74SMauro Carvalho Chehab 	switch (p->type) {
7095bc3cb74SMauro Carvalho Chehab 	case V4L2_DV_BT_656_1120:
7108720427cSMauro 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",
7115bc3cb74SMauro Carvalho Chehab 				p->bt.interlaced, p->bt.pixelclock,
7125bc3cb74SMauro Carvalho Chehab 				p->bt.width, p->bt.height,
7135bc3cb74SMauro Carvalho Chehab 				p->bt.polarities, p->bt.hfrontporch,
7145bc3cb74SMauro Carvalho Chehab 				p->bt.hsync, p->bt.hbackporch,
7155bc3cb74SMauro Carvalho Chehab 				p->bt.vfrontporch, p->bt.vsync,
7165bc3cb74SMauro Carvalho Chehab 				p->bt.vbackporch, p->bt.il_vfrontporch,
7175bc3cb74SMauro Carvalho Chehab 				p->bt.il_vsync, p->bt.il_vbackporch,
7185bc3cb74SMauro Carvalho Chehab 				p->bt.standards, p->bt.flags);
7195bc3cb74SMauro Carvalho Chehab 		break;
7205bc3cb74SMauro Carvalho Chehab 	default:
7215bc3cb74SMauro Carvalho Chehab 		pr_cont("type=%d\n", p->type);
7225bc3cb74SMauro Carvalho Chehab 		break;
7235bc3cb74SMauro Carvalho Chehab 	}
7245bc3cb74SMauro Carvalho Chehab }
7255bc3cb74SMauro Carvalho Chehab 
7265bc3cb74SMauro Carvalho Chehab static void v4l_print_enum_dv_timings(const void *arg, bool write_only)
7275bc3cb74SMauro Carvalho Chehab {
7285bc3cb74SMauro Carvalho Chehab 	const struct v4l2_enum_dv_timings *p = arg;
7295bc3cb74SMauro Carvalho Chehab 
7305bc3cb74SMauro Carvalho Chehab 	pr_cont("index=%u, ", p->index);
7315bc3cb74SMauro Carvalho Chehab 	v4l_print_dv_timings(&p->timings, write_only);
7325bc3cb74SMauro Carvalho Chehab }
7335bc3cb74SMauro Carvalho Chehab 
7345bc3cb74SMauro Carvalho Chehab static void v4l_print_dv_timings_cap(const void *arg, bool write_only)
7355bc3cb74SMauro Carvalho Chehab {
7365bc3cb74SMauro Carvalho Chehab 	const struct v4l2_dv_timings_cap *p = arg;
7375bc3cb74SMauro Carvalho Chehab 
7385bc3cb74SMauro Carvalho Chehab 	switch (p->type) {
7395bc3cb74SMauro Carvalho Chehab 	case V4L2_DV_BT_656_1120:
7408720427cSMauro Carvalho Chehab 		pr_cont("type=bt-656/1120, width=%u-%u, height=%u-%u, pixelclock=%llu-%llu, standards=0x%x, capabilities=0x%x\n",
7415bc3cb74SMauro Carvalho Chehab 			p->bt.min_width, p->bt.max_width,
7425bc3cb74SMauro Carvalho Chehab 			p->bt.min_height, p->bt.max_height,
7435bc3cb74SMauro Carvalho Chehab 			p->bt.min_pixelclock, p->bt.max_pixelclock,
7445bc3cb74SMauro Carvalho Chehab 			p->bt.standards, p->bt.capabilities);
7455bc3cb74SMauro Carvalho Chehab 		break;
7465bc3cb74SMauro Carvalho Chehab 	default:
7475bc3cb74SMauro Carvalho Chehab 		pr_cont("type=%u\n", p->type);
7485bc3cb74SMauro Carvalho Chehab 		break;
7495bc3cb74SMauro Carvalho Chehab 	}
7505bc3cb74SMauro Carvalho Chehab }
7515bc3cb74SMauro Carvalho Chehab 
7525bc3cb74SMauro Carvalho Chehab static void v4l_print_frmsizeenum(const void *arg, bool write_only)
7535bc3cb74SMauro Carvalho Chehab {
7545bc3cb74SMauro Carvalho Chehab 	const struct v4l2_frmsizeenum *p = arg;
7555bc3cb74SMauro Carvalho Chehab 
7565bc3cb74SMauro Carvalho Chehab 	pr_cont("index=%u, pixelformat=%c%c%c%c, type=%u",
7575bc3cb74SMauro Carvalho Chehab 			p->index,
7585bc3cb74SMauro Carvalho Chehab 			(p->pixel_format & 0xff),
7595bc3cb74SMauro Carvalho Chehab 			(p->pixel_format >>  8) & 0xff,
7605bc3cb74SMauro Carvalho Chehab 			(p->pixel_format >> 16) & 0xff,
7615bc3cb74SMauro Carvalho Chehab 			(p->pixel_format >> 24) & 0xff,
7625bc3cb74SMauro Carvalho Chehab 			p->type);
7635bc3cb74SMauro Carvalho Chehab 	switch (p->type) {
7645bc3cb74SMauro Carvalho Chehab 	case V4L2_FRMSIZE_TYPE_DISCRETE:
765560dde24SHans Verkuil 		pr_cont(", wxh=%ux%u\n",
7665bc3cb74SMauro Carvalho Chehab 			p->discrete.width, p->discrete.height);
7675bc3cb74SMauro Carvalho Chehab 		break;
7685bc3cb74SMauro Carvalho Chehab 	case V4L2_FRMSIZE_TYPE_STEPWISE:
769560dde24SHans Verkuil 		pr_cont(", min=%ux%u, max=%ux%u, step=%ux%u\n",
7702489477eSRicardo Ribalda 				p->stepwise.min_width,
7712489477eSRicardo Ribalda 				p->stepwise.min_height,
7722489477eSRicardo Ribalda 				p->stepwise.max_width,
7732489477eSRicardo Ribalda 				p->stepwise.max_height,
7742489477eSRicardo Ribalda 				p->stepwise.step_width,
7752489477eSRicardo Ribalda 				p->stepwise.step_height);
7765bc3cb74SMauro Carvalho Chehab 		break;
7775bc3cb74SMauro Carvalho Chehab 	case V4L2_FRMSIZE_TYPE_CONTINUOUS:
7785bc3cb74SMauro Carvalho Chehab 		/* fall through */
7795bc3cb74SMauro Carvalho Chehab 	default:
7805bc3cb74SMauro Carvalho Chehab 		pr_cont("\n");
7815bc3cb74SMauro Carvalho Chehab 		break;
7825bc3cb74SMauro Carvalho Chehab 	}
7835bc3cb74SMauro Carvalho Chehab }
7845bc3cb74SMauro Carvalho Chehab 
7855bc3cb74SMauro Carvalho Chehab static void v4l_print_frmivalenum(const void *arg, bool write_only)
7865bc3cb74SMauro Carvalho Chehab {
7875bc3cb74SMauro Carvalho Chehab 	const struct v4l2_frmivalenum *p = arg;
7885bc3cb74SMauro Carvalho Chehab 
7895bc3cb74SMauro Carvalho Chehab 	pr_cont("index=%u, pixelformat=%c%c%c%c, wxh=%ux%u, type=%u",
7905bc3cb74SMauro Carvalho Chehab 			p->index,
7915bc3cb74SMauro Carvalho Chehab 			(p->pixel_format & 0xff),
7925bc3cb74SMauro Carvalho Chehab 			(p->pixel_format >>  8) & 0xff,
7935bc3cb74SMauro Carvalho Chehab 			(p->pixel_format >> 16) & 0xff,
7945bc3cb74SMauro Carvalho Chehab 			(p->pixel_format >> 24) & 0xff,
7955bc3cb74SMauro Carvalho Chehab 			p->width, p->height, p->type);
7965bc3cb74SMauro Carvalho Chehab 	switch (p->type) {
7975bc3cb74SMauro Carvalho Chehab 	case V4L2_FRMIVAL_TYPE_DISCRETE:
798560dde24SHans Verkuil 		pr_cont(", fps=%d/%d\n",
7995bc3cb74SMauro Carvalho Chehab 				p->discrete.numerator,
8005bc3cb74SMauro Carvalho Chehab 				p->discrete.denominator);
8015bc3cb74SMauro Carvalho Chehab 		break;
8025bc3cb74SMauro Carvalho Chehab 	case V4L2_FRMIVAL_TYPE_STEPWISE:
803560dde24SHans Verkuil 		pr_cont(", min=%d/%d, max=%d/%d, step=%d/%d\n",
8045bc3cb74SMauro Carvalho Chehab 				p->stepwise.min.numerator,
8055bc3cb74SMauro Carvalho Chehab 				p->stepwise.min.denominator,
8065bc3cb74SMauro Carvalho Chehab 				p->stepwise.max.numerator,
8075bc3cb74SMauro Carvalho Chehab 				p->stepwise.max.denominator,
8085bc3cb74SMauro Carvalho Chehab 				p->stepwise.step.numerator,
8095bc3cb74SMauro Carvalho Chehab 				p->stepwise.step.denominator);
8105bc3cb74SMauro Carvalho Chehab 		break;
8115bc3cb74SMauro Carvalho Chehab 	case V4L2_FRMIVAL_TYPE_CONTINUOUS:
8125bc3cb74SMauro Carvalho Chehab 		/* fall through */
8135bc3cb74SMauro Carvalho Chehab 	default:
8145bc3cb74SMauro Carvalho Chehab 		pr_cont("\n");
8155bc3cb74SMauro Carvalho Chehab 		break;
8165bc3cb74SMauro Carvalho Chehab 	}
8175bc3cb74SMauro Carvalho Chehab }
8185bc3cb74SMauro Carvalho Chehab 
8195bc3cb74SMauro Carvalho Chehab static void v4l_print_event(const void *arg, bool write_only)
8205bc3cb74SMauro Carvalho Chehab {
8215bc3cb74SMauro Carvalho Chehab 	const struct v4l2_event *p = arg;
8225bc3cb74SMauro Carvalho Chehab 	const struct v4l2_event_ctrl *c;
8235bc3cb74SMauro Carvalho Chehab 
8248720427cSMauro Carvalho Chehab 	pr_cont("type=0x%x, pending=%u, sequence=%u, id=%u, timestamp=%lu.%9.9lu\n",
8255bc3cb74SMauro Carvalho Chehab 			p->type, p->pending, p->sequence, p->id,
8265bc3cb74SMauro Carvalho Chehab 			p->timestamp.tv_sec, p->timestamp.tv_nsec);
8275bc3cb74SMauro Carvalho Chehab 	switch (p->type) {
8285bc3cb74SMauro Carvalho Chehab 	case V4L2_EVENT_VSYNC:
8295bc3cb74SMauro Carvalho Chehab 		printk(KERN_DEBUG "field=%s\n",
8305bc3cb74SMauro Carvalho Chehab 			prt_names(p->u.vsync.field, v4l2_field_names));
8315bc3cb74SMauro Carvalho Chehab 		break;
8325bc3cb74SMauro Carvalho Chehab 	case V4L2_EVENT_CTRL:
8335bc3cb74SMauro Carvalho Chehab 		c = &p->u.ctrl;
8345bc3cb74SMauro Carvalho Chehab 		printk(KERN_DEBUG "changes=0x%x, type=%u, ",
8355bc3cb74SMauro Carvalho Chehab 			c->changes, c->type);
8365bc3cb74SMauro Carvalho Chehab 		if (c->type == V4L2_CTRL_TYPE_INTEGER64)
8375bc3cb74SMauro Carvalho Chehab 			pr_cont("value64=%lld, ", c->value64);
8385bc3cb74SMauro Carvalho Chehab 		else
8395bc3cb74SMauro Carvalho Chehab 			pr_cont("value=%d, ", c->value);
8408720427cSMauro Carvalho Chehab 		pr_cont("flags=0x%x, minimum=%d, maximum=%d, step=%d, default_value=%d\n",
8415bc3cb74SMauro Carvalho Chehab 			c->flags, c->minimum, c->maximum,
8425bc3cb74SMauro Carvalho Chehab 			c->step, c->default_value);
8435bc3cb74SMauro Carvalho Chehab 		break;
8445bc3cb74SMauro Carvalho Chehab 	case V4L2_EVENT_FRAME_SYNC:
8455bc3cb74SMauro Carvalho Chehab 		pr_cont("frame_sequence=%u\n",
8465bc3cb74SMauro Carvalho Chehab 			p->u.frame_sync.frame_sequence);
8475bc3cb74SMauro Carvalho Chehab 		break;
8485bc3cb74SMauro Carvalho Chehab 	}
8495bc3cb74SMauro Carvalho Chehab }
8505bc3cb74SMauro Carvalho Chehab 
8515bc3cb74SMauro Carvalho Chehab static void v4l_print_event_subscription(const void *arg, bool write_only)
8525bc3cb74SMauro Carvalho Chehab {
8535bc3cb74SMauro Carvalho Chehab 	const struct v4l2_event_subscription *p = arg;
8545bc3cb74SMauro Carvalho Chehab 
8555bc3cb74SMauro Carvalho Chehab 	pr_cont("type=0x%x, id=0x%x, flags=0x%x\n",
8565bc3cb74SMauro Carvalho Chehab 			p->type, p->id, p->flags);
8575bc3cb74SMauro Carvalho Chehab }
8585bc3cb74SMauro Carvalho Chehab 
8595bc3cb74SMauro Carvalho Chehab static void v4l_print_sliced_vbi_cap(const void *arg, bool write_only)
8605bc3cb74SMauro Carvalho Chehab {
8615bc3cb74SMauro Carvalho Chehab 	const struct v4l2_sliced_vbi_cap *p = arg;
8625bc3cb74SMauro Carvalho Chehab 	int i;
8635bc3cb74SMauro Carvalho Chehab 
8645bc3cb74SMauro Carvalho Chehab 	pr_cont("type=%s, service_set=0x%08x\n",
8655bc3cb74SMauro Carvalho Chehab 			prt_names(p->type, v4l2_type_names), p->service_set);
8665bc3cb74SMauro Carvalho Chehab 	for (i = 0; i < 24; i++)
8675bc3cb74SMauro Carvalho Chehab 		printk(KERN_DEBUG "line[%02u]=0x%04x, 0x%04x\n", i,
8685bc3cb74SMauro Carvalho Chehab 				p->service_lines[0][i],
8695bc3cb74SMauro Carvalho Chehab 				p->service_lines[1][i]);
8705bc3cb74SMauro Carvalho Chehab }
8715bc3cb74SMauro Carvalho Chehab 
8725bc3cb74SMauro Carvalho Chehab static void v4l_print_freq_band(const void *arg, bool write_only)
8735bc3cb74SMauro Carvalho Chehab {
8745bc3cb74SMauro Carvalho Chehab 	const struct v4l2_frequency_band *p = arg;
8755bc3cb74SMauro Carvalho Chehab 
8768720427cSMauro Carvalho Chehab 	pr_cont("tuner=%u, type=%u, index=%u, capability=0x%x, rangelow=%u, rangehigh=%u, modulation=0x%x\n",
8775bc3cb74SMauro Carvalho Chehab 			p->tuner, p->type, p->index,
8785bc3cb74SMauro Carvalho Chehab 			p->capability, p->rangelow,
8795bc3cb74SMauro Carvalho Chehab 			p->rangehigh, p->modulation);
8805bc3cb74SMauro Carvalho Chehab }
8815bc3cb74SMauro Carvalho Chehab 
882dd519bb3SHans Verkuil static void v4l_print_edid(const void *arg, bool write_only)
883dd519bb3SHans Verkuil {
884dd519bb3SHans Verkuil 	const struct v4l2_edid *p = arg;
885dd519bb3SHans Verkuil 
886dd519bb3SHans Verkuil 	pr_cont("pad=%u, start_block=%u, blocks=%u\n",
887dd519bb3SHans Verkuil 		p->pad, p->start_block, p->blocks);
888dd519bb3SHans Verkuil }
889dd519bb3SHans Verkuil 
8905bc3cb74SMauro Carvalho Chehab static void v4l_print_u32(const void *arg, bool write_only)
8915bc3cb74SMauro Carvalho Chehab {
8925bc3cb74SMauro Carvalho Chehab 	pr_cont("value=%u\n", *(const u32 *)arg);
8935bc3cb74SMauro Carvalho Chehab }
8945bc3cb74SMauro Carvalho Chehab 
8955bc3cb74SMauro Carvalho Chehab static void v4l_print_newline(const void *arg, bool write_only)
8965bc3cb74SMauro Carvalho Chehab {
8975bc3cb74SMauro Carvalho Chehab 	pr_cont("\n");
8985bc3cb74SMauro Carvalho Chehab }
8995bc3cb74SMauro Carvalho Chehab 
9005bc3cb74SMauro Carvalho Chehab static void v4l_print_default(const void *arg, bool write_only)
9015bc3cb74SMauro Carvalho Chehab {
9025bc3cb74SMauro Carvalho Chehab 	pr_cont("driver-specific ioctl\n");
9035bc3cb74SMauro Carvalho Chehab }
9045bc3cb74SMauro Carvalho Chehab 
9055bc3cb74SMauro Carvalho Chehab static int check_ext_ctrls(struct v4l2_ext_controls *c, int allow_priv)
9065bc3cb74SMauro Carvalho Chehab {
9075bc3cb74SMauro Carvalho Chehab 	__u32 i;
9085bc3cb74SMauro Carvalho Chehab 
9095bc3cb74SMauro Carvalho Chehab 	/* zero the reserved fields */
9105bc3cb74SMauro Carvalho Chehab 	c->reserved[0] = c->reserved[1] = 0;
9115bc3cb74SMauro Carvalho Chehab 	for (i = 0; i < c->count; i++)
9125bc3cb74SMauro Carvalho Chehab 		c->controls[i].reserved2[0] = 0;
9135bc3cb74SMauro Carvalho Chehab 
9145bc3cb74SMauro Carvalho Chehab 	/* V4L2_CID_PRIVATE_BASE cannot be used as control class
9155bc3cb74SMauro Carvalho Chehab 	   when using extended controls.
9165bc3cb74SMauro Carvalho Chehab 	   Only when passed in through VIDIOC_G_CTRL and VIDIOC_S_CTRL
9175bc3cb74SMauro Carvalho Chehab 	   is it allowed for backwards compatibility.
9185bc3cb74SMauro Carvalho Chehab 	 */
9190f8017beSRicardo Ribalda 	if (!allow_priv && c->which == V4L2_CID_PRIVATE_BASE)
9205bc3cb74SMauro Carvalho Chehab 		return 0;
9210f8017beSRicardo Ribalda 	if (!c->which)
9229b239b22SHans Verkuil 		return 1;
9235bc3cb74SMauro Carvalho Chehab 	/* Check that all controls are from the same control class. */
9245bc3cb74SMauro Carvalho Chehab 	for (i = 0; i < c->count; i++) {
9250f8017beSRicardo Ribalda 		if (V4L2_CTRL_ID2WHICH(c->controls[i].id) != c->which) {
9265bc3cb74SMauro Carvalho Chehab 			c->error_idx = i;
9275bc3cb74SMauro Carvalho Chehab 			return 0;
9285bc3cb74SMauro Carvalho Chehab 		}
9295bc3cb74SMauro Carvalho Chehab 	}
9305bc3cb74SMauro Carvalho Chehab 	return 1;
9315bc3cb74SMauro Carvalho Chehab }
9325bc3cb74SMauro Carvalho Chehab 
9334b20259fSHans Verkuil static int check_fmt(struct file *file, enum v4l2_buf_type type)
9345bc3cb74SMauro Carvalho Chehab {
9354b20259fSHans Verkuil 	struct video_device *vfd = video_devdata(file);
9364b20259fSHans Verkuil 	const struct v4l2_ioctl_ops *ops = vfd->ioctl_ops;
9374b20259fSHans Verkuil 	bool is_vid = vfd->vfl_type == VFL_TYPE_GRABBER;
9384b20259fSHans Verkuil 	bool is_vbi = vfd->vfl_type == VFL_TYPE_VBI;
939582c52cbSAntti Palosaari 	bool is_sdr = vfd->vfl_type == VFL_TYPE_SDR;
940b2fe22d0SNick Dyer 	bool is_tch = vfd->vfl_type == VFL_TYPE_TOUCH;
9414b20259fSHans Verkuil 	bool is_rx = vfd->vfl_dir != VFL_DIR_TX;
9424b20259fSHans Verkuil 	bool is_tx = vfd->vfl_dir != VFL_DIR_RX;
9434b20259fSHans Verkuil 
9445bc3cb74SMauro Carvalho Chehab 	if (ops == NULL)
9455bc3cb74SMauro Carvalho Chehab 		return -EINVAL;
9465bc3cb74SMauro Carvalho Chehab 
9475bc3cb74SMauro Carvalho Chehab 	switch (type) {
9485bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_CAPTURE:
949b2fe22d0SNick Dyer 		if ((is_vid || is_tch) && is_rx &&
9504b20259fSHans Verkuil 		    (ops->vidioc_g_fmt_vid_cap || ops->vidioc_g_fmt_vid_cap_mplane))
9515bc3cb74SMauro Carvalho Chehab 			return 0;
9525bc3cb74SMauro Carvalho Chehab 		break;
9535bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
9544b20259fSHans Verkuil 		if (is_vid && is_rx && ops->vidioc_g_fmt_vid_cap_mplane)
9555bc3cb74SMauro Carvalho Chehab 			return 0;
9565bc3cb74SMauro Carvalho Chehab 		break;
9575bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_OVERLAY:
9584b20259fSHans Verkuil 		if (is_vid && is_rx && ops->vidioc_g_fmt_vid_overlay)
9595bc3cb74SMauro Carvalho Chehab 			return 0;
9605bc3cb74SMauro Carvalho Chehab 		break;
9615bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_OUTPUT:
9624b20259fSHans Verkuil 		if (is_vid && is_tx &&
9634b20259fSHans Verkuil 		    (ops->vidioc_g_fmt_vid_out || ops->vidioc_g_fmt_vid_out_mplane))
9645bc3cb74SMauro Carvalho Chehab 			return 0;
9655bc3cb74SMauro Carvalho Chehab 		break;
9665bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
9674b20259fSHans Verkuil 		if (is_vid && is_tx && 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_OVERLAY:
9714b20259fSHans Verkuil 		if (is_vid && is_tx && ops->vidioc_g_fmt_vid_out_overlay)
9725bc3cb74SMauro Carvalho Chehab 			return 0;
9735bc3cb74SMauro Carvalho Chehab 		break;
9745bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VBI_CAPTURE:
9754b20259fSHans Verkuil 		if (is_vbi && is_rx && ops->vidioc_g_fmt_vbi_cap)
9765bc3cb74SMauro Carvalho Chehab 			return 0;
9775bc3cb74SMauro Carvalho Chehab 		break;
9785bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VBI_OUTPUT:
9794b20259fSHans Verkuil 		if (is_vbi && is_tx && ops->vidioc_g_fmt_vbi_out)
9805bc3cb74SMauro Carvalho Chehab 			return 0;
9815bc3cb74SMauro Carvalho Chehab 		break;
9825bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
9834b20259fSHans Verkuil 		if (is_vbi && is_rx && ops->vidioc_g_fmt_sliced_vbi_cap)
9845bc3cb74SMauro Carvalho Chehab 			return 0;
9855bc3cb74SMauro Carvalho Chehab 		break;
9865bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
9874b20259fSHans Verkuil 		if (is_vbi && is_tx && ops->vidioc_g_fmt_sliced_vbi_out)
9885bc3cb74SMauro Carvalho Chehab 			return 0;
9895bc3cb74SMauro Carvalho Chehab 		break;
990582c52cbSAntti Palosaari 	case V4L2_BUF_TYPE_SDR_CAPTURE:
991582c52cbSAntti Palosaari 		if (is_sdr && is_rx && ops->vidioc_g_fmt_sdr_cap)
992582c52cbSAntti Palosaari 			return 0;
993582c52cbSAntti Palosaari 		break;
9949effc72fSAntti Palosaari 	case V4L2_BUF_TYPE_SDR_OUTPUT:
9959effc72fSAntti Palosaari 		if (is_sdr && is_tx && ops->vidioc_g_fmt_sdr_out)
9969effc72fSAntti Palosaari 			return 0;
9979effc72fSAntti Palosaari 		break;
998fb9ffa6aSLaurent Pinchart 	case V4L2_BUF_TYPE_META_CAPTURE:
999fb9ffa6aSLaurent Pinchart 		if (is_vid && is_rx && ops->vidioc_g_fmt_meta_cap)
1000fb9ffa6aSLaurent Pinchart 			return 0;
1001fb9ffa6aSLaurent Pinchart 		break;
1002633c98e5SHans Verkuil 	default:
10035bc3cb74SMauro Carvalho Chehab 		break;
10045bc3cb74SMauro Carvalho Chehab 	}
10055bc3cb74SMauro Carvalho Chehab 	return -EINVAL;
10065bc3cb74SMauro Carvalho Chehab }
10075bc3cb74SMauro Carvalho Chehab 
1008d52e2381SLaurent Pinchart static void v4l_sanitize_format(struct v4l2_format *fmt)
1009d52e2381SLaurent Pinchart {
1010d52e2381SLaurent Pinchart 	unsigned int offset;
1011d52e2381SLaurent Pinchart 
1012d52e2381SLaurent Pinchart 	/*
1013d52e2381SLaurent Pinchart 	 * The v4l2_pix_format structure has been extended with fields that were
1014d52e2381SLaurent Pinchart 	 * not previously required to be set to zero by applications. The priv
1015d52e2381SLaurent Pinchart 	 * field, when set to a magic value, indicates the the extended fields
1016d52e2381SLaurent Pinchart 	 * are valid. Otherwise they will contain undefined values. To simplify
1017d52e2381SLaurent Pinchart 	 * the API towards drivers zero the extended fields and set the priv
1018d52e2381SLaurent Pinchart 	 * field to the magic value when the extended pixel format structure
1019d52e2381SLaurent Pinchart 	 * isn't used by applications.
1020d52e2381SLaurent Pinchart 	 */
1021d52e2381SLaurent Pinchart 
1022d52e2381SLaurent Pinchart 	if (fmt->type != V4L2_BUF_TYPE_VIDEO_CAPTURE &&
1023d52e2381SLaurent Pinchart 	    fmt->type != V4L2_BUF_TYPE_VIDEO_OUTPUT)
1024d52e2381SLaurent Pinchart 		return;
1025d52e2381SLaurent Pinchart 
1026d52e2381SLaurent Pinchart 	if (fmt->fmt.pix.priv == V4L2_PIX_FMT_PRIV_MAGIC)
1027d52e2381SLaurent Pinchart 		return;
1028d52e2381SLaurent Pinchart 
1029d52e2381SLaurent Pinchart 	fmt->fmt.pix.priv = V4L2_PIX_FMT_PRIV_MAGIC;
1030d52e2381SLaurent Pinchart 
1031d52e2381SLaurent Pinchart 	offset = offsetof(struct v4l2_pix_format, priv)
1032d52e2381SLaurent Pinchart 	       + sizeof(fmt->fmt.pix.priv);
1033d52e2381SLaurent Pinchart 	memset(((void *)&fmt->fmt.pix) + offset, 0,
1034d52e2381SLaurent Pinchart 	       sizeof(fmt->fmt.pix) - offset);
1035d52e2381SLaurent Pinchart }
1036d52e2381SLaurent Pinchart 
10375bc3cb74SMauro Carvalho Chehab static int v4l_querycap(const struct v4l2_ioctl_ops *ops,
10385bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
10395bc3cb74SMauro Carvalho Chehab {
10405bc3cb74SMauro Carvalho Chehab 	struct v4l2_capability *cap = (struct v4l2_capability *)arg;
10417bbe7813SHans Verkuil 	struct video_device *vfd = video_devdata(file);
1042d52e2381SLaurent Pinchart 	int ret;
10435bc3cb74SMauro Carvalho Chehab 
10445bc3cb74SMauro Carvalho Chehab 	cap->version = LINUX_VERSION_CODE;
10457bbe7813SHans Verkuil 	cap->device_caps = vfd->device_caps;
10467bbe7813SHans Verkuil 	cap->capabilities = vfd->device_caps | V4L2_CAP_DEVICE_CAPS;
1047d52e2381SLaurent Pinchart 
1048d52e2381SLaurent Pinchart 	ret = ops->vidioc_querycap(file, fh, cap);
1049d52e2381SLaurent Pinchart 
1050d52e2381SLaurent Pinchart 	cap->capabilities |= V4L2_CAP_EXT_PIX_FORMAT;
1051454a4e72SHans Verkuil 	/*
1052454a4e72SHans Verkuil 	 * Drivers MUST fill in device_caps, so check for this and
1053454a4e72SHans Verkuil 	 * warn if it was forgotten.
1054454a4e72SHans Verkuil 	 */
10556d7570c4SLaura Abbott 	WARN(!(cap->capabilities & V4L2_CAP_DEVICE_CAPS) ||
10566d7570c4SLaura Abbott 		!cap->device_caps, "Bad caps for driver %s, %x %x",
10576d7570c4SLaura Abbott 		cap->driver, cap->capabilities, cap->device_caps);
1058796a2bd2SHans Verkuil 	cap->device_caps |= V4L2_CAP_EXT_PIX_FORMAT;
1059d52e2381SLaurent Pinchart 
1060d52e2381SLaurent Pinchart 	return ret;
10615bc3cb74SMauro Carvalho Chehab }
10625bc3cb74SMauro Carvalho Chehab 
10635bc3cb74SMauro Carvalho Chehab static int v4l_s_input(const struct v4l2_ioctl_ops *ops,
10645bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
10655bc3cb74SMauro Carvalho Chehab {
106677fa4e07SShuah Khan 	struct video_device *vfd = video_devdata(file);
106777fa4e07SShuah Khan 	int ret;
106877fa4e07SShuah Khan 
106977fa4e07SShuah Khan 	ret = v4l_enable_media_source(vfd);
107077fa4e07SShuah Khan 	if (ret)
107177fa4e07SShuah Khan 		return ret;
10725bc3cb74SMauro Carvalho Chehab 	return ops->vidioc_s_input(file, fh, *(unsigned int *)arg);
10735bc3cb74SMauro Carvalho Chehab }
10745bc3cb74SMauro Carvalho Chehab 
10755bc3cb74SMauro Carvalho Chehab static int v4l_s_output(const struct v4l2_ioctl_ops *ops,
10765bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
10775bc3cb74SMauro Carvalho Chehab {
10785bc3cb74SMauro Carvalho Chehab 	return ops->vidioc_s_output(file, fh, *(unsigned int *)arg);
10795bc3cb74SMauro Carvalho Chehab }
10805bc3cb74SMauro Carvalho Chehab 
10815bc3cb74SMauro Carvalho Chehab static int v4l_g_priority(const struct v4l2_ioctl_ops *ops,
10825bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
10835bc3cb74SMauro Carvalho Chehab {
10845bc3cb74SMauro Carvalho Chehab 	struct video_device *vfd;
10855bc3cb74SMauro Carvalho Chehab 	u32 *p = arg;
10865bc3cb74SMauro Carvalho Chehab 
10875bc3cb74SMauro Carvalho Chehab 	vfd = video_devdata(file);
108859b702eaSLaurent Pinchart 	*p = v4l2_prio_max(vfd->prio);
10895bc3cb74SMauro Carvalho Chehab 	return 0;
10905bc3cb74SMauro Carvalho Chehab }
10915bc3cb74SMauro Carvalho Chehab 
10925bc3cb74SMauro Carvalho Chehab static int v4l_s_priority(const struct v4l2_ioctl_ops *ops,
10935bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
10945bc3cb74SMauro Carvalho Chehab {
10955bc3cb74SMauro Carvalho Chehab 	struct video_device *vfd;
10965bc3cb74SMauro Carvalho Chehab 	struct v4l2_fh *vfh;
10975bc3cb74SMauro Carvalho Chehab 	u32 *p = arg;
10985bc3cb74SMauro Carvalho Chehab 
10995bc3cb74SMauro Carvalho Chehab 	vfd = video_devdata(file);
11002438e78aSHans Verkuil 	if (!test_bit(V4L2_FL_USES_V4L2_FH, &vfd->flags))
11012438e78aSHans Verkuil 		return -ENOTTY;
11025bc3cb74SMauro Carvalho Chehab 	vfh = file->private_data;
110359b702eaSLaurent Pinchart 	return v4l2_prio_change(vfd->prio, &vfh->prio, *p);
11045bc3cb74SMauro Carvalho Chehab }
11055bc3cb74SMauro Carvalho Chehab 
11065bc3cb74SMauro Carvalho Chehab static int v4l_enuminput(const struct v4l2_ioctl_ops *ops,
11075bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
11085bc3cb74SMauro Carvalho Chehab {
110973f35418SHans Verkuil 	struct video_device *vfd = video_devdata(file);
11105bc3cb74SMauro Carvalho Chehab 	struct v4l2_input *p = arg;
11115bc3cb74SMauro Carvalho Chehab 
11125bc3cb74SMauro Carvalho Chehab 	/*
111302fa6282SHans Verkuil 	 * We set the flags for CAP_DV_TIMINGS &
11145bc3cb74SMauro Carvalho Chehab 	 * CAP_STD here based on ioctl handler provided by the
11155bc3cb74SMauro Carvalho Chehab 	 * driver. If the driver doesn't support these
11165bc3cb74SMauro Carvalho Chehab 	 * for a specific input, it must override these flags.
11175bc3cb74SMauro Carvalho Chehab 	 */
111873f35418SHans Verkuil 	if (is_valid_ioctl(vfd, VIDIOC_S_STD))
11195bc3cb74SMauro Carvalho Chehab 		p->capabilities |= V4L2_IN_CAP_STD;
11205bc3cb74SMauro Carvalho Chehab 
11215bc3cb74SMauro Carvalho Chehab 	return ops->vidioc_enum_input(file, fh, p);
11225bc3cb74SMauro Carvalho Chehab }
11235bc3cb74SMauro Carvalho Chehab 
11245bc3cb74SMauro Carvalho Chehab static int v4l_enumoutput(const struct v4l2_ioctl_ops *ops,
11255bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
11265bc3cb74SMauro Carvalho Chehab {
112773f35418SHans Verkuil 	struct video_device *vfd = video_devdata(file);
11285bc3cb74SMauro Carvalho Chehab 	struct v4l2_output *p = arg;
11295bc3cb74SMauro Carvalho Chehab 
11305bc3cb74SMauro Carvalho Chehab 	/*
113102fa6282SHans Verkuil 	 * We set the flags for CAP_DV_TIMINGS &
11325bc3cb74SMauro Carvalho Chehab 	 * CAP_STD here based on ioctl handler provided by the
11335bc3cb74SMauro Carvalho Chehab 	 * driver. If the driver doesn't support these
11345bc3cb74SMauro Carvalho Chehab 	 * for a specific output, it must override these flags.
11355bc3cb74SMauro Carvalho Chehab 	 */
113673f35418SHans Verkuil 	if (is_valid_ioctl(vfd, VIDIOC_S_STD))
11375bc3cb74SMauro Carvalho Chehab 		p->capabilities |= V4L2_OUT_CAP_STD;
11385bc3cb74SMauro Carvalho Chehab 
11395bc3cb74SMauro Carvalho Chehab 	return ops->vidioc_enum_output(file, fh, p);
11405bc3cb74SMauro Carvalho Chehab }
11415bc3cb74SMauro Carvalho Chehab 
1142ba300204SHans Verkuil static void v4l_fill_fmtdesc(struct v4l2_fmtdesc *fmt)
1143ba300204SHans Verkuil {
1144ba300204SHans Verkuil 	const unsigned sz = sizeof(fmt->description);
1145ba300204SHans Verkuil 	const char *descr = NULL;
1146ba300204SHans Verkuil 	u32 flags = 0;
1147ba300204SHans Verkuil 
1148ba300204SHans Verkuil 	/*
1149ba300204SHans Verkuil 	 * We depart from the normal coding style here since the descriptions
1150ba300204SHans Verkuil 	 * should be aligned so it is easy to see which descriptions will be
1151ba300204SHans Verkuil 	 * longer than 31 characters (the max length for a description).
1152ba300204SHans Verkuil 	 * And frankly, this is easier to read anyway.
1153ba300204SHans Verkuil 	 *
1154ba300204SHans Verkuil 	 * Note that gcc will use O(log N) comparisons to find the right case.
1155ba300204SHans Verkuil 	 */
1156ba300204SHans Verkuil 	switch (fmt->pixelformat) {
1157ba300204SHans Verkuil 	/* Max description length mask:	descr = "0123456789012345678901234567890" */
1158ba300204SHans Verkuil 	case V4L2_PIX_FMT_RGB332:	descr = "8-bit RGB 3-3-2"; break;
1159ba300204SHans Verkuil 	case V4L2_PIX_FMT_RGB444:	descr = "16-bit A/XRGB 4-4-4-4"; break;
1160ba300204SHans Verkuil 	case V4L2_PIX_FMT_ARGB444:	descr = "16-bit ARGB 4-4-4-4"; break;
1161ba300204SHans Verkuil 	case V4L2_PIX_FMT_XRGB444:	descr = "16-bit XRGB 4-4-4-4"; break;
1162ba300204SHans Verkuil 	case V4L2_PIX_FMT_RGB555:	descr = "16-bit A/XRGB 1-5-5-5"; break;
1163ba300204SHans Verkuil 	case V4L2_PIX_FMT_ARGB555:	descr = "16-bit ARGB 1-5-5-5"; break;
1164ba300204SHans Verkuil 	case V4L2_PIX_FMT_XRGB555:	descr = "16-bit XRGB 1-5-5-5"; break;
1165ba300204SHans Verkuil 	case V4L2_PIX_FMT_RGB565:	descr = "16-bit RGB 5-6-5"; break;
1166ba300204SHans Verkuil 	case V4L2_PIX_FMT_RGB555X:	descr = "16-bit A/XRGB 1-5-5-5 BE"; break;
1167ba300204SHans Verkuil 	case V4L2_PIX_FMT_ARGB555X:	descr = "16-bit ARGB 1-5-5-5 BE"; break;
1168ba300204SHans Verkuil 	case V4L2_PIX_FMT_XRGB555X:	descr = "16-bit XRGB 1-5-5-5 BE"; break;
1169ba300204SHans Verkuil 	case V4L2_PIX_FMT_RGB565X:	descr = "16-bit RGB 5-6-5 BE"; break;
1170ba300204SHans Verkuil 	case V4L2_PIX_FMT_BGR666:	descr = "18-bit BGRX 6-6-6-14"; break;
1171ba300204SHans Verkuil 	case V4L2_PIX_FMT_BGR24:	descr = "24-bit BGR 8-8-8"; break;
1172ba300204SHans Verkuil 	case V4L2_PIX_FMT_RGB24:	descr = "24-bit RGB 8-8-8"; break;
1173ba300204SHans Verkuil 	case V4L2_PIX_FMT_BGR32:	descr = "32-bit BGRA/X 8-8-8-8"; break;
1174ba300204SHans Verkuil 	case V4L2_PIX_FMT_ABGR32:	descr = "32-bit BGRA 8-8-8-8"; break;
1175ba300204SHans Verkuil 	case V4L2_PIX_FMT_XBGR32:	descr = "32-bit BGRX 8-8-8-8"; break;
1176ba300204SHans Verkuil 	case V4L2_PIX_FMT_RGB32:	descr = "32-bit A/XRGB 8-8-8-8"; break;
1177ba300204SHans Verkuil 	case V4L2_PIX_FMT_ARGB32:	descr = "32-bit ARGB 8-8-8-8"; break;
1178ba300204SHans Verkuil 	case V4L2_PIX_FMT_XRGB32:	descr = "32-bit XRGB 8-8-8-8"; break;
1179ba300204SHans Verkuil 	case V4L2_PIX_FMT_GREY:		descr = "8-bit Greyscale"; break;
1180ba300204SHans Verkuil 	case V4L2_PIX_FMT_Y4:		descr = "4-bit Greyscale"; break;
1181ba300204SHans Verkuil 	case V4L2_PIX_FMT_Y6:		descr = "6-bit Greyscale"; break;
1182ba300204SHans Verkuil 	case V4L2_PIX_FMT_Y10:		descr = "10-bit Greyscale"; break;
1183ba300204SHans Verkuil 	case V4L2_PIX_FMT_Y12:		descr = "12-bit Greyscale"; break;
1184ba300204SHans Verkuil 	case V4L2_PIX_FMT_Y16:		descr = "16-bit Greyscale"; break;
11852e5e435fSRicardo Ribalda 	case V4L2_PIX_FMT_Y16_BE:	descr = "16-bit Greyscale BE"; break;
1186ba300204SHans Verkuil 	case V4L2_PIX_FMT_Y10BPACK:	descr = "10-bit Greyscale (Packed)"; break;
11876e15bec4STodor Tomov 	case V4L2_PIX_FMT_Y10P:		descr = "10-bit Greyscale (MIPI Packed)"; break;
11885b382290SLaurent Pinchart 	case V4L2_PIX_FMT_Y8I:		descr = "Interleaved 8-bit Greyscale"; break;
11895b382290SLaurent Pinchart 	case V4L2_PIX_FMT_Y12I:		descr = "Interleaved 12-bit Greyscale"; break;
11905b382290SLaurent Pinchart 	case V4L2_PIX_FMT_Z16:		descr = "16-bit Depth"; break;
11915df082e2SEvgeni Raikhel 	case V4L2_PIX_FMT_INZI:		descr = "Planar 10:16 Greyscale Depth"; break;
1192ba300204SHans Verkuil 	case V4L2_PIX_FMT_PAL8:		descr = "8-bit Palette"; break;
1193ba300204SHans Verkuil 	case V4L2_PIX_FMT_UV8:		descr = "8-bit Chrominance UV 4-4"; break;
1194ba300204SHans Verkuil 	case V4L2_PIX_FMT_YVU410:	descr = "Planar YVU 4:1:0"; break;
1195ba300204SHans Verkuil 	case V4L2_PIX_FMT_YVU420:	descr = "Planar YVU 4:2:0"; break;
1196ba300204SHans Verkuil 	case V4L2_PIX_FMT_YUYV:		descr = "YUYV 4:2:2"; break;
1197ba300204SHans Verkuil 	case V4L2_PIX_FMT_YYUV:		descr = "YYUV 4:2:2"; break;
1198ba300204SHans Verkuil 	case V4L2_PIX_FMT_YVYU:		descr = "YVYU 4:2:2"; break;
1199ba300204SHans Verkuil 	case V4L2_PIX_FMT_UYVY:		descr = "UYVY 4:2:2"; break;
1200ba300204SHans Verkuil 	case V4L2_PIX_FMT_VYUY:		descr = "VYUY 4:2:2"; break;
1201fcbafafbSPhilipp Zabel 	case V4L2_PIX_FMT_YUV422P:	descr = "Planar YUV 4:2:2"; break;
1202ba300204SHans Verkuil 	case V4L2_PIX_FMT_YUV411P:	descr = "Planar YUV 4:1:1"; break;
1203ba300204SHans Verkuil 	case V4L2_PIX_FMT_Y41P:		descr = "YUV 4:1:1 (Packed)"; break;
1204ba300204SHans Verkuil 	case V4L2_PIX_FMT_YUV444:	descr = "16-bit A/XYUV 4-4-4-4"; break;
1205ba300204SHans Verkuil 	case V4L2_PIX_FMT_YUV555:	descr = "16-bit A/XYUV 1-5-5-5"; break;
1206ba300204SHans Verkuil 	case V4L2_PIX_FMT_YUV565:	descr = "16-bit YUV 5-6-5"; break;
1207ba300204SHans Verkuil 	case V4L2_PIX_FMT_YUV32:	descr = "32-bit A/XYUV 8-8-8-8"; break;
1208ba300204SHans Verkuil 	case V4L2_PIX_FMT_YUV410:	descr = "Planar YUV 4:1:0"; break;
1209ba300204SHans Verkuil 	case V4L2_PIX_FMT_YUV420:	descr = "Planar YUV 4:2:0"; break;
1210ba300204SHans Verkuil 	case V4L2_PIX_FMT_HI240:	descr = "8-bit Dithered RGB (BTTV)"; break;
1211ba300204SHans Verkuil 	case V4L2_PIX_FMT_HM12:		descr = "YUV 4:2:0 (16x16 Macroblocks)"; break;
1212ba300204SHans Verkuil 	case V4L2_PIX_FMT_M420:		descr = "YUV 4:2:0 (M420)"; break;
1213ba300204SHans Verkuil 	case V4L2_PIX_FMT_NV12:		descr = "Y/CbCr 4:2:0"; break;
1214ba300204SHans Verkuil 	case V4L2_PIX_FMT_NV21:		descr = "Y/CrCb 4:2:0"; break;
1215ba300204SHans Verkuil 	case V4L2_PIX_FMT_NV16:		descr = "Y/CbCr 4:2:2"; break;
1216ba300204SHans Verkuil 	case V4L2_PIX_FMT_NV61:		descr = "Y/CrCb 4:2:2"; break;
1217ba300204SHans Verkuil 	case V4L2_PIX_FMT_NV24:		descr = "Y/CbCr 4:4:4"; break;
1218ba300204SHans Verkuil 	case V4L2_PIX_FMT_NV42:		descr = "Y/CrCb 4:4:4"; break;
1219ba300204SHans Verkuil 	case V4L2_PIX_FMT_NV12M:	descr = "Y/CbCr 4:2:0 (N-C)"; break;
1220ba300204SHans Verkuil 	case V4L2_PIX_FMT_NV21M:	descr = "Y/CrCb 4:2:0 (N-C)"; break;
1221ba300204SHans Verkuil 	case V4L2_PIX_FMT_NV16M:	descr = "Y/CbCr 4:2:2 (N-C)"; break;
1222ba300204SHans Verkuil 	case V4L2_PIX_FMT_NV61M:	descr = "Y/CrCb 4:2:2 (N-C)"; break;
1223ba300204SHans Verkuil 	case V4L2_PIX_FMT_NV12MT:	descr = "Y/CbCr 4:2:0 (64x32 MB, N-C)"; break;
1224ba300204SHans Verkuil 	case V4L2_PIX_FMT_NV12MT_16X16:	descr = "Y/CbCr 4:2:0 (16x16 MB, N-C)"; break;
1225ba300204SHans Verkuil 	case V4L2_PIX_FMT_YUV420M:	descr = "Planar YUV 4:2:0 (N-C)"; break;
1226ba300204SHans Verkuil 	case V4L2_PIX_FMT_YVU420M:	descr = "Planar YVU 4:2:0 (N-C)"; break;
1227d65fae92SLaurent Pinchart 	case V4L2_PIX_FMT_YUV422M:	descr = "Planar YUV 4:2:2 (N-C)"; break;
1228d65fae92SLaurent Pinchart 	case V4L2_PIX_FMT_YVU422M:	descr = "Planar YVU 4:2:2 (N-C)"; break;
1229d65fae92SLaurent Pinchart 	case V4L2_PIX_FMT_YUV444M:	descr = "Planar YUV 4:4:4 (N-C)"; break;
1230d65fae92SLaurent Pinchart 	case V4L2_PIX_FMT_YVU444M:	descr = "Planar YVU 4:4:4 (N-C)"; break;
1231ba300204SHans Verkuil 	case V4L2_PIX_FMT_SBGGR8:	descr = "8-bit Bayer BGBG/GRGR"; break;
1232ba300204SHans Verkuil 	case V4L2_PIX_FMT_SGBRG8:	descr = "8-bit Bayer GBGB/RGRG"; break;
1233ba300204SHans Verkuil 	case V4L2_PIX_FMT_SGRBG8:	descr = "8-bit Bayer GRGR/BGBG"; break;
1234ba300204SHans Verkuil 	case V4L2_PIX_FMT_SRGGB8:	descr = "8-bit Bayer RGRG/GBGB"; break;
1235ba300204SHans Verkuil 	case V4L2_PIX_FMT_SBGGR10:	descr = "10-bit Bayer BGBG/GRGR"; break;
1236ba300204SHans Verkuil 	case V4L2_PIX_FMT_SGBRG10:	descr = "10-bit Bayer GBGB/RGRG"; break;
1237ba300204SHans Verkuil 	case V4L2_PIX_FMT_SGRBG10:	descr = "10-bit Bayer GRGR/BGBG"; break;
1238ba300204SHans Verkuil 	case V4L2_PIX_FMT_SRGGB10:	descr = "10-bit Bayer RGRG/GBGB"; break;
1239ba300204SHans Verkuil 	case V4L2_PIX_FMT_SBGGR10P:	descr = "10-bit Bayer BGBG/GRGR Packed"; break;
1240ba300204SHans Verkuil 	case V4L2_PIX_FMT_SGBRG10P:	descr = "10-bit Bayer GBGB/RGRG Packed"; break;
1241ba300204SHans Verkuil 	case V4L2_PIX_FMT_SGRBG10P:	descr = "10-bit Bayer GRGR/BGBG Packed"; break;
1242ba300204SHans Verkuil 	case V4L2_PIX_FMT_SRGGB10P:	descr = "10-bit Bayer RGRG/GBGB Packed"; break;
1243e8391b76SYong Zhi 	case V4L2_PIX_FMT_IPU3_SBGGR10: descr = "10-bit bayer BGGR IPU3 Packed"; break;
1244e8391b76SYong Zhi 	case V4L2_PIX_FMT_IPU3_SGBRG10: descr = "10-bit bayer GBRG IPU3 Packed"; break;
1245e8391b76SYong Zhi 	case V4L2_PIX_FMT_IPU3_SGRBG10: descr = "10-bit bayer GRBG IPU3 Packed"; break;
1246e8391b76SYong Zhi 	case V4L2_PIX_FMT_IPU3_SRGGB10: descr = "10-bit bayer RGGB IPU3 Packed"; break;
1247ba300204SHans Verkuil 	case V4L2_PIX_FMT_SBGGR10ALAW8:	descr = "8-bit Bayer BGBG/GRGR (A-law)"; break;
1248ba300204SHans Verkuil 	case V4L2_PIX_FMT_SGBRG10ALAW8:	descr = "8-bit Bayer GBGB/RGRG (A-law)"; break;
1249ba300204SHans Verkuil 	case V4L2_PIX_FMT_SGRBG10ALAW8:	descr = "8-bit Bayer GRGR/BGBG (A-law)"; break;
1250ba300204SHans Verkuil 	case V4L2_PIX_FMT_SRGGB10ALAW8:	descr = "8-bit Bayer RGRG/GBGB (A-law)"; break;
1251ba300204SHans Verkuil 	case V4L2_PIX_FMT_SBGGR10DPCM8:	descr = "8-bit Bayer BGBG/GRGR (DPCM)"; break;
1252ba300204SHans Verkuil 	case V4L2_PIX_FMT_SGBRG10DPCM8:	descr = "8-bit Bayer GBGB/RGRG (DPCM)"; break;
1253ba300204SHans Verkuil 	case V4L2_PIX_FMT_SGRBG10DPCM8:	descr = "8-bit Bayer GRGR/BGBG (DPCM)"; break;
1254ba300204SHans Verkuil 	case V4L2_PIX_FMT_SRGGB10DPCM8:	descr = "8-bit Bayer RGRG/GBGB (DPCM)"; break;
1255d1b3437eSSakari Ailus 	case V4L2_PIX_FMT_SBGGR12:	descr = "12-bit Bayer BGBG/GRGR"; break;
1256d1b3437eSSakari Ailus 	case V4L2_PIX_FMT_SGBRG12:	descr = "12-bit Bayer GBGB/RGRG"; break;
1257d1b3437eSSakari Ailus 	case V4L2_PIX_FMT_SGRBG12:	descr = "12-bit Bayer GRGR/BGBG"; break;
1258d1b3437eSSakari Ailus 	case V4L2_PIX_FMT_SRGGB12:	descr = "12-bit Bayer RGRG/GBGB"; break;
1259d1b3437eSSakari Ailus 	case V4L2_PIX_FMT_SBGGR12P:	descr = "12-bit Bayer BGBG/GRGR Packed"; break;
1260d1b3437eSSakari Ailus 	case V4L2_PIX_FMT_SGBRG12P:	descr = "12-bit Bayer GBGB/RGRG Packed"; break;
1261d1b3437eSSakari Ailus 	case V4L2_PIX_FMT_SGRBG12P:	descr = "12-bit Bayer GRGR/BGBG Packed"; break;
1262d1b3437eSSakari Ailus 	case V4L2_PIX_FMT_SRGGB12P:	descr = "12-bit Bayer RGRG/GBGB Packed"; break;
126383b15832SSakari Ailus 	case V4L2_PIX_FMT_SBGGR14P:	descr = "14-bit Bayer BGBG/GRGR Packed"; break;
126483b15832SSakari Ailus 	case V4L2_PIX_FMT_SGBRG14P:	descr = "14-bit Bayer GBGB/RGRG Packed"; break;
126583b15832SSakari Ailus 	case V4L2_PIX_FMT_SGRBG14P:	descr = "14-bit Bayer GRGR/BGBG Packed"; break;
126683b15832SSakari Ailus 	case V4L2_PIX_FMT_SRGGB14P:	descr = "14-bit Bayer RGRG/GBGB Packed"; break;
1267b9a4b13cSSakari Ailus 	case V4L2_PIX_FMT_SBGGR16:	descr = "16-bit Bayer BGBG/GRGR"; break;
1268b9a4b13cSSakari Ailus 	case V4L2_PIX_FMT_SGBRG16:	descr = "16-bit Bayer GBGB/RGRG"; break;
1269b9a4b13cSSakari Ailus 	case V4L2_PIX_FMT_SGRBG16:	descr = "16-bit Bayer GRGR/BGBG"; break;
1270b9a4b13cSSakari Ailus 	case V4L2_PIX_FMT_SRGGB16:	descr = "16-bit Bayer RGRG/GBGB"; break;
127199b74277SMauro Carvalho Chehab 	case V4L2_PIX_FMT_SN9C20X_I420:	descr = "GSPCA SN9C20X I420"; break;
1272ba300204SHans Verkuil 	case V4L2_PIX_FMT_SPCA501:	descr = "GSPCA SPCA501"; break;
1273ba300204SHans Verkuil 	case V4L2_PIX_FMT_SPCA505:	descr = "GSPCA SPCA505"; break;
1274ba300204SHans Verkuil 	case V4L2_PIX_FMT_SPCA508:	descr = "GSPCA SPCA508"; break;
1275ba300204SHans Verkuil 	case V4L2_PIX_FMT_STV0680:	descr = "GSPCA STV0680"; break;
1276ba300204SHans Verkuil 	case V4L2_PIX_FMT_TM6000:	descr = "A/V + VBI Mux Packet"; break;
1277ba300204SHans Verkuil 	case V4L2_PIX_FMT_CIT_YYVYUY:	descr = "GSPCA CIT YYVYUY"; break;
1278ba300204SHans Verkuil 	case V4L2_PIX_FMT_KONICA420:	descr = "GSPCA KONICA420"; break;
127966b2ab27SRicardo Ribalda Delgado 	case V4L2_PIX_FMT_HSV24:	descr = "24-bit HSV 8-8-8"; break;
128066b2ab27SRicardo Ribalda Delgado 	case V4L2_PIX_FMT_HSV32:	descr = "32-bit XHSV 8-8-8-8"; break;
128148fc10aaSAntti Palosaari 	case V4L2_SDR_FMT_CU8:		descr = "Complex U8"; break;
128248fc10aaSAntti Palosaari 	case V4L2_SDR_FMT_CU16LE:	descr = "Complex U16LE"; break;
1283ba300204SHans Verkuil 	case V4L2_SDR_FMT_CS8:		descr = "Complex S8"; break;
1284ba300204SHans Verkuil 	case V4L2_SDR_FMT_CS14LE:	descr = "Complex S14LE"; break;
1285ba300204SHans Verkuil 	case V4L2_SDR_FMT_RU12LE:	descr = "Real U12LE"; break;
1286c28f2118SRamesh Shanmugasundaram 	case V4L2_SDR_FMT_PCU16BE:	descr = "Planar Complex U16BE"; break;
1287c28f2118SRamesh Shanmugasundaram 	case V4L2_SDR_FMT_PCU18BE:	descr = "Planar Complex U18BE"; break;
1288c28f2118SRamesh Shanmugasundaram 	case V4L2_SDR_FMT_PCU20BE:	descr = "Planar Complex U20BE"; break;
1289b2fe22d0SNick Dyer 	case V4L2_TCH_FMT_DELTA_TD16:	descr = "16-bit signed deltas"; break;
1290b2fe22d0SNick Dyer 	case V4L2_TCH_FMT_DELTA_TD08:	descr = "8-bit signed deltas"; break;
1291b2fe22d0SNick Dyer 	case V4L2_TCH_FMT_TU16:		descr = "16-bit unsigned touch data"; break;
1292b2fe22d0SNick Dyer 	case V4L2_TCH_FMT_TU08:		descr = "8-bit unsigned touch data"; break;
129314d66538SLaurent Pinchart 	case V4L2_META_FMT_VSP1_HGO:	descr = "R-Car VSP1 1-D Histogram"; break;
12945deb1c04SNiklas Söderlund 	case V4L2_META_FMT_VSP1_HGT:	descr = "R-Car VSP1 2-D Histogram"; break;
1295563a01e1SGuennadi Liakhovetski 	case V4L2_META_FMT_UVC:		descr = "UVC payload header metadata"; break;
1296ba300204SHans Verkuil 
1297ba300204SHans Verkuil 	default:
1298ba300204SHans Verkuil 		/* Compressed formats */
1299ba300204SHans Verkuil 		flags = V4L2_FMT_FLAG_COMPRESSED;
1300ba300204SHans Verkuil 		switch (fmt->pixelformat) {
1301ba300204SHans Verkuil 		/* Max description length mask:	descr = "0123456789012345678901234567890" */
1302ba300204SHans Verkuil 		case V4L2_PIX_FMT_MJPEG:	descr = "Motion-JPEG"; break;
1303ba300204SHans Verkuil 		case V4L2_PIX_FMT_JPEG:		descr = "JFIF JPEG"; break;
1304ba300204SHans Verkuil 		case V4L2_PIX_FMT_DV:		descr = "1394"; break;
1305ba300204SHans Verkuil 		case V4L2_PIX_FMT_MPEG:		descr = "MPEG-1/2/4"; break;
1306ba300204SHans Verkuil 		case V4L2_PIX_FMT_H264:		descr = "H.264"; break;
1307ba300204SHans Verkuil 		case V4L2_PIX_FMT_H264_NO_SC:	descr = "H.264 (No Start Codes)"; break;
1308ba300204SHans Verkuil 		case V4L2_PIX_FMT_H264_MVC:	descr = "H.264 MVC"; break;
1309ba300204SHans Verkuil 		case V4L2_PIX_FMT_H263:		descr = "H.263"; break;
1310ba300204SHans Verkuil 		case V4L2_PIX_FMT_MPEG1:	descr = "MPEG-1 ES"; break;
1311ba300204SHans Verkuil 		case V4L2_PIX_FMT_MPEG2:	descr = "MPEG-2 ES"; break;
1312ba300204SHans Verkuil 		case V4L2_PIX_FMT_MPEG4:	descr = "MPEG-4 part 2 ES"; break;
1313ba300204SHans Verkuil 		case V4L2_PIX_FMT_XVID:		descr = "Xvid"; break;
1314ba300204SHans Verkuil 		case V4L2_PIX_FMT_VC1_ANNEX_G:	descr = "VC-1 (SMPTE 412M Annex G)"; break;
1315ba300204SHans Verkuil 		case V4L2_PIX_FMT_VC1_ANNEX_L:	descr = "VC-1 (SMPTE 412M Annex L)"; break;
1316ba300204SHans Verkuil 		case V4L2_PIX_FMT_VP8:		descr = "VP8"; break;
1317fa14a564SWu-Cheng Li 		case V4L2_PIX_FMT_VP9:		descr = "VP9"; break;
13181c791727SSmitha T Murthy 		case V4L2_PIX_FMT_HEVC:		descr = "HEVC"; break; /* aka H.265 */
131962c3fce0SHans Verkuil 		case V4L2_PIX_FMT_FWHT:		descr = "FWHT"; break; /* used in vicodec */
1320ba300204SHans Verkuil 		case V4L2_PIX_FMT_CPIA1:	descr = "GSPCA CPiA YUV"; break;
1321ba300204SHans Verkuil 		case V4L2_PIX_FMT_WNVA:		descr = "WNVA"; break;
1322ba300204SHans Verkuil 		case V4L2_PIX_FMT_SN9C10X:	descr = "GSPCA SN9C10X"; break;
1323ba300204SHans Verkuil 		case V4L2_PIX_FMT_PWC1:		descr = "Raw Philips Webcam Type (Old)"; break;
1324ba300204SHans Verkuil 		case V4L2_PIX_FMT_PWC2:		descr = "Raw Philips Webcam Type (New)"; break;
1325ba300204SHans Verkuil 		case V4L2_PIX_FMT_ET61X251:	descr = "GSPCA ET61X251"; break;
1326ba300204SHans Verkuil 		case V4L2_PIX_FMT_SPCA561:	descr = "GSPCA SPCA561"; break;
1327ba300204SHans Verkuil 		case V4L2_PIX_FMT_PAC207:	descr = "GSPCA PAC207"; break;
1328ba300204SHans Verkuil 		case V4L2_PIX_FMT_MR97310A:	descr = "GSPCA MR97310A"; break;
1329ba300204SHans Verkuil 		case V4L2_PIX_FMT_JL2005BCD:	descr = "GSPCA JL2005BCD"; break;
1330ba300204SHans Verkuil 		case V4L2_PIX_FMT_SN9C2028:	descr = "GSPCA SN9C2028"; break;
1331ba300204SHans Verkuil 		case V4L2_PIX_FMT_SQ905C:	descr = "GSPCA SQ905C"; break;
1332ba300204SHans Verkuil 		case V4L2_PIX_FMT_PJPG:		descr = "GSPCA PJPG"; break;
1333ba300204SHans Verkuil 		case V4L2_PIX_FMT_OV511:	descr = "GSPCA OV511"; break;
1334ba300204SHans Verkuil 		case V4L2_PIX_FMT_OV518:	descr = "GSPCA OV518"; break;
1335ba300204SHans Verkuil 		case V4L2_PIX_FMT_JPGL:		descr = "JPEG Lite"; break;
1336ba300204SHans Verkuil 		case V4L2_PIX_FMT_SE401:	descr = "GSPCA SE401"; break;
1337ba300204SHans Verkuil 		case V4L2_PIX_FMT_S5C_UYVY_JPG:	descr = "S5C73MX interleaved UYVY/JPEG"; break;
1338d4de6634STiffany Lin 		case V4L2_PIX_FMT_MT21C:	descr = "Mediatek Compressed Format"; break;
1339ba300204SHans Verkuil 		default:
1340ba300204SHans Verkuil 			WARN(1, "Unknown pixelformat 0x%08x\n", fmt->pixelformat);
1341ba300204SHans Verkuil 			if (fmt->description[0])
1342ba300204SHans Verkuil 				return;
1343ba300204SHans Verkuil 			flags = 0;
1344ba300204SHans Verkuil 			snprintf(fmt->description, sz, "%c%c%c%c%s",
1345ba300204SHans Verkuil 					(char)(fmt->pixelformat & 0x7f),
1346ba300204SHans Verkuil 					(char)((fmt->pixelformat >> 8) & 0x7f),
1347ba300204SHans Verkuil 					(char)((fmt->pixelformat >> 16) & 0x7f),
1348ba300204SHans Verkuil 					(char)((fmt->pixelformat >> 24) & 0x7f),
1349ba300204SHans Verkuil 					(fmt->pixelformat & (1 << 31)) ? "-BE" : "");
1350ba300204SHans Verkuil 			break;
1351ba300204SHans Verkuil 		}
1352ba300204SHans Verkuil 	}
1353ba300204SHans Verkuil 
1354ba300204SHans Verkuil 	if (descr)
1355ba300204SHans Verkuil 		WARN_ON(strlcpy(fmt->description, descr, sz) >= sz);
1356ba300204SHans Verkuil 	fmt->flags = flags;
1357ba300204SHans Verkuil }
1358ba300204SHans Verkuil 
13595bc3cb74SMauro Carvalho Chehab static int v4l_enum_fmt(const struct v4l2_ioctl_ops *ops,
13605bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
13615bc3cb74SMauro Carvalho Chehab {
13625bc3cb74SMauro Carvalho Chehab 	struct v4l2_fmtdesc *p = arg;
1363b2469c81SHans Verkuil 	int ret = check_fmt(file, p->type);
1364b2469c81SHans Verkuil 
1365b2469c81SHans Verkuil 	if (ret)
1366b2469c81SHans Verkuil 		return ret;
1367b2469c81SHans Verkuil 	ret = -EINVAL;
13685bc3cb74SMauro Carvalho Chehab 
13695bc3cb74SMauro Carvalho Chehab 	switch (p->type) {
13705bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_CAPTURE:
1371b2469c81SHans Verkuil 		if (unlikely(!ops->vidioc_enum_fmt_vid_cap))
13725bc3cb74SMauro Carvalho Chehab 			break;
1373ba300204SHans Verkuil 		ret = ops->vidioc_enum_fmt_vid_cap(file, fh, arg);
1374ba300204SHans Verkuil 		break;
13755bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
1376b2469c81SHans Verkuil 		if (unlikely(!ops->vidioc_enum_fmt_vid_cap_mplane))
13775bc3cb74SMauro Carvalho Chehab 			break;
1378ba300204SHans Verkuil 		ret = ops->vidioc_enum_fmt_vid_cap_mplane(file, fh, arg);
1379ba300204SHans Verkuil 		break;
13805bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_OVERLAY:
1381b2469c81SHans Verkuil 		if (unlikely(!ops->vidioc_enum_fmt_vid_overlay))
13825bc3cb74SMauro Carvalho Chehab 			break;
1383ba300204SHans Verkuil 		ret = ops->vidioc_enum_fmt_vid_overlay(file, fh, arg);
1384ba300204SHans Verkuil 		break;
13855bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_OUTPUT:
1386b2469c81SHans Verkuil 		if (unlikely(!ops->vidioc_enum_fmt_vid_out))
13875bc3cb74SMauro Carvalho Chehab 			break;
1388ba300204SHans Verkuil 		ret = ops->vidioc_enum_fmt_vid_out(file, fh, arg);
1389ba300204SHans Verkuil 		break;
13905bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
1391b2469c81SHans Verkuil 		if (unlikely(!ops->vidioc_enum_fmt_vid_out_mplane))
13925bc3cb74SMauro Carvalho Chehab 			break;
1393ba300204SHans Verkuil 		ret = ops->vidioc_enum_fmt_vid_out_mplane(file, fh, arg);
1394ba300204SHans Verkuil 		break;
1395582c52cbSAntti Palosaari 	case V4L2_BUF_TYPE_SDR_CAPTURE:
1396b2469c81SHans Verkuil 		if (unlikely(!ops->vidioc_enum_fmt_sdr_cap))
1397582c52cbSAntti Palosaari 			break;
1398ba300204SHans Verkuil 		ret = ops->vidioc_enum_fmt_sdr_cap(file, fh, arg);
1399ba300204SHans Verkuil 		break;
14009effc72fSAntti Palosaari 	case V4L2_BUF_TYPE_SDR_OUTPUT:
1401b2469c81SHans Verkuil 		if (unlikely(!ops->vidioc_enum_fmt_sdr_out))
14029effc72fSAntti Palosaari 			break;
14039effc72fSAntti Palosaari 		ret = ops->vidioc_enum_fmt_sdr_out(file, fh, arg);
14049effc72fSAntti Palosaari 		break;
1405fb9ffa6aSLaurent Pinchart 	case V4L2_BUF_TYPE_META_CAPTURE:
1406b2469c81SHans Verkuil 		if (unlikely(!ops->vidioc_enum_fmt_meta_cap))
1407fb9ffa6aSLaurent Pinchart 			break;
1408fb9ffa6aSLaurent Pinchart 		ret = ops->vidioc_enum_fmt_meta_cap(file, fh, arg);
1409fb9ffa6aSLaurent Pinchart 		break;
14105bc3cb74SMauro Carvalho Chehab 	}
1411ba300204SHans Verkuil 	if (ret == 0)
1412ba300204SHans Verkuil 		v4l_fill_fmtdesc(p);
1413ba300204SHans Verkuil 	return ret;
14145bc3cb74SMauro Carvalho Chehab }
14155bc3cb74SMauro Carvalho Chehab 
14165bc3cb74SMauro Carvalho Chehab static int v4l_g_fmt(const struct v4l2_ioctl_ops *ops,
14175bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
14185bc3cb74SMauro Carvalho Chehab {
14195bc3cb74SMauro Carvalho Chehab 	struct v4l2_format *p = arg;
1420b2469c81SHans Verkuil 	int ret = check_fmt(file, p->type);
1421b2469c81SHans Verkuil 
1422b2469c81SHans Verkuil 	if (ret)
1423b2469c81SHans Verkuil 		return ret;
1424d52e2381SLaurent Pinchart 
1425e5ce558aSHans Verkuil 	/*
1426e5ce558aSHans Verkuil 	 * fmt can't be cleared for these overlay types due to the 'clips'
1427e5ce558aSHans Verkuil 	 * 'clipcount' and 'bitmap' pointers in struct v4l2_window.
1428e5ce558aSHans Verkuil 	 * Those are provided by the user. So handle these two overlay types
1429e5ce558aSHans Verkuil 	 * first, and then just do a simple memset for the other types.
1430e5ce558aSHans Verkuil 	 */
1431e5ce558aSHans Verkuil 	switch (p->type) {
1432e5ce558aSHans Verkuil 	case V4L2_BUF_TYPE_VIDEO_OVERLAY:
1433e5ce558aSHans Verkuil 	case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY: {
14344d1afa51SHans Verkuil 		struct v4l2_clip __user *clips = p->fmt.win.clips;
1435e5ce558aSHans Verkuil 		u32 clipcount = p->fmt.win.clipcount;
14364d1afa51SHans Verkuil 		void __user *bitmap = p->fmt.win.bitmap;
1437e5ce558aSHans Verkuil 
1438e5ce558aSHans Verkuil 		memset(&p->fmt, 0, sizeof(p->fmt));
1439e5ce558aSHans Verkuil 		p->fmt.win.clips = clips;
1440e5ce558aSHans Verkuil 		p->fmt.win.clipcount = clipcount;
1441e5ce558aSHans Verkuil 		p->fmt.win.bitmap = bitmap;
1442e5ce558aSHans Verkuil 		break;
1443e5ce558aSHans Verkuil 	}
1444e5ce558aSHans Verkuil 	default:
1445e5ce558aSHans Verkuil 		memset(&p->fmt, 0, sizeof(p->fmt));
1446e5ce558aSHans Verkuil 		break;
1447e5ce558aSHans Verkuil 	}
1448e5ce558aSHans Verkuil 
14495bc3cb74SMauro Carvalho Chehab 	switch (p->type) {
14505bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_CAPTURE:
1451b2469c81SHans Verkuil 		if (unlikely(!ops->vidioc_g_fmt_vid_cap))
14525bc3cb74SMauro Carvalho Chehab 			break;
145348f2650aSHans Verkuil 		p->fmt.pix.priv = V4L2_PIX_FMT_PRIV_MAGIC;
1454d52e2381SLaurent Pinchart 		ret = ops->vidioc_g_fmt_vid_cap(file, fh, arg);
145548f2650aSHans Verkuil 		/* just in case the driver zeroed it again */
1456d52e2381SLaurent Pinchart 		p->fmt.pix.priv = V4L2_PIX_FMT_PRIV_MAGIC;
1457d52e2381SLaurent Pinchart 		return ret;
14585bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
14595bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_g_fmt_vid_cap_mplane(file, fh, arg);
14605bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_OVERLAY:
14615bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_g_fmt_vid_overlay(file, fh, arg);
14624b20259fSHans Verkuil 	case V4L2_BUF_TYPE_VBI_CAPTURE:
14634b20259fSHans Verkuil 		return ops->vidioc_g_fmt_vbi_cap(file, fh, arg);
14644b20259fSHans Verkuil 	case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
14654b20259fSHans Verkuil 		return ops->vidioc_g_fmt_sliced_vbi_cap(file, fh, arg);
14665bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_OUTPUT:
1467b2469c81SHans Verkuil 		if (unlikely(!ops->vidioc_g_fmt_vid_out))
14685bc3cb74SMauro Carvalho Chehab 			break;
146948f2650aSHans Verkuil 		p->fmt.pix.priv = V4L2_PIX_FMT_PRIV_MAGIC;
1470d52e2381SLaurent Pinchart 		ret = ops->vidioc_g_fmt_vid_out(file, fh, arg);
147148f2650aSHans Verkuil 		/* just in case the driver zeroed it again */
1472d52e2381SLaurent Pinchart 		p->fmt.pix.priv = V4L2_PIX_FMT_PRIV_MAGIC;
1473d52e2381SLaurent Pinchart 		return ret;
14745bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
14755bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_g_fmt_vid_out_mplane(file, fh, arg);
14765bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
14775bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_g_fmt_vid_out_overlay(file, fh, arg);
14785bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VBI_OUTPUT:
14795bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_g_fmt_vbi_out(file, fh, arg);
14805bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
14815bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_g_fmt_sliced_vbi_out(file, fh, arg);
1482582c52cbSAntti Palosaari 	case V4L2_BUF_TYPE_SDR_CAPTURE:
1483582c52cbSAntti Palosaari 		return ops->vidioc_g_fmt_sdr_cap(file, fh, arg);
14849effc72fSAntti Palosaari 	case V4L2_BUF_TYPE_SDR_OUTPUT:
14859effc72fSAntti Palosaari 		return ops->vidioc_g_fmt_sdr_out(file, fh, arg);
1486fb9ffa6aSLaurent Pinchart 	case V4L2_BUF_TYPE_META_CAPTURE:
1487fb9ffa6aSLaurent Pinchart 		return ops->vidioc_g_fmt_meta_cap(file, fh, arg);
14885bc3cb74SMauro Carvalho Chehab 	}
14895bc3cb74SMauro Carvalho Chehab 	return -EINVAL;
14905bc3cb74SMauro Carvalho Chehab }
14915bc3cb74SMauro Carvalho Chehab 
1492b2fe22d0SNick Dyer static void v4l_pix_format_touch(struct v4l2_pix_format *p)
1493b2fe22d0SNick Dyer {
1494b2fe22d0SNick Dyer 	/*
1495b2fe22d0SNick Dyer 	 * The v4l2_pix_format structure contains fields that make no sense for
1496b2fe22d0SNick Dyer 	 * touch. Set them to default values in this case.
1497b2fe22d0SNick Dyer 	 */
1498b2fe22d0SNick Dyer 
1499b2fe22d0SNick Dyer 	p->field = V4L2_FIELD_NONE;
1500b2fe22d0SNick Dyer 	p->colorspace = V4L2_COLORSPACE_RAW;
1501b2fe22d0SNick Dyer 	p->flags = 0;
1502b2fe22d0SNick Dyer 	p->ycbcr_enc = 0;
1503b2fe22d0SNick Dyer 	p->quantization = 0;
1504b2fe22d0SNick Dyer 	p->xfer_func = 0;
1505b2fe22d0SNick Dyer }
1506b2fe22d0SNick Dyer 
15075bc3cb74SMauro Carvalho Chehab static int v4l_s_fmt(const struct v4l2_ioctl_ops *ops,
15085bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
15095bc3cb74SMauro Carvalho Chehab {
15105bc3cb74SMauro Carvalho Chehab 	struct v4l2_format *p = arg;
15114b20259fSHans Verkuil 	struct video_device *vfd = video_devdata(file);
1512b2469c81SHans Verkuil 	int ret = check_fmt(file, p->type);
1513b2469c81SHans Verkuil 
1514b2469c81SHans Verkuil 	if (ret)
1515b2469c81SHans Verkuil 		return ret;
15165bc3cb74SMauro Carvalho Chehab 
151777fa4e07SShuah Khan 	ret = v4l_enable_media_source(vfd);
151877fa4e07SShuah Khan 	if (ret)
151977fa4e07SShuah Khan 		return ret;
1520d52e2381SLaurent Pinchart 	v4l_sanitize_format(p);
1521d52e2381SLaurent Pinchart 
15225bc3cb74SMauro Carvalho Chehab 	switch (p->type) {
15235bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_CAPTURE:
1524b2469c81SHans Verkuil 		if (unlikely(!ops->vidioc_s_fmt_vid_cap))
15255bc3cb74SMauro Carvalho Chehab 			break;
15265bc3cb74SMauro Carvalho Chehab 		CLEAR_AFTER_FIELD(p, fmt.pix);
152748f2650aSHans Verkuil 		ret = ops->vidioc_s_fmt_vid_cap(file, fh, arg);
152848f2650aSHans Verkuil 		/* just in case the driver zeroed it again */
152948f2650aSHans Verkuil 		p->fmt.pix.priv = V4L2_PIX_FMT_PRIV_MAGIC;
1530b2469c81SHans Verkuil 		if (vfd->vfl_type == VFL_TYPE_TOUCH)
1531b2fe22d0SNick Dyer 			v4l_pix_format_touch(&p->fmt.pix);
153248f2650aSHans Verkuil 		return ret;
15335bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
1534b2469c81SHans Verkuil 		if (unlikely(!ops->vidioc_s_fmt_vid_cap_mplane))
15355bc3cb74SMauro Carvalho Chehab 			break;
1536c49148e8SLaurent Pinchart 		CLEAR_AFTER_FIELD(p, fmt.pix_mp.xfer_func);
15375bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_s_fmt_vid_cap_mplane(file, fh, arg);
15385bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_OVERLAY:
1539b2469c81SHans Verkuil 		if (unlikely(!ops->vidioc_s_fmt_vid_overlay))
15405bc3cb74SMauro Carvalho Chehab 			break;
15415bc3cb74SMauro Carvalho Chehab 		CLEAR_AFTER_FIELD(p, fmt.win);
15425bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_s_fmt_vid_overlay(file, fh, arg);
15434b20259fSHans Verkuil 	case V4L2_BUF_TYPE_VBI_CAPTURE:
1544b2469c81SHans Verkuil 		if (unlikely(!ops->vidioc_s_fmt_vbi_cap))
15454b20259fSHans Verkuil 			break;
15464b20259fSHans Verkuil 		CLEAR_AFTER_FIELD(p, fmt.vbi);
15474b20259fSHans Verkuil 		return ops->vidioc_s_fmt_vbi_cap(file, fh, arg);
15484b20259fSHans Verkuil 	case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
1549b2469c81SHans Verkuil 		if (unlikely(!ops->vidioc_s_fmt_sliced_vbi_cap))
15504b20259fSHans Verkuil 			break;
15514b20259fSHans Verkuil 		CLEAR_AFTER_FIELD(p, fmt.sliced);
15524b20259fSHans Verkuil 		return ops->vidioc_s_fmt_sliced_vbi_cap(file, fh, arg);
15535bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_OUTPUT:
1554b2469c81SHans Verkuil 		if (unlikely(!ops->vidioc_s_fmt_vid_out))
15555bc3cb74SMauro Carvalho Chehab 			break;
15565bc3cb74SMauro Carvalho Chehab 		CLEAR_AFTER_FIELD(p, fmt.pix);
155748f2650aSHans Verkuil 		ret = ops->vidioc_s_fmt_vid_out(file, fh, arg);
155848f2650aSHans Verkuil 		/* just in case the driver zeroed it again */
155948f2650aSHans Verkuil 		p->fmt.pix.priv = V4L2_PIX_FMT_PRIV_MAGIC;
156048f2650aSHans Verkuil 		return ret;
15615bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
1562b2469c81SHans Verkuil 		if (unlikely(!ops->vidioc_s_fmt_vid_out_mplane))
15635bc3cb74SMauro Carvalho Chehab 			break;
1564c49148e8SLaurent Pinchart 		CLEAR_AFTER_FIELD(p, fmt.pix_mp.xfer_func);
15655bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_s_fmt_vid_out_mplane(file, fh, arg);
15665bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
1567b2469c81SHans Verkuil 		if (unlikely(!ops->vidioc_s_fmt_vid_out_overlay))
15685bc3cb74SMauro Carvalho Chehab 			break;
15695bc3cb74SMauro Carvalho Chehab 		CLEAR_AFTER_FIELD(p, fmt.win);
15705bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_s_fmt_vid_out_overlay(file, fh, arg);
15715bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VBI_OUTPUT:
1572b2469c81SHans Verkuil 		if (unlikely(!ops->vidioc_s_fmt_vbi_out))
15735bc3cb74SMauro Carvalho Chehab 			break;
15745bc3cb74SMauro Carvalho Chehab 		CLEAR_AFTER_FIELD(p, fmt.vbi);
15755bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_s_fmt_vbi_out(file, fh, arg);
15765bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
1577b2469c81SHans Verkuil 		if (unlikely(!ops->vidioc_s_fmt_sliced_vbi_out))
15785bc3cb74SMauro Carvalho Chehab 			break;
15795bc3cb74SMauro Carvalho Chehab 		CLEAR_AFTER_FIELD(p, fmt.sliced);
15805bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_s_fmt_sliced_vbi_out(file, fh, arg);
1581582c52cbSAntti Palosaari 	case V4L2_BUF_TYPE_SDR_CAPTURE:
1582b2469c81SHans Verkuil 		if (unlikely(!ops->vidioc_s_fmt_sdr_cap))
1583582c52cbSAntti Palosaari 			break;
1584582c52cbSAntti Palosaari 		CLEAR_AFTER_FIELD(p, fmt.sdr);
1585582c52cbSAntti Palosaari 		return ops->vidioc_s_fmt_sdr_cap(file, fh, arg);
15869effc72fSAntti Palosaari 	case V4L2_BUF_TYPE_SDR_OUTPUT:
1587b2469c81SHans Verkuil 		if (unlikely(!ops->vidioc_s_fmt_sdr_out))
15889effc72fSAntti Palosaari 			break;
15899effc72fSAntti Palosaari 		CLEAR_AFTER_FIELD(p, fmt.sdr);
15909effc72fSAntti Palosaari 		return ops->vidioc_s_fmt_sdr_out(file, fh, arg);
1591fb9ffa6aSLaurent Pinchart 	case V4L2_BUF_TYPE_META_CAPTURE:
1592b2469c81SHans Verkuil 		if (unlikely(!ops->vidioc_s_fmt_meta_cap))
1593fb9ffa6aSLaurent Pinchart 			break;
1594fb9ffa6aSLaurent Pinchart 		CLEAR_AFTER_FIELD(p, fmt.meta);
1595fb9ffa6aSLaurent Pinchart 		return ops->vidioc_s_fmt_meta_cap(file, fh, arg);
15965bc3cb74SMauro Carvalho Chehab 	}
15975bc3cb74SMauro Carvalho Chehab 	return -EINVAL;
15985bc3cb74SMauro Carvalho Chehab }
15995bc3cb74SMauro Carvalho Chehab 
16005bc3cb74SMauro Carvalho Chehab static int v4l_try_fmt(const struct v4l2_ioctl_ops *ops,
16015bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
16025bc3cb74SMauro Carvalho Chehab {
16035bc3cb74SMauro Carvalho Chehab 	struct v4l2_format *p = arg;
1604b2469c81SHans Verkuil 	int ret = check_fmt(file, p->type);
1605b2469c81SHans Verkuil 
1606b2469c81SHans Verkuil 	if (ret)
1607b2469c81SHans Verkuil 		return ret;
16085bc3cb74SMauro Carvalho Chehab 
1609d52e2381SLaurent Pinchart 	v4l_sanitize_format(p);
1610d52e2381SLaurent Pinchart 
16115bc3cb74SMauro Carvalho Chehab 	switch (p->type) {
16125bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_CAPTURE:
1613b2469c81SHans Verkuil 		if (unlikely(!ops->vidioc_try_fmt_vid_cap))
16145bc3cb74SMauro Carvalho Chehab 			break;
16155bc3cb74SMauro Carvalho Chehab 		CLEAR_AFTER_FIELD(p, fmt.pix);
161648f2650aSHans Verkuil 		ret = ops->vidioc_try_fmt_vid_cap(file, fh, arg);
161748f2650aSHans Verkuil 		/* just in case the driver zeroed it again */
161848f2650aSHans Verkuil 		p->fmt.pix.priv = V4L2_PIX_FMT_PRIV_MAGIC;
161948f2650aSHans Verkuil 		return ret;
16205bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
1621b2469c81SHans Verkuil 		if (unlikely(!ops->vidioc_try_fmt_vid_cap_mplane))
16225bc3cb74SMauro Carvalho Chehab 			break;
1623c49148e8SLaurent Pinchart 		CLEAR_AFTER_FIELD(p, fmt.pix_mp.xfer_func);
16245bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_try_fmt_vid_cap_mplane(file, fh, arg);
16255bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_OVERLAY:
1626b2469c81SHans Verkuil 		if (unlikely(!ops->vidioc_try_fmt_vid_overlay))
16275bc3cb74SMauro Carvalho Chehab 			break;
16285bc3cb74SMauro Carvalho Chehab 		CLEAR_AFTER_FIELD(p, fmt.win);
16295bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_try_fmt_vid_overlay(file, fh, arg);
16304b20259fSHans Verkuil 	case V4L2_BUF_TYPE_VBI_CAPTURE:
1631b2469c81SHans Verkuil 		if (unlikely(!ops->vidioc_try_fmt_vbi_cap))
16324b20259fSHans Verkuil 			break;
16334b20259fSHans Verkuil 		CLEAR_AFTER_FIELD(p, fmt.vbi);
16344b20259fSHans Verkuil 		return ops->vidioc_try_fmt_vbi_cap(file, fh, arg);
16354b20259fSHans Verkuil 	case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
1636b2469c81SHans Verkuil 		if (unlikely(!ops->vidioc_try_fmt_sliced_vbi_cap))
16374b20259fSHans Verkuil 			break;
16384b20259fSHans Verkuil 		CLEAR_AFTER_FIELD(p, fmt.sliced);
16394b20259fSHans Verkuil 		return ops->vidioc_try_fmt_sliced_vbi_cap(file, fh, arg);
16405bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_OUTPUT:
1641b2469c81SHans Verkuil 		if (unlikely(!ops->vidioc_try_fmt_vid_out))
16425bc3cb74SMauro Carvalho Chehab 			break;
16435bc3cb74SMauro Carvalho Chehab 		CLEAR_AFTER_FIELD(p, fmt.pix);
164448f2650aSHans Verkuil 		ret = ops->vidioc_try_fmt_vid_out(file, fh, arg);
164548f2650aSHans Verkuil 		/* just in case the driver zeroed it again */
164648f2650aSHans Verkuil 		p->fmt.pix.priv = V4L2_PIX_FMT_PRIV_MAGIC;
164748f2650aSHans Verkuil 		return ret;
16485bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
1649b2469c81SHans Verkuil 		if (unlikely(!ops->vidioc_try_fmt_vid_out_mplane))
16505bc3cb74SMauro Carvalho Chehab 			break;
1651c49148e8SLaurent Pinchart 		CLEAR_AFTER_FIELD(p, fmt.pix_mp.xfer_func);
16525bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_try_fmt_vid_out_mplane(file, fh, arg);
16535bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
1654b2469c81SHans Verkuil 		if (unlikely(!ops->vidioc_try_fmt_vid_out_overlay))
16555bc3cb74SMauro Carvalho Chehab 			break;
16565bc3cb74SMauro Carvalho Chehab 		CLEAR_AFTER_FIELD(p, fmt.win);
16575bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_try_fmt_vid_out_overlay(file, fh, arg);
16585bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VBI_OUTPUT:
1659b2469c81SHans Verkuil 		if (unlikely(!ops->vidioc_try_fmt_vbi_out))
16605bc3cb74SMauro Carvalho Chehab 			break;
16615bc3cb74SMauro Carvalho Chehab 		CLEAR_AFTER_FIELD(p, fmt.vbi);
16625bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_try_fmt_vbi_out(file, fh, arg);
16635bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
1664b2469c81SHans Verkuil 		if (unlikely(!ops->vidioc_try_fmt_sliced_vbi_out))
16655bc3cb74SMauro Carvalho Chehab 			break;
16665bc3cb74SMauro Carvalho Chehab 		CLEAR_AFTER_FIELD(p, fmt.sliced);
16675bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_try_fmt_sliced_vbi_out(file, fh, arg);
1668582c52cbSAntti Palosaari 	case V4L2_BUF_TYPE_SDR_CAPTURE:
1669b2469c81SHans Verkuil 		if (unlikely(!ops->vidioc_try_fmt_sdr_cap))
1670582c52cbSAntti Palosaari 			break;
1671582c52cbSAntti Palosaari 		CLEAR_AFTER_FIELD(p, fmt.sdr);
1672582c52cbSAntti Palosaari 		return ops->vidioc_try_fmt_sdr_cap(file, fh, arg);
16739effc72fSAntti Palosaari 	case V4L2_BUF_TYPE_SDR_OUTPUT:
1674b2469c81SHans Verkuil 		if (unlikely(!ops->vidioc_try_fmt_sdr_out))
16759effc72fSAntti Palosaari 			break;
16769effc72fSAntti Palosaari 		CLEAR_AFTER_FIELD(p, fmt.sdr);
16779effc72fSAntti Palosaari 		return ops->vidioc_try_fmt_sdr_out(file, fh, arg);
1678fb9ffa6aSLaurent Pinchart 	case V4L2_BUF_TYPE_META_CAPTURE:
1679b2469c81SHans Verkuil 		if (unlikely(!ops->vidioc_try_fmt_meta_cap))
1680fb9ffa6aSLaurent Pinchart 			break;
1681fb9ffa6aSLaurent Pinchart 		CLEAR_AFTER_FIELD(p, fmt.meta);
1682fb9ffa6aSLaurent Pinchart 		return ops->vidioc_try_fmt_meta_cap(file, fh, arg);
16835bc3cb74SMauro Carvalho Chehab 	}
16845bc3cb74SMauro Carvalho Chehab 	return -EINVAL;
16855bc3cb74SMauro Carvalho Chehab }
16865bc3cb74SMauro Carvalho Chehab 
16875bc3cb74SMauro Carvalho Chehab static int v4l_streamon(const struct v4l2_ioctl_ops *ops,
16885bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
16895bc3cb74SMauro Carvalho Chehab {
16905bc3cb74SMauro Carvalho Chehab 	return ops->vidioc_streamon(file, fh, *(unsigned int *)arg);
16915bc3cb74SMauro Carvalho Chehab }
16925bc3cb74SMauro Carvalho Chehab 
16935bc3cb74SMauro Carvalho Chehab static int v4l_streamoff(const struct v4l2_ioctl_ops *ops,
16945bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
16955bc3cb74SMauro Carvalho Chehab {
16965bc3cb74SMauro Carvalho Chehab 	return ops->vidioc_streamoff(file, fh, *(unsigned int *)arg);
16975bc3cb74SMauro Carvalho Chehab }
16985bc3cb74SMauro Carvalho Chehab 
16995bc3cb74SMauro Carvalho Chehab static int v4l_g_tuner(const struct v4l2_ioctl_ops *ops,
17005bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
17015bc3cb74SMauro Carvalho Chehab {
17025bc3cb74SMauro Carvalho Chehab 	struct video_device *vfd = video_devdata(file);
17035bc3cb74SMauro Carvalho Chehab 	struct v4l2_tuner *p = arg;
17045bc3cb74SMauro Carvalho Chehab 	int err;
17055bc3cb74SMauro Carvalho Chehab 
17065bc3cb74SMauro Carvalho Chehab 	p->type = (vfd->vfl_type == VFL_TYPE_RADIO) ?
17075bc3cb74SMauro Carvalho Chehab 			V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV;
17085bc3cb74SMauro Carvalho Chehab 	err = ops->vidioc_g_tuner(file, fh, p);
17095bc3cb74SMauro Carvalho Chehab 	if (!err)
17105bc3cb74SMauro Carvalho Chehab 		p->capability |= V4L2_TUNER_CAP_FREQ_BANDS;
17115bc3cb74SMauro Carvalho Chehab 	return err;
17125bc3cb74SMauro Carvalho Chehab }
17135bc3cb74SMauro Carvalho Chehab 
17145bc3cb74SMauro Carvalho Chehab static int v4l_s_tuner(const struct v4l2_ioctl_ops *ops,
17155bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
17165bc3cb74SMauro Carvalho Chehab {
17175bc3cb74SMauro Carvalho Chehab 	struct video_device *vfd = video_devdata(file);
17185bc3cb74SMauro Carvalho Chehab 	struct v4l2_tuner *p = arg;
171977fa4e07SShuah Khan 	int ret;
17205bc3cb74SMauro Carvalho Chehab 
172177fa4e07SShuah Khan 	ret = v4l_enable_media_source(vfd);
172277fa4e07SShuah Khan 	if (ret)
172377fa4e07SShuah Khan 		return ret;
17245bc3cb74SMauro Carvalho Chehab 	p->type = (vfd->vfl_type == VFL_TYPE_RADIO) ?
17255bc3cb74SMauro Carvalho Chehab 			V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV;
17265bc3cb74SMauro Carvalho Chehab 	return ops->vidioc_s_tuner(file, fh, p);
17275bc3cb74SMauro Carvalho Chehab }
17285bc3cb74SMauro Carvalho Chehab 
17295bc3cb74SMauro Carvalho Chehab static int v4l_g_modulator(const struct v4l2_ioctl_ops *ops,
17305bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
17315bc3cb74SMauro Carvalho Chehab {
17324124a3c4SAntti Palosaari 	struct video_device *vfd = video_devdata(file);
17335bc3cb74SMauro Carvalho Chehab 	struct v4l2_modulator *p = arg;
17345bc3cb74SMauro Carvalho Chehab 	int err;
17355bc3cb74SMauro Carvalho Chehab 
17364124a3c4SAntti Palosaari 	if (vfd->vfl_type == VFL_TYPE_RADIO)
17374124a3c4SAntti Palosaari 		p->type = V4L2_TUNER_RADIO;
17384124a3c4SAntti Palosaari 
17395bc3cb74SMauro Carvalho Chehab 	err = ops->vidioc_g_modulator(file, fh, p);
17405bc3cb74SMauro Carvalho Chehab 	if (!err)
17415bc3cb74SMauro Carvalho Chehab 		p->capability |= V4L2_TUNER_CAP_FREQ_BANDS;
17425bc3cb74SMauro Carvalho Chehab 	return err;
17435bc3cb74SMauro Carvalho Chehab }
17445bc3cb74SMauro Carvalho Chehab 
17454124a3c4SAntti Palosaari static int v4l_s_modulator(const struct v4l2_ioctl_ops *ops,
17464124a3c4SAntti Palosaari 				struct file *file, void *fh, void *arg)
17474124a3c4SAntti Palosaari {
17484124a3c4SAntti Palosaari 	struct video_device *vfd = video_devdata(file);
17494124a3c4SAntti Palosaari 	struct v4l2_modulator *p = arg;
17504124a3c4SAntti Palosaari 
17514124a3c4SAntti Palosaari 	if (vfd->vfl_type == VFL_TYPE_RADIO)
17524124a3c4SAntti Palosaari 		p->type = V4L2_TUNER_RADIO;
17534124a3c4SAntti Palosaari 
17544124a3c4SAntti Palosaari 	return ops->vidioc_s_modulator(file, fh, p);
17554124a3c4SAntti Palosaari }
17564124a3c4SAntti Palosaari 
17575bc3cb74SMauro Carvalho Chehab static int v4l_g_frequency(const struct v4l2_ioctl_ops *ops,
17585bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
17595bc3cb74SMauro Carvalho Chehab {
17605bc3cb74SMauro Carvalho Chehab 	struct video_device *vfd = video_devdata(file);
17615bc3cb74SMauro Carvalho Chehab 	struct v4l2_frequency *p = arg;
17625bc3cb74SMauro Carvalho Chehab 
176384099a28SAntti Palosaari 	if (vfd->vfl_type == VFL_TYPE_SDR)
1764f3c3ececSAntti Palosaari 		p->type = V4L2_TUNER_SDR;
176584099a28SAntti Palosaari 	else
17665bc3cb74SMauro Carvalho Chehab 		p->type = (vfd->vfl_type == VFL_TYPE_RADIO) ?
17675bc3cb74SMauro Carvalho Chehab 				V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV;
17685bc3cb74SMauro Carvalho Chehab 	return ops->vidioc_g_frequency(file, fh, p);
17695bc3cb74SMauro Carvalho Chehab }
17705bc3cb74SMauro Carvalho Chehab 
17715bc3cb74SMauro Carvalho Chehab static int v4l_s_frequency(const struct v4l2_ioctl_ops *ops,
17725bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
17735bc3cb74SMauro Carvalho Chehab {
17745bc3cb74SMauro Carvalho Chehab 	struct video_device *vfd = video_devdata(file);
1775b530a447SHans Verkuil 	const struct v4l2_frequency *p = arg;
17765bc3cb74SMauro Carvalho Chehab 	enum v4l2_tuner_type type;
177777fa4e07SShuah Khan 	int ret;
17785bc3cb74SMauro Carvalho Chehab 
177977fa4e07SShuah Khan 	ret = v4l_enable_media_source(vfd);
178077fa4e07SShuah Khan 	if (ret)
178177fa4e07SShuah Khan 		return ret;
178284099a28SAntti Palosaari 	if (vfd->vfl_type == VFL_TYPE_SDR) {
1783f3c3ececSAntti Palosaari 		if (p->type != V4L2_TUNER_SDR && p->type != V4L2_TUNER_RF)
178484099a28SAntti Palosaari 			return -EINVAL;
178584099a28SAntti Palosaari 	} else {
17865bc3cb74SMauro Carvalho Chehab 		type = (vfd->vfl_type == VFL_TYPE_RADIO) ?
17875bc3cb74SMauro Carvalho Chehab 				V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV;
178884099a28SAntti Palosaari 		if (type != p->type)
17895bc3cb74SMauro Carvalho Chehab 			return -EINVAL;
179084099a28SAntti Palosaari 	}
17915bc3cb74SMauro Carvalho Chehab 	return ops->vidioc_s_frequency(file, fh, p);
17925bc3cb74SMauro Carvalho Chehab }
17935bc3cb74SMauro Carvalho Chehab 
17945bc3cb74SMauro Carvalho Chehab static int v4l_enumstd(const struct v4l2_ioctl_ops *ops,
17955bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
17965bc3cb74SMauro Carvalho Chehab {
17975bc3cb74SMauro Carvalho Chehab 	struct video_device *vfd = video_devdata(file);
17985bc3cb74SMauro Carvalho Chehab 	struct v4l2_standard *p = arg;
17995bc3cb74SMauro Carvalho Chehab 
1800aa2f8871SNiklas Söderlund 	return v4l_video_std_enumstd(p, vfd->tvnorms);
18015bc3cb74SMauro Carvalho Chehab }
18025bc3cb74SMauro Carvalho Chehab 
18035bc3cb74SMauro Carvalho Chehab static int v4l_s_std(const struct v4l2_ioctl_ops *ops,
18045bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
18055bc3cb74SMauro Carvalho Chehab {
18065bc3cb74SMauro Carvalho Chehab 	struct video_device *vfd = video_devdata(file);
1807314527acSHans Verkuil 	v4l2_std_id id = *(v4l2_std_id *)arg, norm;
180877fa4e07SShuah Khan 	int ret;
18095bc3cb74SMauro Carvalho Chehab 
181077fa4e07SShuah Khan 	ret = v4l_enable_media_source(vfd);
181177fa4e07SShuah Khan 	if (ret)
181277fa4e07SShuah Khan 		return ret;
1813314527acSHans Verkuil 	norm = id & vfd->tvnorms;
18145bc3cb74SMauro Carvalho Chehab 	if (vfd->tvnorms && !norm)	/* Check if std is supported */
18155bc3cb74SMauro Carvalho Chehab 		return -EINVAL;
18165bc3cb74SMauro Carvalho Chehab 
18175bc3cb74SMauro Carvalho Chehab 	/* Calls the specific handler */
1818ca371575SHans Verkuil 	return ops->vidioc_s_std(file, fh, norm);
18195bc3cb74SMauro Carvalho Chehab }
18205bc3cb74SMauro Carvalho Chehab 
18215bc3cb74SMauro Carvalho Chehab static int v4l_querystd(const struct v4l2_ioctl_ops *ops,
18225bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
18235bc3cb74SMauro Carvalho Chehab {
18245bc3cb74SMauro Carvalho Chehab 	struct video_device *vfd = video_devdata(file);
18255bc3cb74SMauro Carvalho Chehab 	v4l2_std_id *p = arg;
182677fa4e07SShuah Khan 	int ret;
18275bc3cb74SMauro Carvalho Chehab 
182877fa4e07SShuah Khan 	ret = v4l_enable_media_source(vfd);
182977fa4e07SShuah Khan 	if (ret)
183077fa4e07SShuah Khan 		return ret;
18315bc3cb74SMauro Carvalho Chehab 	/*
18321a2c6866SHans Verkuil 	 * If no signal is detected, then the driver should return
18331a2c6866SHans Verkuil 	 * V4L2_STD_UNKNOWN. Otherwise it should return tvnorms with
18341a2c6866SHans Verkuil 	 * any standards that do not apply removed.
18351a2c6866SHans Verkuil 	 *
18365bc3cb74SMauro Carvalho Chehab 	 * This means that tuners, audio and video decoders can join
18375bc3cb74SMauro Carvalho Chehab 	 * their efforts to improve the standards detection.
18385bc3cb74SMauro Carvalho Chehab 	 */
18395bc3cb74SMauro Carvalho Chehab 	*p = vfd->tvnorms;
18405bc3cb74SMauro Carvalho Chehab 	return ops->vidioc_querystd(file, fh, arg);
18415bc3cb74SMauro Carvalho Chehab }
18425bc3cb74SMauro Carvalho Chehab 
18435bc3cb74SMauro Carvalho Chehab static int v4l_s_hw_freq_seek(const struct v4l2_ioctl_ops *ops,
18445bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
18455bc3cb74SMauro Carvalho Chehab {
18465bc3cb74SMauro Carvalho Chehab 	struct video_device *vfd = video_devdata(file);
18475bc3cb74SMauro Carvalho Chehab 	struct v4l2_hw_freq_seek *p = arg;
18485bc3cb74SMauro Carvalho Chehab 	enum v4l2_tuner_type type;
184977fa4e07SShuah Khan 	int ret;
18505bc3cb74SMauro Carvalho Chehab 
185177fa4e07SShuah Khan 	ret = v4l_enable_media_source(vfd);
185277fa4e07SShuah Khan 	if (ret)
185377fa4e07SShuah Khan 		return ret;
185484099a28SAntti Palosaari 	/* s_hw_freq_seek is not supported for SDR for now */
185584099a28SAntti Palosaari 	if (vfd->vfl_type == VFL_TYPE_SDR)
185684099a28SAntti Palosaari 		return -EINVAL;
185784099a28SAntti Palosaari 
18585bc3cb74SMauro Carvalho Chehab 	type = (vfd->vfl_type == VFL_TYPE_RADIO) ?
18595bc3cb74SMauro Carvalho Chehab 		V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV;
18605bc3cb74SMauro Carvalho Chehab 	if (p->type != type)
18615bc3cb74SMauro Carvalho Chehab 		return -EINVAL;
18625bc3cb74SMauro Carvalho Chehab 	return ops->vidioc_s_hw_freq_seek(file, fh, p);
18635bc3cb74SMauro Carvalho Chehab }
18645bc3cb74SMauro Carvalho Chehab 
1865737c097bSHans Verkuil static int v4l_overlay(const struct v4l2_ioctl_ops *ops,
1866737c097bSHans Verkuil 				struct file *file, void *fh, void *arg)
1867737c097bSHans Verkuil {
1868737c097bSHans Verkuil 	return ops->vidioc_overlay(file, fh, *(unsigned int *)arg);
1869737c097bSHans Verkuil }
1870737c097bSHans Verkuil 
18715bc3cb74SMauro Carvalho Chehab static int v4l_reqbufs(const struct v4l2_ioctl_ops *ops,
18725bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
18735bc3cb74SMauro Carvalho Chehab {
18745bc3cb74SMauro Carvalho Chehab 	struct v4l2_requestbuffers *p = arg;
18754b20259fSHans Verkuil 	int ret = check_fmt(file, p->type);
18765bc3cb74SMauro Carvalho Chehab 
18775bc3cb74SMauro Carvalho Chehab 	if (ret)
18785bc3cb74SMauro Carvalho Chehab 		return ret;
18795bc3cb74SMauro Carvalho Chehab 
18805bc3cb74SMauro Carvalho Chehab 	CLEAR_AFTER_FIELD(p, memory);
18815bc3cb74SMauro Carvalho Chehab 
18825bc3cb74SMauro Carvalho Chehab 	return ops->vidioc_reqbufs(file, fh, p);
18835bc3cb74SMauro Carvalho Chehab }
18845bc3cb74SMauro Carvalho Chehab 
18855bc3cb74SMauro Carvalho Chehab static int v4l_querybuf(const struct v4l2_ioctl_ops *ops,
18865bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
18875bc3cb74SMauro Carvalho Chehab {
18885bc3cb74SMauro Carvalho Chehab 	struct v4l2_buffer *p = arg;
18894b20259fSHans Verkuil 	int ret = check_fmt(file, p->type);
18905bc3cb74SMauro Carvalho Chehab 
18915bc3cb74SMauro Carvalho Chehab 	return ret ? ret : ops->vidioc_querybuf(file, fh, p);
18925bc3cb74SMauro Carvalho Chehab }
18935bc3cb74SMauro Carvalho Chehab 
18945bc3cb74SMauro Carvalho Chehab static int v4l_qbuf(const struct v4l2_ioctl_ops *ops,
18955bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
18965bc3cb74SMauro Carvalho Chehab {
18975bc3cb74SMauro Carvalho Chehab 	struct v4l2_buffer *p = arg;
18984b20259fSHans Verkuil 	int ret = check_fmt(file, p->type);
18995bc3cb74SMauro Carvalho Chehab 
19005bc3cb74SMauro Carvalho Chehab 	return ret ? ret : ops->vidioc_qbuf(file, fh, p);
19015bc3cb74SMauro Carvalho Chehab }
19025bc3cb74SMauro Carvalho Chehab 
19035bc3cb74SMauro Carvalho Chehab static int v4l_dqbuf(const struct v4l2_ioctl_ops *ops,
19045bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
19055bc3cb74SMauro Carvalho Chehab {
19065bc3cb74SMauro Carvalho Chehab 	struct v4l2_buffer *p = arg;
19074b20259fSHans Verkuil 	int ret = check_fmt(file, p->type);
19085bc3cb74SMauro Carvalho Chehab 
19095bc3cb74SMauro Carvalho Chehab 	return ret ? ret : ops->vidioc_dqbuf(file, fh, p);
19105bc3cb74SMauro Carvalho Chehab }
19115bc3cb74SMauro Carvalho Chehab 
19125bc3cb74SMauro Carvalho Chehab static int v4l_create_bufs(const struct v4l2_ioctl_ops *ops,
19135bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
19145bc3cb74SMauro Carvalho Chehab {
19155bc3cb74SMauro Carvalho Chehab 	struct v4l2_create_buffers *create = arg;
19164b20259fSHans Verkuil 	int ret = check_fmt(file, create->format.type);
19175bc3cb74SMauro Carvalho Chehab 
1918d52e2381SLaurent Pinchart 	if (ret)
1919d52e2381SLaurent Pinchart 		return ret;
1920d52e2381SLaurent Pinchart 
19215d351251SHans Verkuil 	CLEAR_AFTER_FIELD(create, format);
19225d351251SHans Verkuil 
1923d52e2381SLaurent Pinchart 	v4l_sanitize_format(&create->format);
1924d52e2381SLaurent Pinchart 
1925d52e2381SLaurent Pinchart 	ret = ops->vidioc_create_bufs(file, fh, create);
1926d52e2381SLaurent Pinchart 
1927d52e2381SLaurent Pinchart 	if (create->format.type == V4L2_BUF_TYPE_VIDEO_CAPTURE ||
1928d52e2381SLaurent Pinchart 	    create->format.type == V4L2_BUF_TYPE_VIDEO_OUTPUT)
1929d52e2381SLaurent Pinchart 		create->format.fmt.pix.priv = V4L2_PIX_FMT_PRIV_MAGIC;
1930d52e2381SLaurent Pinchart 
1931d52e2381SLaurent Pinchart 	return ret;
19325bc3cb74SMauro Carvalho Chehab }
19335bc3cb74SMauro Carvalho Chehab 
19345bc3cb74SMauro Carvalho Chehab static int v4l_prepare_buf(const struct v4l2_ioctl_ops *ops,
19355bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
19365bc3cb74SMauro Carvalho Chehab {
19375bc3cb74SMauro Carvalho Chehab 	struct v4l2_buffer *b = arg;
19384b20259fSHans Verkuil 	int ret = check_fmt(file, b->type);
19395bc3cb74SMauro Carvalho Chehab 
19405bc3cb74SMauro Carvalho Chehab 	return ret ? ret : ops->vidioc_prepare_buf(file, fh, b);
19415bc3cb74SMauro Carvalho Chehab }
19425bc3cb74SMauro Carvalho Chehab 
19435bc3cb74SMauro Carvalho Chehab static int v4l_g_parm(const struct v4l2_ioctl_ops *ops,
19445bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
19455bc3cb74SMauro Carvalho Chehab {
19465bc3cb74SMauro Carvalho Chehab 	struct v4l2_streamparm *p = arg;
19475bc3cb74SMauro Carvalho Chehab 	v4l2_std_id std;
19484b20259fSHans Verkuil 	int ret = check_fmt(file, p->type);
19495bc3cb74SMauro Carvalho Chehab 
19505bc3cb74SMauro Carvalho Chehab 	if (ret)
19515bc3cb74SMauro Carvalho Chehab 		return ret;
19525bc3cb74SMauro Carvalho Chehab 	if (ops->vidioc_g_parm)
19535bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_g_parm(file, fh, p);
19545bc3cb74SMauro Carvalho Chehab 	if (p->type != V4L2_BUF_TYPE_VIDEO_CAPTURE &&
19555bc3cb74SMauro Carvalho Chehab 	    p->type != V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
19565bc3cb74SMauro Carvalho Chehab 		return -EINVAL;
19575bc3cb74SMauro Carvalho Chehab 	p->parm.capture.readbuffers = 2;
19585bc3cb74SMauro Carvalho Chehab 	ret = ops->vidioc_g_std(file, fh, &std);
19595bc3cb74SMauro Carvalho Chehab 	if (ret == 0)
1960ca371575SHans Verkuil 		v4l2_video_std_frame_period(std, &p->parm.capture.timeperframe);
19615bc3cb74SMauro Carvalho Chehab 	return ret;
19625bc3cb74SMauro Carvalho Chehab }
19635bc3cb74SMauro Carvalho Chehab 
19645bc3cb74SMauro Carvalho Chehab static int v4l_s_parm(const struct v4l2_ioctl_ops *ops,
19655bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
19665bc3cb74SMauro Carvalho Chehab {
19675bc3cb74SMauro Carvalho Chehab 	struct v4l2_streamparm *p = arg;
19684b20259fSHans Verkuil 	int ret = check_fmt(file, p->type);
19695bc3cb74SMauro Carvalho Chehab 
19708a7c5594SHans Verkuil 	if (ret)
19718a7c5594SHans Verkuil 		return ret;
19728a7c5594SHans Verkuil 
19738a7c5594SHans Verkuil 	/* Note: extendedmode is never used in drivers */
19748a7c5594SHans Verkuil 	if (V4L2_TYPE_IS_OUTPUT(p->type)) {
19758a7c5594SHans Verkuil 		memset(p->parm.output.reserved, 0,
19768a7c5594SHans Verkuil 		       sizeof(p->parm.output.reserved));
19778a7c5594SHans Verkuil 		p->parm.output.extendedmode = 0;
19788a7c5594SHans Verkuil 		p->parm.output.outputmode &= V4L2_MODE_HIGHQUALITY;
19798a7c5594SHans Verkuil 	} else {
19808a7c5594SHans Verkuil 		memset(p->parm.capture.reserved, 0,
19818a7c5594SHans Verkuil 		       sizeof(p->parm.capture.reserved));
19828a7c5594SHans Verkuil 		p->parm.capture.extendedmode = 0;
19838a7c5594SHans Verkuil 		p->parm.capture.capturemode &= V4L2_MODE_HIGHQUALITY;
19848a7c5594SHans Verkuil 	}
19858a7c5594SHans Verkuil 	return ops->vidioc_s_parm(file, fh, p);
19865bc3cb74SMauro Carvalho Chehab }
19875bc3cb74SMauro Carvalho Chehab 
19885bc3cb74SMauro Carvalho Chehab static int v4l_queryctrl(const struct v4l2_ioctl_ops *ops,
19895bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
19905bc3cb74SMauro Carvalho Chehab {
19915bc3cb74SMauro Carvalho Chehab 	struct video_device *vfd = video_devdata(file);
19925bc3cb74SMauro Carvalho Chehab 	struct v4l2_queryctrl *p = arg;
19935bc3cb74SMauro Carvalho Chehab 	struct v4l2_fh *vfh =
19945bc3cb74SMauro Carvalho Chehab 		test_bit(V4L2_FL_USES_V4L2_FH, &vfd->flags) ? fh : NULL;
19955bc3cb74SMauro Carvalho Chehab 
19965bc3cb74SMauro Carvalho Chehab 	if (vfh && vfh->ctrl_handler)
19975bc3cb74SMauro Carvalho Chehab 		return v4l2_queryctrl(vfh->ctrl_handler, p);
19985bc3cb74SMauro Carvalho Chehab 	if (vfd->ctrl_handler)
19995bc3cb74SMauro Carvalho Chehab 		return v4l2_queryctrl(vfd->ctrl_handler, p);
20005bc3cb74SMauro Carvalho Chehab 	if (ops->vidioc_queryctrl)
20015bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_queryctrl(file, fh, p);
20025bc3cb74SMauro Carvalho Chehab 	return -ENOTTY;
20035bc3cb74SMauro Carvalho Chehab }
20045bc3cb74SMauro Carvalho Chehab 
2005e6bee368SHans Verkuil static int v4l_query_ext_ctrl(const struct v4l2_ioctl_ops *ops,
2006e6bee368SHans Verkuil 				struct file *file, void *fh, void *arg)
2007e6bee368SHans Verkuil {
2008e6bee368SHans Verkuil 	struct video_device *vfd = video_devdata(file);
2009e6bee368SHans Verkuil 	struct v4l2_query_ext_ctrl *p = arg;
2010e6bee368SHans Verkuil 	struct v4l2_fh *vfh =
2011e6bee368SHans Verkuil 		test_bit(V4L2_FL_USES_V4L2_FH, &vfd->flags) ? fh : NULL;
2012e6bee368SHans Verkuil 
2013e6bee368SHans Verkuil 	if (vfh && vfh->ctrl_handler)
2014e6bee368SHans Verkuil 		return v4l2_query_ext_ctrl(vfh->ctrl_handler, p);
2015e6bee368SHans Verkuil 	if (vfd->ctrl_handler)
2016e6bee368SHans Verkuil 		return v4l2_query_ext_ctrl(vfd->ctrl_handler, p);
2017e6bee368SHans Verkuil 	if (ops->vidioc_query_ext_ctrl)
2018e6bee368SHans Verkuil 		return ops->vidioc_query_ext_ctrl(file, fh, p);
2019e6bee368SHans Verkuil 	return -ENOTTY;
2020e6bee368SHans Verkuil }
2021e6bee368SHans Verkuil 
20225bc3cb74SMauro Carvalho Chehab static int v4l_querymenu(const struct v4l2_ioctl_ops *ops,
20235bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
20245bc3cb74SMauro Carvalho Chehab {
20255bc3cb74SMauro Carvalho Chehab 	struct video_device *vfd = video_devdata(file);
20265bc3cb74SMauro Carvalho Chehab 	struct v4l2_querymenu *p = arg;
20275bc3cb74SMauro Carvalho Chehab 	struct v4l2_fh *vfh =
20285bc3cb74SMauro Carvalho Chehab 		test_bit(V4L2_FL_USES_V4L2_FH, &vfd->flags) ? fh : NULL;
20295bc3cb74SMauro Carvalho Chehab 
20305bc3cb74SMauro Carvalho Chehab 	if (vfh && vfh->ctrl_handler)
20315bc3cb74SMauro Carvalho Chehab 		return v4l2_querymenu(vfh->ctrl_handler, p);
20325bc3cb74SMauro Carvalho Chehab 	if (vfd->ctrl_handler)
20335bc3cb74SMauro Carvalho Chehab 		return v4l2_querymenu(vfd->ctrl_handler, p);
20345bc3cb74SMauro Carvalho Chehab 	if (ops->vidioc_querymenu)
20355bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_querymenu(file, fh, p);
20365bc3cb74SMauro Carvalho Chehab 	return -ENOTTY;
20375bc3cb74SMauro Carvalho Chehab }
20385bc3cb74SMauro Carvalho Chehab 
20395bc3cb74SMauro Carvalho Chehab static int v4l_g_ctrl(const struct v4l2_ioctl_ops *ops,
20405bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
20415bc3cb74SMauro Carvalho Chehab {
20425bc3cb74SMauro Carvalho Chehab 	struct video_device *vfd = video_devdata(file);
20435bc3cb74SMauro Carvalho Chehab 	struct v4l2_control *p = arg;
20445bc3cb74SMauro Carvalho Chehab 	struct v4l2_fh *vfh =
20455bc3cb74SMauro Carvalho Chehab 		test_bit(V4L2_FL_USES_V4L2_FH, &vfd->flags) ? fh : NULL;
20465bc3cb74SMauro Carvalho Chehab 	struct v4l2_ext_controls ctrls;
20475bc3cb74SMauro Carvalho Chehab 	struct v4l2_ext_control ctrl;
20485bc3cb74SMauro Carvalho Chehab 
20495bc3cb74SMauro Carvalho Chehab 	if (vfh && vfh->ctrl_handler)
20505bc3cb74SMauro Carvalho Chehab 		return v4l2_g_ctrl(vfh->ctrl_handler, p);
20515bc3cb74SMauro Carvalho Chehab 	if (vfd->ctrl_handler)
20525bc3cb74SMauro Carvalho Chehab 		return v4l2_g_ctrl(vfd->ctrl_handler, p);
20535bc3cb74SMauro Carvalho Chehab 	if (ops->vidioc_g_ctrl)
20545bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_g_ctrl(file, fh, p);
20555bc3cb74SMauro Carvalho Chehab 	if (ops->vidioc_g_ext_ctrls == NULL)
20565bc3cb74SMauro Carvalho Chehab 		return -ENOTTY;
20575bc3cb74SMauro Carvalho Chehab 
20580f8017beSRicardo Ribalda 	ctrls.which = V4L2_CTRL_ID2WHICH(p->id);
20595bc3cb74SMauro Carvalho Chehab 	ctrls.count = 1;
20605bc3cb74SMauro Carvalho Chehab 	ctrls.controls = &ctrl;
20615bc3cb74SMauro Carvalho Chehab 	ctrl.id = p->id;
20625bc3cb74SMauro Carvalho Chehab 	ctrl.value = p->value;
20635bc3cb74SMauro Carvalho Chehab 	if (check_ext_ctrls(&ctrls, 1)) {
20645bc3cb74SMauro Carvalho Chehab 		int ret = ops->vidioc_g_ext_ctrls(file, fh, &ctrls);
20655bc3cb74SMauro Carvalho Chehab 
20665bc3cb74SMauro Carvalho Chehab 		if (ret == 0)
20675bc3cb74SMauro Carvalho Chehab 			p->value = ctrl.value;
20685bc3cb74SMauro Carvalho Chehab 		return ret;
20695bc3cb74SMauro Carvalho Chehab 	}
20705bc3cb74SMauro Carvalho Chehab 	return -EINVAL;
20715bc3cb74SMauro Carvalho Chehab }
20725bc3cb74SMauro Carvalho Chehab 
20735bc3cb74SMauro Carvalho Chehab static int v4l_s_ctrl(const struct v4l2_ioctl_ops *ops,
20745bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
20755bc3cb74SMauro Carvalho Chehab {
20765bc3cb74SMauro Carvalho Chehab 	struct video_device *vfd = video_devdata(file);
20775bc3cb74SMauro Carvalho Chehab 	struct v4l2_control *p = arg;
20785bc3cb74SMauro Carvalho Chehab 	struct v4l2_fh *vfh =
20795bc3cb74SMauro Carvalho Chehab 		test_bit(V4L2_FL_USES_V4L2_FH, &vfd->flags) ? fh : NULL;
20805bc3cb74SMauro Carvalho Chehab 	struct v4l2_ext_controls ctrls;
20815bc3cb74SMauro Carvalho Chehab 	struct v4l2_ext_control ctrl;
20825bc3cb74SMauro Carvalho Chehab 
20835bc3cb74SMauro Carvalho Chehab 	if (vfh && vfh->ctrl_handler)
20845bc3cb74SMauro Carvalho Chehab 		return v4l2_s_ctrl(vfh, vfh->ctrl_handler, p);
20855bc3cb74SMauro Carvalho Chehab 	if (vfd->ctrl_handler)
20865bc3cb74SMauro Carvalho Chehab 		return v4l2_s_ctrl(NULL, vfd->ctrl_handler, p);
20875bc3cb74SMauro Carvalho Chehab 	if (ops->vidioc_s_ctrl)
20885bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_s_ctrl(file, fh, p);
20895bc3cb74SMauro Carvalho Chehab 	if (ops->vidioc_s_ext_ctrls == NULL)
20905bc3cb74SMauro Carvalho Chehab 		return -ENOTTY;
20915bc3cb74SMauro Carvalho Chehab 
20920f8017beSRicardo Ribalda 	ctrls.which = V4L2_CTRL_ID2WHICH(p->id);
20935bc3cb74SMauro Carvalho Chehab 	ctrls.count = 1;
20945bc3cb74SMauro Carvalho Chehab 	ctrls.controls = &ctrl;
20955bc3cb74SMauro Carvalho Chehab 	ctrl.id = p->id;
20965bc3cb74SMauro Carvalho Chehab 	ctrl.value = p->value;
20975bc3cb74SMauro Carvalho Chehab 	if (check_ext_ctrls(&ctrls, 1))
20985bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_s_ext_ctrls(file, fh, &ctrls);
20995bc3cb74SMauro Carvalho Chehab 	return -EINVAL;
21005bc3cb74SMauro Carvalho Chehab }
21015bc3cb74SMauro Carvalho Chehab 
21025bc3cb74SMauro Carvalho Chehab static int v4l_g_ext_ctrls(const struct v4l2_ioctl_ops *ops,
21035bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
21045bc3cb74SMauro Carvalho Chehab {
21055bc3cb74SMauro Carvalho Chehab 	struct video_device *vfd = video_devdata(file);
21065bc3cb74SMauro Carvalho Chehab 	struct v4l2_ext_controls *p = arg;
21075bc3cb74SMauro Carvalho Chehab 	struct v4l2_fh *vfh =
21085bc3cb74SMauro Carvalho Chehab 		test_bit(V4L2_FL_USES_V4L2_FH, &vfd->flags) ? fh : NULL;
21095bc3cb74SMauro Carvalho Chehab 
21105bc3cb74SMauro Carvalho Chehab 	p->error_idx = p->count;
21115bc3cb74SMauro Carvalho Chehab 	if (vfh && vfh->ctrl_handler)
21125bc3cb74SMauro Carvalho Chehab 		return v4l2_g_ext_ctrls(vfh->ctrl_handler, p);
21135bc3cb74SMauro Carvalho Chehab 	if (vfd->ctrl_handler)
21145bc3cb74SMauro Carvalho Chehab 		return v4l2_g_ext_ctrls(vfd->ctrl_handler, p);
21155bc3cb74SMauro Carvalho Chehab 	if (ops->vidioc_g_ext_ctrls == NULL)
21165bc3cb74SMauro Carvalho Chehab 		return -ENOTTY;
21175bc3cb74SMauro Carvalho Chehab 	return check_ext_ctrls(p, 0) ? ops->vidioc_g_ext_ctrls(file, fh, p) :
21185bc3cb74SMauro Carvalho Chehab 					-EINVAL;
21195bc3cb74SMauro Carvalho Chehab }
21205bc3cb74SMauro Carvalho Chehab 
21215bc3cb74SMauro Carvalho Chehab static int v4l_s_ext_ctrls(const struct v4l2_ioctl_ops *ops,
21225bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
21235bc3cb74SMauro Carvalho Chehab {
21245bc3cb74SMauro Carvalho Chehab 	struct video_device *vfd = video_devdata(file);
21255bc3cb74SMauro Carvalho Chehab 	struct v4l2_ext_controls *p = arg;
21265bc3cb74SMauro Carvalho Chehab 	struct v4l2_fh *vfh =
21275bc3cb74SMauro Carvalho Chehab 		test_bit(V4L2_FL_USES_V4L2_FH, &vfd->flags) ? fh : NULL;
21285bc3cb74SMauro Carvalho Chehab 
21295bc3cb74SMauro Carvalho Chehab 	p->error_idx = p->count;
21305bc3cb74SMauro Carvalho Chehab 	if (vfh && vfh->ctrl_handler)
21315bc3cb74SMauro Carvalho Chehab 		return v4l2_s_ext_ctrls(vfh, vfh->ctrl_handler, p);
21325bc3cb74SMauro Carvalho Chehab 	if (vfd->ctrl_handler)
21335bc3cb74SMauro Carvalho Chehab 		return v4l2_s_ext_ctrls(NULL, vfd->ctrl_handler, p);
21345bc3cb74SMauro Carvalho Chehab 	if (ops->vidioc_s_ext_ctrls == NULL)
21355bc3cb74SMauro Carvalho Chehab 		return -ENOTTY;
21365bc3cb74SMauro Carvalho Chehab 	return check_ext_ctrls(p, 0) ? ops->vidioc_s_ext_ctrls(file, fh, p) :
21375bc3cb74SMauro Carvalho Chehab 					-EINVAL;
21385bc3cb74SMauro Carvalho Chehab }
21395bc3cb74SMauro Carvalho Chehab 
21405bc3cb74SMauro Carvalho Chehab static int v4l_try_ext_ctrls(const struct v4l2_ioctl_ops *ops,
21415bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
21425bc3cb74SMauro Carvalho Chehab {
21435bc3cb74SMauro Carvalho Chehab 	struct video_device *vfd = video_devdata(file);
21445bc3cb74SMauro Carvalho Chehab 	struct v4l2_ext_controls *p = arg;
21455bc3cb74SMauro Carvalho Chehab 	struct v4l2_fh *vfh =
21465bc3cb74SMauro Carvalho Chehab 		test_bit(V4L2_FL_USES_V4L2_FH, &vfd->flags) ? fh : NULL;
21475bc3cb74SMauro Carvalho Chehab 
21485bc3cb74SMauro Carvalho Chehab 	p->error_idx = p->count;
21495bc3cb74SMauro Carvalho Chehab 	if (vfh && vfh->ctrl_handler)
21505bc3cb74SMauro Carvalho Chehab 		return v4l2_try_ext_ctrls(vfh->ctrl_handler, p);
21515bc3cb74SMauro Carvalho Chehab 	if (vfd->ctrl_handler)
21525bc3cb74SMauro Carvalho Chehab 		return v4l2_try_ext_ctrls(vfd->ctrl_handler, p);
21535bc3cb74SMauro Carvalho Chehab 	if (ops->vidioc_try_ext_ctrls == NULL)
21545bc3cb74SMauro Carvalho Chehab 		return -ENOTTY;
21555bc3cb74SMauro Carvalho Chehab 	return check_ext_ctrls(p, 0) ? ops->vidioc_try_ext_ctrls(file, fh, p) :
21565bc3cb74SMauro Carvalho Chehab 					-EINVAL;
21575bc3cb74SMauro Carvalho Chehab }
21585bc3cb74SMauro Carvalho Chehab 
2159eaec420fSHans Verkuil /*
2160eaec420fSHans Verkuil  * The selection API specified originally that the _MPLANE buffer types
2161eaec420fSHans Verkuil  * shouldn't be used. The reasons for this are lost in the mists of time
2162eaec420fSHans Verkuil  * (or just really crappy memories). Regardless, this is really annoying
2163eaec420fSHans Verkuil  * for userspace. So to keep things simple we map _MPLANE buffer types
2164eaec420fSHans Verkuil  * to their 'regular' counterparts before calling the driver. And we
2165eaec420fSHans Verkuil  * restore it afterwards. This way applications can use either buffer
2166eaec420fSHans Verkuil  * type and drivers don't need to check for both.
2167eaec420fSHans Verkuil  */
2168eaec420fSHans Verkuil static int v4l_g_selection(const struct v4l2_ioctl_ops *ops,
2169eaec420fSHans Verkuil 			   struct file *file, void *fh, void *arg)
2170eaec420fSHans Verkuil {
2171eaec420fSHans Verkuil 	struct v4l2_selection *p = arg;
2172eaec420fSHans Verkuil 	u32 old_type = p->type;
2173eaec420fSHans Verkuil 	int ret;
2174eaec420fSHans Verkuil 
2175eaec420fSHans Verkuil 	if (p->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
2176eaec420fSHans Verkuil 		p->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
2177eaec420fSHans Verkuil 	else if (p->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)
2178eaec420fSHans Verkuil 		p->type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
2179eaec420fSHans Verkuil 	ret = ops->vidioc_g_selection(file, fh, p);
2180eaec420fSHans Verkuil 	p->type = old_type;
2181eaec420fSHans Verkuil 	return ret;
2182eaec420fSHans Verkuil }
2183eaec420fSHans Verkuil 
2184eaec420fSHans Verkuil static int v4l_s_selection(const struct v4l2_ioctl_ops *ops,
2185eaec420fSHans Verkuil 			   struct file *file, void *fh, void *arg)
2186eaec420fSHans Verkuil {
2187eaec420fSHans Verkuil 	struct v4l2_selection *p = arg;
2188eaec420fSHans Verkuil 	u32 old_type = p->type;
2189eaec420fSHans Verkuil 	int ret;
2190eaec420fSHans Verkuil 
2191eaec420fSHans Verkuil 	if (p->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
2192eaec420fSHans Verkuil 		p->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
2193eaec420fSHans Verkuil 	else if (p->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)
2194eaec420fSHans Verkuil 		p->type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
2195eaec420fSHans Verkuil 	ret = ops->vidioc_s_selection(file, fh, p);
2196eaec420fSHans Verkuil 	p->type = old_type;
2197eaec420fSHans Verkuil 	return ret;
2198eaec420fSHans Verkuil }
2199eaec420fSHans Verkuil 
22005bc3cb74SMauro Carvalho Chehab static int v4l_g_crop(const struct v4l2_ioctl_ops *ops,
22015bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
22025bc3cb74SMauro Carvalho Chehab {
22035bc3cb74SMauro Carvalho Chehab 	struct v4l2_crop *p = arg;
22045bc3cb74SMauro Carvalho Chehab 	struct v4l2_selection s = {
22055bc3cb74SMauro Carvalho Chehab 		.type = p->type,
22065bc3cb74SMauro Carvalho Chehab 	};
22075bc3cb74SMauro Carvalho Chehab 	int ret;
22085bc3cb74SMauro Carvalho Chehab 
22095bc3cb74SMauro Carvalho Chehab 	if (ops->vidioc_g_crop)
22105bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_g_crop(file, fh, p);
22115bc3cb74SMauro Carvalho Chehab 	/* simulate capture crop using selection api */
22125bc3cb74SMauro Carvalho Chehab 
22135bc3cb74SMauro Carvalho Chehab 	/* crop means compose for output devices */
22145bc3cb74SMauro Carvalho Chehab 	if (V4L2_TYPE_IS_OUTPUT(p->type))
22155bc3cb74SMauro Carvalho Chehab 		s.target = V4L2_SEL_TGT_COMPOSE_ACTIVE;
22165bc3cb74SMauro Carvalho Chehab 	else
22175bc3cb74SMauro Carvalho Chehab 		s.target = V4L2_SEL_TGT_CROP_ACTIVE;
22185bc3cb74SMauro Carvalho Chehab 
2219eaec420fSHans Verkuil 	ret = v4l_g_selection(ops, file, fh, &s);
22205bc3cb74SMauro Carvalho Chehab 
22215bc3cb74SMauro Carvalho Chehab 	/* copying results to old structure on success */
22225bc3cb74SMauro Carvalho Chehab 	if (!ret)
22235bc3cb74SMauro Carvalho Chehab 		p->c = s.r;
22245bc3cb74SMauro Carvalho Chehab 	return ret;
22255bc3cb74SMauro Carvalho Chehab }
22265bc3cb74SMauro Carvalho Chehab 
22275bc3cb74SMauro Carvalho Chehab static int v4l_s_crop(const struct v4l2_ioctl_ops *ops,
22285bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
22295bc3cb74SMauro Carvalho Chehab {
22305bc3cb74SMauro Carvalho Chehab 	struct v4l2_crop *p = arg;
22315bc3cb74SMauro Carvalho Chehab 	struct v4l2_selection s = {
22325bc3cb74SMauro Carvalho Chehab 		.type = p->type,
22335bc3cb74SMauro Carvalho Chehab 		.r = p->c,
22345bc3cb74SMauro Carvalho Chehab 	};
22355bc3cb74SMauro Carvalho Chehab 
22365bc3cb74SMauro Carvalho Chehab 	if (ops->vidioc_s_crop)
22375bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_s_crop(file, fh, p);
22385bc3cb74SMauro Carvalho Chehab 	/* simulate capture crop using selection api */
22395bc3cb74SMauro Carvalho Chehab 
22405bc3cb74SMauro Carvalho Chehab 	/* crop means compose for output devices */
22415bc3cb74SMauro Carvalho Chehab 	if (V4L2_TYPE_IS_OUTPUT(p->type))
22425bc3cb74SMauro Carvalho Chehab 		s.target = V4L2_SEL_TGT_COMPOSE_ACTIVE;
22435bc3cb74SMauro Carvalho Chehab 	else
22445bc3cb74SMauro Carvalho Chehab 		s.target = V4L2_SEL_TGT_CROP_ACTIVE;
22455bc3cb74SMauro Carvalho Chehab 
2246eaec420fSHans Verkuil 	return v4l_s_selection(ops, file, fh, &s);
22475bc3cb74SMauro Carvalho Chehab }
22485bc3cb74SMauro Carvalho Chehab 
22495bc3cb74SMauro Carvalho Chehab static int v4l_cropcap(const struct v4l2_ioctl_ops *ops,
22505bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
22515bc3cb74SMauro Carvalho Chehab {
22525bc3cb74SMauro Carvalho Chehab 	struct v4l2_cropcap *p = arg;
22535bc3cb74SMauro Carvalho Chehab 	struct v4l2_selection s = { .type = p->type };
225495dd7b7eSHans Verkuil 	int ret = 0;
225595dd7b7eSHans Verkuil 
225695dd7b7eSHans Verkuil 	/* setting trivial pixelaspect */
225795dd7b7eSHans Verkuil 	p->pixelaspect.numerator = 1;
225895dd7b7eSHans Verkuil 	p->pixelaspect.denominator = 1;
225995dd7b7eSHans Verkuil 
226095dd7b7eSHans Verkuil 	/*
226195dd7b7eSHans Verkuil 	 * The determine_valid_ioctls() call already should ensure
226295dd7b7eSHans Verkuil 	 * that this can never happen, but just in case...
226395dd7b7eSHans Verkuil 	 */
22641ca830b1SHans Verkuil 	if (WARN_ON(!ops->vidioc_cropcap && !ops->vidioc_g_selection))
226595dd7b7eSHans Verkuil 		return -ENOTTY;
226695dd7b7eSHans Verkuil 
226795dd7b7eSHans Verkuil 	if (ops->vidioc_cropcap)
226895dd7b7eSHans Verkuil 		ret = ops->vidioc_cropcap(file, fh, p);
226995dd7b7eSHans Verkuil 
227095dd7b7eSHans Verkuil 	if (!ops->vidioc_g_selection)
227195dd7b7eSHans Verkuil 		return ret;
227295dd7b7eSHans Verkuil 
227395dd7b7eSHans Verkuil 	/*
227495dd7b7eSHans Verkuil 	 * Ignore ENOTTY or ENOIOCTLCMD error returns, just use the
227595dd7b7eSHans Verkuil 	 * square pixel aspect ratio in that case.
227695dd7b7eSHans Verkuil 	 */
227795dd7b7eSHans Verkuil 	if (ret && ret != -ENOTTY && ret != -ENOIOCTLCMD)
227895dd7b7eSHans Verkuil 		return ret;
227995dd7b7eSHans Verkuil 
228095dd7b7eSHans Verkuil 	/* Use g_selection() to fill in the bounds and defrect rectangles */
22815bc3cb74SMauro Carvalho Chehab 
22825bc3cb74SMauro Carvalho Chehab 	/* obtaining bounds */
22835bc3cb74SMauro Carvalho Chehab 	if (V4L2_TYPE_IS_OUTPUT(p->type))
22845bc3cb74SMauro Carvalho Chehab 		s.target = V4L2_SEL_TGT_COMPOSE_BOUNDS;
22855bc3cb74SMauro Carvalho Chehab 	else
22865bc3cb74SMauro Carvalho Chehab 		s.target = V4L2_SEL_TGT_CROP_BOUNDS;
22875bc3cb74SMauro Carvalho Chehab 
2288eaec420fSHans Verkuil 	ret = v4l_g_selection(ops, file, fh, &s);
22895bc3cb74SMauro Carvalho Chehab 	if (ret)
22905bc3cb74SMauro Carvalho Chehab 		return ret;
22915bc3cb74SMauro Carvalho Chehab 	p->bounds = s.r;
22925bc3cb74SMauro Carvalho Chehab 
22935bc3cb74SMauro Carvalho Chehab 	/* obtaining defrect */
22945bc3cb74SMauro Carvalho Chehab 	if (V4L2_TYPE_IS_OUTPUT(p->type))
22955bc3cb74SMauro Carvalho Chehab 		s.target = V4L2_SEL_TGT_COMPOSE_DEFAULT;
22965bc3cb74SMauro Carvalho Chehab 	else
22975bc3cb74SMauro Carvalho Chehab 		s.target = V4L2_SEL_TGT_CROP_DEFAULT;
22985bc3cb74SMauro Carvalho Chehab 
2299eaec420fSHans Verkuil 	ret = v4l_g_selection(ops, file, fh, &s);
23005bc3cb74SMauro Carvalho Chehab 	if (ret)
23015bc3cb74SMauro Carvalho Chehab 		return ret;
23025bc3cb74SMauro Carvalho Chehab 	p->defrect = s.r;
23039409945cSHans Verkuil 
23045bc3cb74SMauro Carvalho Chehab 	return 0;
23055bc3cb74SMauro Carvalho Chehab }
23065bc3cb74SMauro Carvalho Chehab 
23075bc3cb74SMauro Carvalho Chehab static int v4l_log_status(const struct v4l2_ioctl_ops *ops,
23085bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
23095bc3cb74SMauro Carvalho Chehab {
23105bc3cb74SMauro Carvalho Chehab 	struct video_device *vfd = video_devdata(file);
23115bc3cb74SMauro Carvalho Chehab 	int ret;
23125bc3cb74SMauro Carvalho Chehab 
23135bc3cb74SMauro Carvalho Chehab 	if (vfd->v4l2_dev)
23145bc3cb74SMauro Carvalho Chehab 		pr_info("%s: =================  START STATUS  =================\n",
23155bc3cb74SMauro Carvalho Chehab 			vfd->v4l2_dev->name);
23165bc3cb74SMauro Carvalho Chehab 	ret = ops->vidioc_log_status(file, fh);
23175bc3cb74SMauro Carvalho Chehab 	if (vfd->v4l2_dev)
23185bc3cb74SMauro Carvalho Chehab 		pr_info("%s: ==================  END STATUS  ==================\n",
23195bc3cb74SMauro Carvalho Chehab 			vfd->v4l2_dev->name);
23205bc3cb74SMauro Carvalho Chehab 	return ret;
23215bc3cb74SMauro Carvalho Chehab }
23225bc3cb74SMauro Carvalho Chehab 
23235bc3cb74SMauro Carvalho Chehab static int v4l_dbg_g_register(const struct v4l2_ioctl_ops *ops,
23245bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
23255bc3cb74SMauro Carvalho Chehab {
23265bc3cb74SMauro Carvalho Chehab #ifdef CONFIG_VIDEO_ADV_DEBUG
23275bc3cb74SMauro Carvalho Chehab 	struct v4l2_dbg_register *p = arg;
232879b0c640SHans Verkuil 	struct video_device *vfd = video_devdata(file);
232979b0c640SHans Verkuil 	struct v4l2_subdev *sd;
233079b0c640SHans Verkuil 	int idx = 0;
23315bc3cb74SMauro Carvalho Chehab 
23325bc3cb74SMauro Carvalho Chehab 	if (!capable(CAP_SYS_ADMIN))
23335bc3cb74SMauro Carvalho Chehab 		return -EPERM;
23343eef2510SHans Verkuil 	if (p->match.type == V4L2_CHIP_MATCH_SUBDEV) {
233579b0c640SHans Verkuil 		if (vfd->v4l2_dev == NULL)
233679b0c640SHans Verkuil 			return -EINVAL;
23373eef2510SHans Verkuil 		v4l2_device_for_each_subdev(sd, vfd->v4l2_dev)
23383eef2510SHans Verkuil 			if (p->match.addr == idx++)
233979b0c640SHans Verkuil 				return v4l2_subdev_call(sd, core, g_register, p);
234079b0c640SHans Verkuil 		return -EINVAL;
234179b0c640SHans Verkuil 	}
2342191b79b0SHans Verkuil 	if (ops->vidioc_g_register && p->match.type == V4L2_CHIP_MATCH_BRIDGE &&
2343191b79b0SHans Verkuil 	    (ops->vidioc_g_chip_info || p->match.addr == 0))
23445bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_g_register(file, fh, p);
234579b0c640SHans Verkuil 	return -EINVAL;
23465bc3cb74SMauro Carvalho Chehab #else
23475bc3cb74SMauro Carvalho Chehab 	return -ENOTTY;
23485bc3cb74SMauro Carvalho Chehab #endif
23495bc3cb74SMauro Carvalho Chehab }
23505bc3cb74SMauro Carvalho Chehab 
23515bc3cb74SMauro Carvalho Chehab static int v4l_dbg_s_register(const struct v4l2_ioctl_ops *ops,
23525bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
23535bc3cb74SMauro Carvalho Chehab {
23545bc3cb74SMauro Carvalho Chehab #ifdef CONFIG_VIDEO_ADV_DEBUG
2355977ba3b1SHans Verkuil 	const struct v4l2_dbg_register *p = arg;
235679b0c640SHans Verkuil 	struct video_device *vfd = video_devdata(file);
235779b0c640SHans Verkuil 	struct v4l2_subdev *sd;
235879b0c640SHans Verkuil 	int idx = 0;
23595bc3cb74SMauro Carvalho Chehab 
23605bc3cb74SMauro Carvalho Chehab 	if (!capable(CAP_SYS_ADMIN))
23615bc3cb74SMauro Carvalho Chehab 		return -EPERM;
23623eef2510SHans Verkuil 	if (p->match.type == V4L2_CHIP_MATCH_SUBDEV) {
236379b0c640SHans Verkuil 		if (vfd->v4l2_dev == NULL)
236479b0c640SHans Verkuil 			return -EINVAL;
23653eef2510SHans Verkuil 		v4l2_device_for_each_subdev(sd, vfd->v4l2_dev)
23663eef2510SHans Verkuil 			if (p->match.addr == idx++)
236779b0c640SHans Verkuil 				return v4l2_subdev_call(sd, core, s_register, p);
236879b0c640SHans Verkuil 		return -EINVAL;
236979b0c640SHans Verkuil 	}
2370191b79b0SHans Verkuil 	if (ops->vidioc_s_register && p->match.type == V4L2_CHIP_MATCH_BRIDGE &&
2371191b79b0SHans Verkuil 	    (ops->vidioc_g_chip_info || p->match.addr == 0))
23725bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_s_register(file, fh, p);
237379b0c640SHans Verkuil 	return -EINVAL;
23745bc3cb74SMauro Carvalho Chehab #else
23755bc3cb74SMauro Carvalho Chehab 	return -ENOTTY;
23765bc3cb74SMauro Carvalho Chehab #endif
23775bc3cb74SMauro Carvalho Chehab }
23785bc3cb74SMauro Carvalho Chehab 
237996b03d2aSHans Verkuil static int v4l_dbg_g_chip_info(const struct v4l2_ioctl_ops *ops,
238079b0c640SHans Verkuil 				struct file *file, void *fh, void *arg)
238179b0c640SHans Verkuil {
2382cd634f1bSHans Verkuil #ifdef CONFIG_VIDEO_ADV_DEBUG
238379b0c640SHans Verkuil 	struct video_device *vfd = video_devdata(file);
238496b03d2aSHans Verkuil 	struct v4l2_dbg_chip_info *p = arg;
238579b0c640SHans Verkuil 	struct v4l2_subdev *sd;
238679b0c640SHans Verkuil 	int idx = 0;
238779b0c640SHans Verkuil 
238879b0c640SHans Verkuil 	switch (p->match.type) {
238979b0c640SHans Verkuil 	case V4L2_CHIP_MATCH_BRIDGE:
239079b0c640SHans Verkuil 		if (ops->vidioc_s_register)
239179b0c640SHans Verkuil 			p->flags |= V4L2_CHIP_FL_WRITABLE;
239279b0c640SHans Verkuil 		if (ops->vidioc_g_register)
239379b0c640SHans Verkuil 			p->flags |= V4L2_CHIP_FL_READABLE;
239479b0c640SHans Verkuil 		strlcpy(p->name, vfd->v4l2_dev->name, sizeof(p->name));
239596b03d2aSHans Verkuil 		if (ops->vidioc_g_chip_info)
239696b03d2aSHans Verkuil 			return ops->vidioc_g_chip_info(file, fh, arg);
23970f0fe4b9SHans Verkuil 		if (p->match.addr)
23980f0fe4b9SHans Verkuil 			return -EINVAL;
239979b0c640SHans Verkuil 		return 0;
240079b0c640SHans Verkuil 
24013eef2510SHans Verkuil 	case V4L2_CHIP_MATCH_SUBDEV:
240279b0c640SHans Verkuil 		if (vfd->v4l2_dev == NULL)
240379b0c640SHans Verkuil 			break;
240479b0c640SHans Verkuil 		v4l2_device_for_each_subdev(sd, vfd->v4l2_dev) {
24053eef2510SHans Verkuil 			if (p->match.addr != idx++)
24063eef2510SHans Verkuil 				continue;
240779b0c640SHans Verkuil 			if (sd->ops->core && sd->ops->core->s_register)
240879b0c640SHans Verkuil 				p->flags |= V4L2_CHIP_FL_WRITABLE;
240979b0c640SHans Verkuil 			if (sd->ops->core && sd->ops->core->g_register)
241079b0c640SHans Verkuil 				p->flags |= V4L2_CHIP_FL_READABLE;
241179b0c640SHans Verkuil 			strlcpy(p->name, sd->name, sizeof(p->name));
241279b0c640SHans Verkuil 			return 0;
241379b0c640SHans Verkuil 		}
241479b0c640SHans Verkuil 		break;
241579b0c640SHans Verkuil 	}
241679b0c640SHans Verkuil 	return -EINVAL;
2417cd634f1bSHans Verkuil #else
2418cd634f1bSHans Verkuil 	return -ENOTTY;
2419cd634f1bSHans Verkuil #endif
242079b0c640SHans Verkuil }
242179b0c640SHans Verkuil 
24225bc3cb74SMauro Carvalho Chehab static int v4l_dqevent(const struct v4l2_ioctl_ops *ops,
24235bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
24245bc3cb74SMauro Carvalho Chehab {
24255bc3cb74SMauro Carvalho Chehab 	return v4l2_event_dequeue(fh, arg, file->f_flags & O_NONBLOCK);
24265bc3cb74SMauro Carvalho Chehab }
24275bc3cb74SMauro Carvalho Chehab 
24285bc3cb74SMauro Carvalho Chehab static int v4l_subscribe_event(const struct v4l2_ioctl_ops *ops,
24295bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
24305bc3cb74SMauro Carvalho Chehab {
24315bc3cb74SMauro Carvalho Chehab 	return ops->vidioc_subscribe_event(fh, arg);
24325bc3cb74SMauro Carvalho Chehab }
24335bc3cb74SMauro Carvalho Chehab 
24345bc3cb74SMauro Carvalho Chehab static int v4l_unsubscribe_event(const struct v4l2_ioctl_ops *ops,
24355bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
24365bc3cb74SMauro Carvalho Chehab {
24375bc3cb74SMauro Carvalho Chehab 	return ops->vidioc_unsubscribe_event(fh, arg);
24385bc3cb74SMauro Carvalho Chehab }
24395bc3cb74SMauro Carvalho Chehab 
24405bc3cb74SMauro Carvalho Chehab static int v4l_g_sliced_vbi_cap(const struct v4l2_ioctl_ops *ops,
24415bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
24425bc3cb74SMauro Carvalho Chehab {
24435bc3cb74SMauro Carvalho Chehab 	struct v4l2_sliced_vbi_cap *p = arg;
24444b20259fSHans Verkuil 	int ret = check_fmt(file, p->type);
24454b20259fSHans Verkuil 
24464b20259fSHans Verkuil 	if (ret)
24474b20259fSHans Verkuil 		return ret;
24485bc3cb74SMauro Carvalho Chehab 
24495bc3cb74SMauro Carvalho Chehab 	/* Clear up to type, everything after type is zeroed already */
24505bc3cb74SMauro Carvalho Chehab 	memset(p, 0, offsetof(struct v4l2_sliced_vbi_cap, type));
24515bc3cb74SMauro Carvalho Chehab 
24525bc3cb74SMauro Carvalho Chehab 	return ops->vidioc_g_sliced_vbi_cap(file, fh, p);
24535bc3cb74SMauro Carvalho Chehab }
24545bc3cb74SMauro Carvalho Chehab 
24555bc3cb74SMauro Carvalho Chehab static int v4l_enum_freq_bands(const struct v4l2_ioctl_ops *ops,
24565bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
24575bc3cb74SMauro Carvalho Chehab {
24585bc3cb74SMauro Carvalho Chehab 	struct video_device *vfd = video_devdata(file);
24595bc3cb74SMauro Carvalho Chehab 	struct v4l2_frequency_band *p = arg;
24605bc3cb74SMauro Carvalho Chehab 	enum v4l2_tuner_type type;
24615bc3cb74SMauro Carvalho Chehab 	int err;
24625bc3cb74SMauro Carvalho Chehab 
246384099a28SAntti Palosaari 	if (vfd->vfl_type == VFL_TYPE_SDR) {
2464f3c3ececSAntti Palosaari 		if (p->type != V4L2_TUNER_SDR && p->type != V4L2_TUNER_RF)
246584099a28SAntti Palosaari 			return -EINVAL;
246684099a28SAntti Palosaari 		type = p->type;
246784099a28SAntti Palosaari 	} else {
24685bc3cb74SMauro Carvalho Chehab 		type = (vfd->vfl_type == VFL_TYPE_RADIO) ?
24695bc3cb74SMauro Carvalho Chehab 				V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV;
24705bc3cb74SMauro Carvalho Chehab 		if (type != p->type)
24715bc3cb74SMauro Carvalho Chehab 			return -EINVAL;
247284099a28SAntti Palosaari 	}
2473a7f404afSHans Verkuil 	if (ops->vidioc_enum_freq_bands) {
2474a7f404afSHans Verkuil 		err = ops->vidioc_enum_freq_bands(file, fh, p);
2475a7f404afSHans Verkuil 		if (err != -ENOTTY)
2476a7f404afSHans Verkuil 			return err;
2477a7f404afSHans Verkuil 	}
247873f35418SHans Verkuil 	if (is_valid_ioctl(vfd, VIDIOC_G_TUNER)) {
24795bc3cb74SMauro Carvalho Chehab 		struct v4l2_tuner t = {
24805bc3cb74SMauro Carvalho Chehab 			.index = p->tuner,
24815bc3cb74SMauro Carvalho Chehab 			.type = type,
24825bc3cb74SMauro Carvalho Chehab 		};
24835bc3cb74SMauro Carvalho Chehab 
248479e8c7beSMauro Carvalho Chehab 		if (p->index)
248579e8c7beSMauro Carvalho Chehab 			return -EINVAL;
24865bc3cb74SMauro Carvalho Chehab 		err = ops->vidioc_g_tuner(file, fh, &t);
24875bc3cb74SMauro Carvalho Chehab 		if (err)
24885bc3cb74SMauro Carvalho Chehab 			return err;
24895bc3cb74SMauro Carvalho Chehab 		p->capability = t.capability | V4L2_TUNER_CAP_FREQ_BANDS;
24905bc3cb74SMauro Carvalho Chehab 		p->rangelow = t.rangelow;
24915bc3cb74SMauro Carvalho Chehab 		p->rangehigh = t.rangehigh;
24925bc3cb74SMauro Carvalho Chehab 		p->modulation = (type == V4L2_TUNER_RADIO) ?
24935bc3cb74SMauro Carvalho Chehab 			V4L2_BAND_MODULATION_FM : V4L2_BAND_MODULATION_VSB;
24945bc3cb74SMauro Carvalho Chehab 		return 0;
24955bc3cb74SMauro Carvalho Chehab 	}
249673f35418SHans Verkuil 	if (is_valid_ioctl(vfd, VIDIOC_G_MODULATOR)) {
24975bc3cb74SMauro Carvalho Chehab 		struct v4l2_modulator m = {
24985bc3cb74SMauro Carvalho Chehab 			.index = p->tuner,
24995bc3cb74SMauro Carvalho Chehab 		};
25005bc3cb74SMauro Carvalho Chehab 
25015bc3cb74SMauro Carvalho Chehab 		if (type != V4L2_TUNER_RADIO)
25025bc3cb74SMauro Carvalho Chehab 			return -EINVAL;
250379e8c7beSMauro Carvalho Chehab 		if (p->index)
250479e8c7beSMauro Carvalho Chehab 			return -EINVAL;
25055bc3cb74SMauro Carvalho Chehab 		err = ops->vidioc_g_modulator(file, fh, &m);
25065bc3cb74SMauro Carvalho Chehab 		if (err)
25075bc3cb74SMauro Carvalho Chehab 			return err;
25085bc3cb74SMauro Carvalho Chehab 		p->capability = m.capability | V4L2_TUNER_CAP_FREQ_BANDS;
25095bc3cb74SMauro Carvalho Chehab 		p->rangelow = m.rangelow;
25105bc3cb74SMauro Carvalho Chehab 		p->rangehigh = m.rangehigh;
25115bc3cb74SMauro Carvalho Chehab 		p->modulation = (type == V4L2_TUNER_RADIO) ?
25125bc3cb74SMauro Carvalho Chehab 			V4L2_BAND_MODULATION_FM : V4L2_BAND_MODULATION_VSB;
25135bc3cb74SMauro Carvalho Chehab 		return 0;
25145bc3cb74SMauro Carvalho Chehab 	}
25155bc3cb74SMauro Carvalho Chehab 	return -ENOTTY;
25165bc3cb74SMauro Carvalho Chehab }
25175bc3cb74SMauro Carvalho Chehab 
25185bc3cb74SMauro Carvalho Chehab struct v4l2_ioctl_info {
25195bc3cb74SMauro Carvalho Chehab 	unsigned int ioctl;
25205bc3cb74SMauro Carvalho Chehab 	u32 flags;
25215bc3cb74SMauro Carvalho Chehab 	const char * const name;
25223ad3b7a2SSami Tolvanen 	int (*func)(const struct v4l2_ioctl_ops *ops, struct file *file,
25233ad3b7a2SSami Tolvanen 		    void *fh, void *p);
25245bc3cb74SMauro Carvalho Chehab 	void (*debug)(const void *arg, bool write_only);
25255bc3cb74SMauro Carvalho Chehab };
25265bc3cb74SMauro Carvalho Chehab 
25275bc3cb74SMauro Carvalho Chehab /* This control needs a priority check */
25285bc3cb74SMauro Carvalho Chehab #define INFO_FL_PRIO		(1 << 0)
25295bc3cb74SMauro Carvalho Chehab /* This control can be valid if the filehandle passes a control handler. */
25305bc3cb74SMauro Carvalho Chehab #define INFO_FL_CTRL		(1 << 1)
25315bc3cb74SMauro Carvalho Chehab /* Queuing ioctl */
25323ad3b7a2SSami Tolvanen #define INFO_FL_QUEUE		(1 << 2)
2533043f77edSHans Verkuil /* Always copy back result, even on error */
25343ad3b7a2SSami Tolvanen #define INFO_FL_ALWAYS_COPY	(1 << 3)
25355bc3cb74SMauro Carvalho Chehab /* Zero struct from after the field to the end */
25365bc3cb74SMauro Carvalho Chehab #define INFO_FL_CLEAR(v4l2_struct, field)			\
25375bc3cb74SMauro Carvalho Chehab 	((offsetof(struct v4l2_struct, field) +			\
25385bc3cb74SMauro Carvalho Chehab 	  sizeof(((struct v4l2_struct *)0)->field)) << 16)
25395bc3cb74SMauro Carvalho Chehab #define INFO_FL_CLEAR_MASK	(_IOC_SIZEMASK << 16)
25405bc3cb74SMauro Carvalho Chehab 
25413ad3b7a2SSami Tolvanen #define DEFINE_V4L_STUB_FUNC(_vidioc)				\
25423ad3b7a2SSami Tolvanen 	static int v4l_stub_ ## _vidioc(			\
25433ad3b7a2SSami Tolvanen 			const struct v4l2_ioctl_ops *ops,	\
25443ad3b7a2SSami Tolvanen 			struct file *file, void *fh, void *p)	\
25453ad3b7a2SSami Tolvanen 	{							\
25463ad3b7a2SSami Tolvanen 		return ops->vidioc_ ## _vidioc(file, fh, p);	\
25473ad3b7a2SSami Tolvanen 	}
25483ad3b7a2SSami Tolvanen 
25493ad3b7a2SSami Tolvanen #define IOCTL_INFO(_ioctl, _func, _debug, _flags)		\
25505bc3cb74SMauro Carvalho Chehab 	[_IOC_NR(_ioctl)] = {					\
25515bc3cb74SMauro Carvalho Chehab 		.ioctl = _ioctl,				\
25523ad3b7a2SSami Tolvanen 		.flags = _flags,				\
25535bc3cb74SMauro Carvalho Chehab 		.name = #_ioctl,				\
25543ad3b7a2SSami Tolvanen 		.func = _func,					\
25555bc3cb74SMauro Carvalho Chehab 		.debug = _debug,				\
25565bc3cb74SMauro Carvalho Chehab 	}
25575bc3cb74SMauro Carvalho Chehab 
25583ad3b7a2SSami Tolvanen DEFINE_V4L_STUB_FUNC(g_fbuf)
25593ad3b7a2SSami Tolvanen DEFINE_V4L_STUB_FUNC(s_fbuf)
25603ad3b7a2SSami Tolvanen DEFINE_V4L_STUB_FUNC(expbuf)
25613ad3b7a2SSami Tolvanen DEFINE_V4L_STUB_FUNC(g_std)
25623ad3b7a2SSami Tolvanen DEFINE_V4L_STUB_FUNC(g_audio)
25633ad3b7a2SSami Tolvanen DEFINE_V4L_STUB_FUNC(s_audio)
25643ad3b7a2SSami Tolvanen DEFINE_V4L_STUB_FUNC(g_input)
25653ad3b7a2SSami Tolvanen DEFINE_V4L_STUB_FUNC(g_edid)
25663ad3b7a2SSami Tolvanen DEFINE_V4L_STUB_FUNC(s_edid)
25673ad3b7a2SSami Tolvanen DEFINE_V4L_STUB_FUNC(g_output)
25683ad3b7a2SSami Tolvanen DEFINE_V4L_STUB_FUNC(g_audout)
25693ad3b7a2SSami Tolvanen DEFINE_V4L_STUB_FUNC(s_audout)
25703ad3b7a2SSami Tolvanen DEFINE_V4L_STUB_FUNC(g_jpegcomp)
25713ad3b7a2SSami Tolvanen DEFINE_V4L_STUB_FUNC(s_jpegcomp)
25723ad3b7a2SSami Tolvanen DEFINE_V4L_STUB_FUNC(enumaudio)
25733ad3b7a2SSami Tolvanen DEFINE_V4L_STUB_FUNC(enumaudout)
25743ad3b7a2SSami Tolvanen DEFINE_V4L_STUB_FUNC(enum_framesizes)
25753ad3b7a2SSami Tolvanen DEFINE_V4L_STUB_FUNC(enum_frameintervals)
25763ad3b7a2SSami Tolvanen DEFINE_V4L_STUB_FUNC(g_enc_index)
25773ad3b7a2SSami Tolvanen DEFINE_V4L_STUB_FUNC(encoder_cmd)
25783ad3b7a2SSami Tolvanen DEFINE_V4L_STUB_FUNC(try_encoder_cmd)
25793ad3b7a2SSami Tolvanen DEFINE_V4L_STUB_FUNC(decoder_cmd)
25803ad3b7a2SSami Tolvanen DEFINE_V4L_STUB_FUNC(try_decoder_cmd)
25813ad3b7a2SSami Tolvanen DEFINE_V4L_STUB_FUNC(s_dv_timings)
25823ad3b7a2SSami Tolvanen DEFINE_V4L_STUB_FUNC(g_dv_timings)
25833ad3b7a2SSami Tolvanen DEFINE_V4L_STUB_FUNC(enum_dv_timings)
25843ad3b7a2SSami Tolvanen DEFINE_V4L_STUB_FUNC(query_dv_timings)
25853ad3b7a2SSami Tolvanen DEFINE_V4L_STUB_FUNC(dv_timings_cap)
25865bc3cb74SMauro Carvalho Chehab 
25875bc3cb74SMauro Carvalho Chehab static struct v4l2_ioctl_info v4l2_ioctls[] = {
25883ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_QUERYCAP, v4l_querycap, v4l_print_querycap, 0),
25893ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_ENUM_FMT, v4l_enum_fmt, v4l_print_fmtdesc, INFO_FL_CLEAR(v4l2_fmtdesc, type)),
25903ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_G_FMT, v4l_g_fmt, v4l_print_format, 0),
25913ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_S_FMT, v4l_s_fmt, v4l_print_format, INFO_FL_PRIO),
25923ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_REQBUFS, v4l_reqbufs, v4l_print_requestbuffers, INFO_FL_PRIO | INFO_FL_QUEUE),
25933ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_QUERYBUF, v4l_querybuf, v4l_print_buffer, INFO_FL_QUEUE | INFO_FL_CLEAR(v4l2_buffer, length)),
25943ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_G_FBUF, v4l_stub_g_fbuf, v4l_print_framebuffer, 0),
25953ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_S_FBUF, v4l_stub_s_fbuf, v4l_print_framebuffer, INFO_FL_PRIO),
25963ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_OVERLAY, v4l_overlay, v4l_print_u32, INFO_FL_PRIO),
25973ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_QBUF, v4l_qbuf, v4l_print_buffer, INFO_FL_QUEUE),
25983ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_EXPBUF, v4l_stub_expbuf, v4l_print_exportbuffer, INFO_FL_QUEUE | INFO_FL_CLEAR(v4l2_exportbuffer, flags)),
25993ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_DQBUF, v4l_dqbuf, v4l_print_buffer, INFO_FL_QUEUE),
26003ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_STREAMON, v4l_streamon, v4l_print_buftype, INFO_FL_PRIO | INFO_FL_QUEUE),
26013ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_STREAMOFF, v4l_streamoff, v4l_print_buftype, INFO_FL_PRIO | INFO_FL_QUEUE),
26023ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_G_PARM, v4l_g_parm, v4l_print_streamparm, INFO_FL_CLEAR(v4l2_streamparm, type)),
26033ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_S_PARM, v4l_s_parm, v4l_print_streamparm, INFO_FL_PRIO),
26043ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_G_STD, v4l_stub_g_std, v4l_print_std, 0),
26053ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_S_STD, v4l_s_std, v4l_print_std, INFO_FL_PRIO),
26063ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_ENUMSTD, v4l_enumstd, v4l_print_standard, INFO_FL_CLEAR(v4l2_standard, index)),
26073ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_ENUMINPUT, v4l_enuminput, v4l_print_enuminput, INFO_FL_CLEAR(v4l2_input, index)),
26083ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_G_CTRL, v4l_g_ctrl, v4l_print_control, INFO_FL_CTRL | INFO_FL_CLEAR(v4l2_control, id)),
26093ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_S_CTRL, v4l_s_ctrl, v4l_print_control, INFO_FL_PRIO | INFO_FL_CTRL),
26103ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_G_TUNER, v4l_g_tuner, v4l_print_tuner, INFO_FL_CLEAR(v4l2_tuner, index)),
26113ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_S_TUNER, v4l_s_tuner, v4l_print_tuner, INFO_FL_PRIO),
26123ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_G_AUDIO, v4l_stub_g_audio, v4l_print_audio, 0),
26133ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_S_AUDIO, v4l_stub_s_audio, v4l_print_audio, INFO_FL_PRIO),
26143ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_QUERYCTRL, v4l_queryctrl, v4l_print_queryctrl, INFO_FL_CTRL | INFO_FL_CLEAR(v4l2_queryctrl, id)),
26153ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_QUERYMENU, v4l_querymenu, v4l_print_querymenu, INFO_FL_CTRL | INFO_FL_CLEAR(v4l2_querymenu, index)),
26163ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_G_INPUT, v4l_stub_g_input, v4l_print_u32, 0),
26173ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_S_INPUT, v4l_s_input, v4l_print_u32, INFO_FL_PRIO),
26183ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_G_EDID, v4l_stub_g_edid, v4l_print_edid, INFO_FL_ALWAYS_COPY),
26193ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_S_EDID, v4l_stub_s_edid, v4l_print_edid, INFO_FL_PRIO | INFO_FL_ALWAYS_COPY),
26203ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_G_OUTPUT, v4l_stub_g_output, v4l_print_u32, 0),
26213ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_S_OUTPUT, v4l_s_output, v4l_print_u32, INFO_FL_PRIO),
26223ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_ENUMOUTPUT, v4l_enumoutput, v4l_print_enumoutput, INFO_FL_CLEAR(v4l2_output, index)),
26233ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_G_AUDOUT, v4l_stub_g_audout, v4l_print_audioout, 0),
26243ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_S_AUDOUT, v4l_stub_s_audout, v4l_print_audioout, INFO_FL_PRIO),
26253ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_G_MODULATOR, v4l_g_modulator, v4l_print_modulator, INFO_FL_CLEAR(v4l2_modulator, index)),
26263ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_S_MODULATOR, v4l_s_modulator, v4l_print_modulator, INFO_FL_PRIO),
26273ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_G_FREQUENCY, v4l_g_frequency, v4l_print_frequency, INFO_FL_CLEAR(v4l2_frequency, tuner)),
26283ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_S_FREQUENCY, v4l_s_frequency, v4l_print_frequency, INFO_FL_PRIO),
26293ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_CROPCAP, v4l_cropcap, v4l_print_cropcap, INFO_FL_CLEAR(v4l2_cropcap, type)),
26303ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_G_CROP, v4l_g_crop, v4l_print_crop, INFO_FL_CLEAR(v4l2_crop, type)),
26313ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_S_CROP, v4l_s_crop, v4l_print_crop, INFO_FL_PRIO),
26323ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_G_SELECTION, v4l_g_selection, v4l_print_selection, INFO_FL_CLEAR(v4l2_selection, r)),
26333ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_S_SELECTION, v4l_s_selection, v4l_print_selection, INFO_FL_PRIO | INFO_FL_CLEAR(v4l2_selection, r)),
26343ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_G_JPEGCOMP, v4l_stub_g_jpegcomp, v4l_print_jpegcompression, 0),
26353ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_S_JPEGCOMP, v4l_stub_s_jpegcomp, v4l_print_jpegcompression, INFO_FL_PRIO),
26363ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_QUERYSTD, v4l_querystd, v4l_print_std, 0),
26373ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_TRY_FMT, v4l_try_fmt, v4l_print_format, 0),
26383ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_ENUMAUDIO, v4l_stub_enumaudio, v4l_print_audio, INFO_FL_CLEAR(v4l2_audio, index)),
26393ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_ENUMAUDOUT, v4l_stub_enumaudout, v4l_print_audioout, INFO_FL_CLEAR(v4l2_audioout, index)),
26403ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_G_PRIORITY, v4l_g_priority, v4l_print_u32, 0),
26413ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_S_PRIORITY, v4l_s_priority, v4l_print_u32, INFO_FL_PRIO),
26423ad3b7a2SSami 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)),
26433ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_LOG_STATUS, v4l_log_status, v4l_print_newline, 0),
26443ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_G_EXT_CTRLS, v4l_g_ext_ctrls, v4l_print_ext_controls, INFO_FL_CTRL),
26453ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_S_EXT_CTRLS, v4l_s_ext_ctrls, v4l_print_ext_controls, INFO_FL_PRIO | INFO_FL_CTRL),
26463ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_TRY_EXT_CTRLS, v4l_try_ext_ctrls, v4l_print_ext_controls, INFO_FL_CTRL),
26473ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_ENUM_FRAMESIZES, v4l_stub_enum_framesizes, v4l_print_frmsizeenum, INFO_FL_CLEAR(v4l2_frmsizeenum, pixel_format)),
26483ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_ENUM_FRAMEINTERVALS, v4l_stub_enum_frameintervals, v4l_print_frmivalenum, INFO_FL_CLEAR(v4l2_frmivalenum, height)),
26493ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_G_ENC_INDEX, v4l_stub_g_enc_index, v4l_print_enc_idx, 0),
26503ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_ENCODER_CMD, v4l_stub_encoder_cmd, v4l_print_encoder_cmd, INFO_FL_PRIO | INFO_FL_CLEAR(v4l2_encoder_cmd, flags)),
26513ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_TRY_ENCODER_CMD, v4l_stub_try_encoder_cmd, v4l_print_encoder_cmd, INFO_FL_CLEAR(v4l2_encoder_cmd, flags)),
26523ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_DECODER_CMD, v4l_stub_decoder_cmd, v4l_print_decoder_cmd, INFO_FL_PRIO),
26533ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_TRY_DECODER_CMD, v4l_stub_try_decoder_cmd, v4l_print_decoder_cmd, 0),
26543ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_DBG_S_REGISTER, v4l_dbg_s_register, v4l_print_dbg_register, 0),
26553ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_DBG_G_REGISTER, v4l_dbg_g_register, v4l_print_dbg_register, 0),
26563ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_S_HW_FREQ_SEEK, v4l_s_hw_freq_seek, v4l_print_hw_freq_seek, INFO_FL_PRIO),
26573ad3b7a2SSami 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)),
26583ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_G_DV_TIMINGS, v4l_stub_g_dv_timings, v4l_print_dv_timings, 0),
26593ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_DQEVENT, v4l_dqevent, v4l_print_event, 0),
26603ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_SUBSCRIBE_EVENT, v4l_subscribe_event, v4l_print_event_subscription, 0),
26613ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_UNSUBSCRIBE_EVENT, v4l_unsubscribe_event, v4l_print_event_subscription, 0),
26623ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_CREATE_BUFS, v4l_create_bufs, v4l_print_create_buffers, INFO_FL_PRIO | INFO_FL_QUEUE),
26633ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_PREPARE_BUF, v4l_prepare_buf, v4l_print_buffer, INFO_FL_QUEUE),
26643ad3b7a2SSami 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)),
26653ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_QUERY_DV_TIMINGS, v4l_stub_query_dv_timings, v4l_print_dv_timings, INFO_FL_ALWAYS_COPY),
26663ad3b7a2SSami 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)),
26673ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_ENUM_FREQ_BANDS, v4l_enum_freq_bands, v4l_print_freq_band, 0),
26683ad3b7a2SSami 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)),
26693ad3b7a2SSami 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)),
26705bc3cb74SMauro Carvalho Chehab };
26715bc3cb74SMauro Carvalho Chehab #define V4L2_IOCTLS ARRAY_SIZE(v4l2_ioctls)
26725bc3cb74SMauro Carvalho Chehab 
267373a11062SHans Verkuil static bool v4l2_is_known_ioctl(unsigned int cmd)
26745bc3cb74SMauro Carvalho Chehab {
26755bc3cb74SMauro Carvalho Chehab 	if (_IOC_NR(cmd) >= V4L2_IOCTLS)
26765bc3cb74SMauro Carvalho Chehab 		return false;
26775bc3cb74SMauro Carvalho Chehab 	return v4l2_ioctls[_IOC_NR(cmd)].ioctl == cmd;
26785bc3cb74SMauro Carvalho Chehab }
26795bc3cb74SMauro Carvalho Chehab 
2680d862bc08SHans Verkuil #if IS_ENABLED(CONFIG_V4L2_MEM2MEM_DEV)
2681d862bc08SHans Verkuil static bool v4l2_ioctl_m2m_queue_is_output(unsigned int cmd, void *arg)
2682d862bc08SHans Verkuil {
2683d862bc08SHans Verkuil 	switch (cmd) {
2684d862bc08SHans Verkuil 	case VIDIOC_CREATE_BUFS: {
2685d862bc08SHans Verkuil 		struct v4l2_create_buffers *cbufs = arg;
2686d862bc08SHans Verkuil 
2687d862bc08SHans Verkuil 		return V4L2_TYPE_IS_OUTPUT(cbufs->format.type);
2688d862bc08SHans Verkuil 	}
2689d862bc08SHans Verkuil 	case VIDIOC_REQBUFS: {
2690d862bc08SHans Verkuil 		struct v4l2_requestbuffers *rbufs = arg;
2691d862bc08SHans Verkuil 
2692d862bc08SHans Verkuil 		return V4L2_TYPE_IS_OUTPUT(rbufs->type);
2693d862bc08SHans Verkuil 	}
2694d862bc08SHans Verkuil 	case VIDIOC_QBUF:
2695d862bc08SHans Verkuil 	case VIDIOC_DQBUF:
2696d862bc08SHans Verkuil 	case VIDIOC_QUERYBUF:
2697d862bc08SHans Verkuil 	case VIDIOC_PREPARE_BUF: {
2698d862bc08SHans Verkuil 		struct v4l2_buffer *buf = arg;
2699d862bc08SHans Verkuil 
2700d862bc08SHans Verkuil 		return V4L2_TYPE_IS_OUTPUT(buf->type);
2701d862bc08SHans Verkuil 	}
2702d862bc08SHans Verkuil 	case VIDIOC_EXPBUF: {
2703d862bc08SHans Verkuil 		struct v4l2_exportbuffer *expbuf = arg;
2704d862bc08SHans Verkuil 
2705d862bc08SHans Verkuil 		return V4L2_TYPE_IS_OUTPUT(expbuf->type);
2706d862bc08SHans Verkuil 	}
2707d862bc08SHans Verkuil 	case VIDIOC_STREAMON:
2708d862bc08SHans Verkuil 	case VIDIOC_STREAMOFF: {
2709d862bc08SHans Verkuil 		int *type = arg;
2710d862bc08SHans Verkuil 
2711d862bc08SHans Verkuil 		return V4L2_TYPE_IS_OUTPUT(*type);
2712d862bc08SHans Verkuil 	}
2713d862bc08SHans Verkuil 	default:
2714d862bc08SHans Verkuil 		return false;
2715d862bc08SHans Verkuil 	}
2716d862bc08SHans Verkuil }
2717d862bc08SHans Verkuil #endif
2718d862bc08SHans Verkuil 
271973a11062SHans Verkuil static struct mutex *v4l2_ioctl_get_lock(struct video_device *vdev,
2720d862bc08SHans Verkuil 					 struct v4l2_fh *vfh, unsigned int cmd,
2721d862bc08SHans Verkuil 					 void *arg)
27225bc3cb74SMauro Carvalho Chehab {
27235bc3cb74SMauro Carvalho Chehab 	if (_IOC_NR(cmd) >= V4L2_IOCTLS)
27245bc3cb74SMauro Carvalho Chehab 		return vdev->lock;
2725d862bc08SHans Verkuil #if IS_ENABLED(CONFIG_V4L2_MEM2MEM_DEV)
2726d862bc08SHans Verkuil 	if (vfh && vfh->m2m_ctx &&
2727d862bc08SHans Verkuil 	    (v4l2_ioctls[_IOC_NR(cmd)].flags & INFO_FL_QUEUE)) {
2728d862bc08SHans Verkuil 		bool is_output = v4l2_ioctl_m2m_queue_is_output(cmd, arg);
2729d862bc08SHans Verkuil 		struct v4l2_m2m_queue_ctx *ctx = is_output ?
2730d862bc08SHans Verkuil 			&vfh->m2m_ctx->out_q_ctx : &vfh->m2m_ctx->cap_q_ctx;
2731d862bc08SHans Verkuil 
2732d862bc08SHans Verkuil 		if (ctx->q.lock)
2733d862bc08SHans Verkuil 			return ctx->q.lock;
2734d862bc08SHans Verkuil 	}
2735d862bc08SHans Verkuil #endif
27365bc3cb74SMauro Carvalho Chehab 	if (vdev->queue && vdev->queue->lock &&
27375bc3cb74SMauro Carvalho Chehab 			(v4l2_ioctls[_IOC_NR(cmd)].flags & INFO_FL_QUEUE))
27385bc3cb74SMauro Carvalho Chehab 		return vdev->queue->lock;
27395bc3cb74SMauro Carvalho Chehab 	return vdev->lock;
27405bc3cb74SMauro Carvalho Chehab }
27415bc3cb74SMauro Carvalho Chehab 
27425bc3cb74SMauro Carvalho Chehab /* Common ioctl debug function. This function can be used by
27435bc3cb74SMauro Carvalho Chehab    external ioctl messages as well as internal V4L ioctl */
27445bc3cb74SMauro Carvalho Chehab void v4l_printk_ioctl(const char *prefix, unsigned int cmd)
27455bc3cb74SMauro Carvalho Chehab {
27465bc3cb74SMauro Carvalho Chehab 	const char *dir, *type;
27475bc3cb74SMauro Carvalho Chehab 
27485bc3cb74SMauro Carvalho Chehab 	if (prefix)
27495bc3cb74SMauro Carvalho Chehab 		printk(KERN_DEBUG "%s: ", prefix);
27505bc3cb74SMauro Carvalho Chehab 
27515bc3cb74SMauro Carvalho Chehab 	switch (_IOC_TYPE(cmd)) {
27525bc3cb74SMauro Carvalho Chehab 	case 'd':
27535bc3cb74SMauro Carvalho Chehab 		type = "v4l2_int";
27545bc3cb74SMauro Carvalho Chehab 		break;
27555bc3cb74SMauro Carvalho Chehab 	case 'V':
27565bc3cb74SMauro Carvalho Chehab 		if (_IOC_NR(cmd) >= V4L2_IOCTLS) {
27575bc3cb74SMauro Carvalho Chehab 			type = "v4l2";
27585bc3cb74SMauro Carvalho Chehab 			break;
27595bc3cb74SMauro Carvalho Chehab 		}
27605bc3cb74SMauro Carvalho Chehab 		pr_cont("%s", v4l2_ioctls[_IOC_NR(cmd)].name);
27615bc3cb74SMauro Carvalho Chehab 		return;
27625bc3cb74SMauro Carvalho Chehab 	default:
27635bc3cb74SMauro Carvalho Chehab 		type = "unknown";
27645bc3cb74SMauro Carvalho Chehab 		break;
27655bc3cb74SMauro Carvalho Chehab 	}
27665bc3cb74SMauro Carvalho Chehab 
27675bc3cb74SMauro Carvalho Chehab 	switch (_IOC_DIR(cmd)) {
27685bc3cb74SMauro Carvalho Chehab 	case _IOC_NONE:              dir = "--"; break;
27695bc3cb74SMauro Carvalho Chehab 	case _IOC_READ:              dir = "r-"; break;
27705bc3cb74SMauro Carvalho Chehab 	case _IOC_WRITE:             dir = "-w"; break;
27715bc3cb74SMauro Carvalho Chehab 	case _IOC_READ | _IOC_WRITE: dir = "rw"; break;
27725bc3cb74SMauro Carvalho Chehab 	default:                     dir = "*ERR*"; break;
27735bc3cb74SMauro Carvalho Chehab 	}
27745bc3cb74SMauro Carvalho Chehab 	pr_cont("%s ioctl '%c', dir=%s, #%d (0x%08x)",
27755bc3cb74SMauro Carvalho Chehab 		type, _IOC_TYPE(cmd), dir, _IOC_NR(cmd), cmd);
27765bc3cb74SMauro Carvalho Chehab }
27775bc3cb74SMauro Carvalho Chehab EXPORT_SYMBOL(v4l_printk_ioctl);
27785bc3cb74SMauro Carvalho Chehab 
27795bc3cb74SMauro Carvalho Chehab static long __video_do_ioctl(struct file *file,
27805bc3cb74SMauro Carvalho Chehab 		unsigned int cmd, void *arg)
27815bc3cb74SMauro Carvalho Chehab {
27825bc3cb74SMauro Carvalho Chehab 	struct video_device *vfd = video_devdata(file);
2783cc6eddcdSHans Verkuil 	struct mutex *req_queue_lock = NULL;
278473a11062SHans Verkuil 	struct mutex *lock; /* ioctl serialization mutex */
27855bc3cb74SMauro Carvalho Chehab 	const struct v4l2_ioctl_ops *ops = vfd->ioctl_ops;
27865bc3cb74SMauro Carvalho Chehab 	bool write_only = false;
27875bc3cb74SMauro Carvalho Chehab 	struct v4l2_ioctl_info default_info;
27885bc3cb74SMauro Carvalho Chehab 	const struct v4l2_ioctl_info *info;
27895bc3cb74SMauro Carvalho Chehab 	void *fh = file->private_data;
27905bc3cb74SMauro Carvalho Chehab 	struct v4l2_fh *vfh = NULL;
279117028cdbSHans Verkuil 	int dev_debug = vfd->dev_debug;
27925bc3cb74SMauro Carvalho Chehab 	long ret = -ENOTTY;
27935bc3cb74SMauro Carvalho Chehab 
27945bc3cb74SMauro Carvalho Chehab 	if (ops == NULL) {
27955bc3cb74SMauro Carvalho Chehab 		pr_warn("%s: has no ioctl_ops.\n",
27965bc3cb74SMauro Carvalho Chehab 				video_device_node_name(vfd));
27975bc3cb74SMauro Carvalho Chehab 		return ret;
27985bc3cb74SMauro Carvalho Chehab 	}
27995bc3cb74SMauro Carvalho Chehab 
2800b7284bb0SRamakrishnan Muthukrishnan 	if (test_bit(V4L2_FL_USES_V4L2_FH, &vfd->flags))
28015bc3cb74SMauro Carvalho Chehab 		vfh = file->private_data;
28025bc3cb74SMauro Carvalho Chehab 
2803cc6eddcdSHans Verkuil 	/*
2804cc6eddcdSHans Verkuil 	 * We need to serialize streamon/off with queueing new requests.
2805cc6eddcdSHans Verkuil 	 * These ioctls may trigger the cancellation of a streaming
2806cc6eddcdSHans Verkuil 	 * operation, and that should not be mixed with queueing a new
2807cc6eddcdSHans Verkuil 	 * request at the same time.
2808cc6eddcdSHans Verkuil 	 */
2809cc6eddcdSHans Verkuil 	if (v4l2_device_supports_requests(vfd->v4l2_dev) &&
2810cc6eddcdSHans Verkuil 	    (cmd == VIDIOC_STREAMON || cmd == VIDIOC_STREAMOFF)) {
2811cc6eddcdSHans Verkuil 		req_queue_lock = &vfd->v4l2_dev->mdev->req_queue_mutex;
2812cc6eddcdSHans Verkuil 
2813cc6eddcdSHans Verkuil 		if (mutex_lock_interruptible(req_queue_lock))
2814cc6eddcdSHans Verkuil 			return -ERESTARTSYS;
2815cc6eddcdSHans Verkuil 	}
2816cc6eddcdSHans Verkuil 
2817d862bc08SHans Verkuil 	lock = v4l2_ioctl_get_lock(vfd, vfh, cmd, arg);
281873a11062SHans Verkuil 
2819cc6eddcdSHans Verkuil 	if (lock && mutex_lock_interruptible(lock)) {
2820cc6eddcdSHans Verkuil 		if (req_queue_lock)
2821cc6eddcdSHans Verkuil 			mutex_unlock(req_queue_lock);
282273a11062SHans Verkuil 		return -ERESTARTSYS;
2823cc6eddcdSHans Verkuil 	}
282473a11062SHans Verkuil 
282573a11062SHans Verkuil 	if (!video_is_registered(vfd)) {
282673a11062SHans Verkuil 		ret = -ENODEV;
282773a11062SHans Verkuil 		goto unlock;
282873a11062SHans Verkuil 	}
282973a11062SHans Verkuil 
28305bc3cb74SMauro Carvalho Chehab 	if (v4l2_is_known_ioctl(cmd)) {
28315bc3cb74SMauro Carvalho Chehab 		info = &v4l2_ioctls[_IOC_NR(cmd)];
28325bc3cb74SMauro Carvalho Chehab 
28335bc3cb74SMauro Carvalho Chehab 		if (!test_bit(_IOC_NR(cmd), vfd->valid_ioctls) &&
28345bc3cb74SMauro Carvalho Chehab 		    !((info->flags & INFO_FL_CTRL) && vfh && vfh->ctrl_handler))
28355bc3cb74SMauro Carvalho Chehab 			goto done;
28365bc3cb74SMauro Carvalho Chehab 
2837b7284bb0SRamakrishnan Muthukrishnan 		if (vfh && (info->flags & INFO_FL_PRIO)) {
28385bc3cb74SMauro Carvalho Chehab 			ret = v4l2_prio_check(vfd->prio, vfh->prio);
28395bc3cb74SMauro Carvalho Chehab 			if (ret)
28405bc3cb74SMauro Carvalho Chehab 				goto done;
28415bc3cb74SMauro Carvalho Chehab 		}
28425bc3cb74SMauro Carvalho Chehab 	} else {
28435bc3cb74SMauro Carvalho Chehab 		default_info.ioctl = cmd;
28445bc3cb74SMauro Carvalho Chehab 		default_info.flags = 0;
28455bc3cb74SMauro Carvalho Chehab 		default_info.debug = v4l_print_default;
28465bc3cb74SMauro Carvalho Chehab 		info = &default_info;
28475bc3cb74SMauro Carvalho Chehab 	}
28485bc3cb74SMauro Carvalho Chehab 
28495bc3cb74SMauro Carvalho Chehab 	write_only = _IOC_DIR(cmd) == _IOC_WRITE;
28503ad3b7a2SSami Tolvanen 	if (info != &default_info) {
28513ad3b7a2SSami Tolvanen 		ret = info->func(ops, file, fh, arg);
28525bc3cb74SMauro Carvalho Chehab 	} else if (!ops->vidioc_default) {
28535bc3cb74SMauro Carvalho Chehab 		ret = -ENOTTY;
28545bc3cb74SMauro Carvalho Chehab 	} else {
28555bc3cb74SMauro Carvalho Chehab 		ret = ops->vidioc_default(file, fh,
2856b7284bb0SRamakrishnan Muthukrishnan 			vfh ? v4l2_prio_check(vfd->prio, vfh->prio) >= 0 : 0,
28575bc3cb74SMauro Carvalho Chehab 			cmd, arg);
28585bc3cb74SMauro Carvalho Chehab 	}
28595bc3cb74SMauro Carvalho Chehab 
28605bc3cb74SMauro Carvalho Chehab done:
286117028cdbSHans Verkuil 	if (dev_debug & (V4L2_DEV_DEBUG_IOCTL | V4L2_DEV_DEBUG_IOCTL_ARG)) {
286217028cdbSHans Verkuil 		if (!(dev_debug & V4L2_DEV_DEBUG_STREAMING) &&
286317028cdbSHans Verkuil 		    (cmd == VIDIOC_QBUF || cmd == VIDIOC_DQBUF))
28645983d3bcSHans Verkuil 			goto unlock;
286517028cdbSHans Verkuil 
28665bc3cb74SMauro Carvalho Chehab 		v4l_printk_ioctl(video_device_node_name(vfd), cmd);
28675bc3cb74SMauro Carvalho Chehab 		if (ret < 0)
2868505d04bdSHans Verkuil 			pr_cont(": error %ld", ret);
286917028cdbSHans Verkuil 		if (!(dev_debug & V4L2_DEV_DEBUG_IOCTL_ARG))
28705bc3cb74SMauro Carvalho Chehab 			pr_cont("\n");
28715bc3cb74SMauro Carvalho Chehab 		else if (_IOC_DIR(cmd) == _IOC_NONE)
28725bc3cb74SMauro Carvalho Chehab 			info->debug(arg, write_only);
28735bc3cb74SMauro Carvalho Chehab 		else {
28745bc3cb74SMauro Carvalho Chehab 			pr_cont(": ");
28755bc3cb74SMauro Carvalho Chehab 			info->debug(arg, write_only);
28765bc3cb74SMauro Carvalho Chehab 		}
28775bc3cb74SMauro Carvalho Chehab 	}
28785bc3cb74SMauro Carvalho Chehab 
287973a11062SHans Verkuil unlock:
288073a11062SHans Verkuil 	if (lock)
288173a11062SHans Verkuil 		mutex_unlock(lock);
2882cc6eddcdSHans Verkuil 	if (req_queue_lock)
2883cc6eddcdSHans Verkuil 		mutex_unlock(req_queue_lock);
28845bc3cb74SMauro Carvalho Chehab 	return ret;
28855bc3cb74SMauro Carvalho Chehab }
28865bc3cb74SMauro Carvalho Chehab 
28875bc3cb74SMauro Carvalho Chehab static int check_array_args(unsigned int cmd, void *parg, size_t *array_size,
2888ba2d35c1SHans Verkuil 			    void __user **user_ptr, void ***kernel_ptr)
28895bc3cb74SMauro Carvalho Chehab {
28905bc3cb74SMauro Carvalho Chehab 	int ret = 0;
28915bc3cb74SMauro Carvalho Chehab 
28925bc3cb74SMauro Carvalho Chehab 	switch (cmd) {
289396b1a702SHans Verkuil 	case VIDIOC_PREPARE_BUF:
28945bc3cb74SMauro Carvalho Chehab 	case VIDIOC_QUERYBUF:
28955bc3cb74SMauro Carvalho Chehab 	case VIDIOC_QBUF:
28965bc3cb74SMauro Carvalho Chehab 	case VIDIOC_DQBUF: {
28975bc3cb74SMauro Carvalho Chehab 		struct v4l2_buffer *buf = parg;
28985bc3cb74SMauro Carvalho Chehab 
28995bc3cb74SMauro Carvalho Chehab 		if (V4L2_TYPE_IS_MULTIPLANAR(buf->type) && buf->length > 0) {
29005bc3cb74SMauro Carvalho Chehab 			if (buf->length > VIDEO_MAX_PLANES) {
29015bc3cb74SMauro Carvalho Chehab 				ret = -EINVAL;
29025bc3cb74SMauro Carvalho Chehab 				break;
29035bc3cb74SMauro Carvalho Chehab 			}
29045bc3cb74SMauro Carvalho Chehab 			*user_ptr = (void __user *)buf->m.planes;
2905ba2d35c1SHans Verkuil 			*kernel_ptr = (void **)&buf->m.planes;
29065bc3cb74SMauro Carvalho Chehab 			*array_size = sizeof(struct v4l2_plane) * buf->length;
29075bc3cb74SMauro Carvalho Chehab 			ret = 1;
29085bc3cb74SMauro Carvalho Chehab 		}
29095bc3cb74SMauro Carvalho Chehab 		break;
29105bc3cb74SMauro Carvalho Chehab 	}
29115bc3cb74SMauro Carvalho Chehab 
2912dd519bb3SHans Verkuil 	case VIDIOC_G_EDID:
2913dd519bb3SHans Verkuil 	case VIDIOC_S_EDID: {
2914dd519bb3SHans Verkuil 		struct v4l2_edid *edid = parg;
2915ed45ce2cSHans Verkuil 
2916ed45ce2cSHans Verkuil 		if (edid->blocks) {
29171b8b10ccSHans Verkuil 			if (edid->blocks > 256) {
29181b8b10ccSHans Verkuil 				ret = -EINVAL;
29191b8b10ccSHans Verkuil 				break;
29201b8b10ccSHans Verkuil 			}
2921ed45ce2cSHans Verkuil 			*user_ptr = (void __user *)edid->edid;
2922ba2d35c1SHans Verkuil 			*kernel_ptr = (void **)&edid->edid;
2923ed45ce2cSHans Verkuil 			*array_size = edid->blocks * 128;
2924ed45ce2cSHans Verkuil 			ret = 1;
2925ed45ce2cSHans Verkuil 		}
2926ed45ce2cSHans Verkuil 		break;
2927ed45ce2cSHans Verkuil 	}
2928ed45ce2cSHans Verkuil 
29295bc3cb74SMauro Carvalho Chehab 	case VIDIOC_S_EXT_CTRLS:
29305bc3cb74SMauro Carvalho Chehab 	case VIDIOC_G_EXT_CTRLS:
29315bc3cb74SMauro Carvalho Chehab 	case VIDIOC_TRY_EXT_CTRLS: {
29325bc3cb74SMauro Carvalho Chehab 		struct v4l2_ext_controls *ctrls = parg;
29335bc3cb74SMauro Carvalho Chehab 
29345bc3cb74SMauro Carvalho Chehab 		if (ctrls->count != 0) {
29355bc3cb74SMauro Carvalho Chehab 			if (ctrls->count > V4L2_CID_MAX_CTRLS) {
29365bc3cb74SMauro Carvalho Chehab 				ret = -EINVAL;
29375bc3cb74SMauro Carvalho Chehab 				break;
29385bc3cb74SMauro Carvalho Chehab 			}
29395bc3cb74SMauro Carvalho Chehab 			*user_ptr = (void __user *)ctrls->controls;
2940ba2d35c1SHans Verkuil 			*kernel_ptr = (void **)&ctrls->controls;
29415bc3cb74SMauro Carvalho Chehab 			*array_size = sizeof(struct v4l2_ext_control)
29425bc3cb74SMauro Carvalho Chehab 				    * ctrls->count;
29435bc3cb74SMauro Carvalho Chehab 			ret = 1;
29445bc3cb74SMauro Carvalho Chehab 		}
29455bc3cb74SMauro Carvalho Chehab 		break;
29465bc3cb74SMauro Carvalho Chehab 	}
29475bc3cb74SMauro Carvalho Chehab 	}
29485bc3cb74SMauro Carvalho Chehab 
29495bc3cb74SMauro Carvalho Chehab 	return ret;
29505bc3cb74SMauro Carvalho Chehab }
29515bc3cb74SMauro Carvalho Chehab 
29525bc3cb74SMauro Carvalho Chehab long
29535bc3cb74SMauro Carvalho Chehab video_usercopy(struct file *file, unsigned int cmd, unsigned long arg,
29545bc3cb74SMauro Carvalho Chehab 	       v4l2_kioctl func)
29555bc3cb74SMauro Carvalho Chehab {
29565bc3cb74SMauro Carvalho Chehab 	char	sbuf[128];
29575bc3cb74SMauro Carvalho Chehab 	void    *mbuf = NULL;
29585bc3cb74SMauro Carvalho Chehab 	void	*parg = (void *)arg;
29595bc3cb74SMauro Carvalho Chehab 	long	err  = -EINVAL;
29605bc3cb74SMauro Carvalho Chehab 	bool	has_array_args;
2961043f77edSHans Verkuil 	bool	always_copy = false;
29625bc3cb74SMauro Carvalho Chehab 	size_t  array_size = 0;
29635bc3cb74SMauro Carvalho Chehab 	void __user *user_ptr = NULL;
29645bc3cb74SMauro Carvalho Chehab 	void	**kernel_ptr = NULL;
2965f8a695c4SMauro Carvalho Chehab 	const size_t ioc_size = _IOC_SIZE(cmd);
29665bc3cb74SMauro Carvalho Chehab 
29675bc3cb74SMauro Carvalho Chehab 	/*  Copy arguments into temp kernel buffer  */
29685bc3cb74SMauro Carvalho Chehab 	if (_IOC_DIR(cmd) != _IOC_NONE) {
2969f8a695c4SMauro Carvalho Chehab 		if (ioc_size <= sizeof(sbuf)) {
29705bc3cb74SMauro Carvalho Chehab 			parg = sbuf;
29715bc3cb74SMauro Carvalho Chehab 		} else {
29725bc3cb74SMauro Carvalho Chehab 			/* too big to allocate from stack */
2973f8a695c4SMauro Carvalho Chehab 			mbuf = kvmalloc(ioc_size, GFP_KERNEL);
29745bc3cb74SMauro Carvalho Chehab 			if (NULL == mbuf)
29755bc3cb74SMauro Carvalho Chehab 				return -ENOMEM;
29765bc3cb74SMauro Carvalho Chehab 			parg = mbuf;
29775bc3cb74SMauro Carvalho Chehab 		}
29785bc3cb74SMauro Carvalho Chehab 
29795bc3cb74SMauro Carvalho Chehab 		err = -EFAULT;
29805bc3cb74SMauro Carvalho Chehab 		if (_IOC_DIR(cmd) & _IOC_WRITE) {
2981f8a695c4SMauro Carvalho Chehab 			unsigned int n = ioc_size;
29825bc3cb74SMauro Carvalho Chehab 
29835bc3cb74SMauro Carvalho Chehab 			/*
29845bc3cb74SMauro Carvalho Chehab 			 * In some cases, only a few fields are used as input,
29855bc3cb74SMauro Carvalho Chehab 			 * i.e. when the app sets "index" and then the driver
29865bc3cb74SMauro Carvalho Chehab 			 * fills in the rest of the structure for the thing
29875bc3cb74SMauro Carvalho Chehab 			 * with that index.  We only need to copy up the first
29885bc3cb74SMauro Carvalho Chehab 			 * non-input field.
29895bc3cb74SMauro Carvalho Chehab 			 */
29905bc3cb74SMauro Carvalho Chehab 			if (v4l2_is_known_ioctl(cmd)) {
29915bc3cb74SMauro Carvalho Chehab 				u32 flags = v4l2_ioctls[_IOC_NR(cmd)].flags;
2992043f77edSHans Verkuil 
29935bc3cb74SMauro Carvalho Chehab 				if (flags & INFO_FL_CLEAR_MASK)
29945bc3cb74SMauro Carvalho Chehab 					n = (flags & INFO_FL_CLEAR_MASK) >> 16;
2995043f77edSHans Verkuil 				always_copy = flags & INFO_FL_ALWAYS_COPY;
29965bc3cb74SMauro Carvalho Chehab 			}
29975bc3cb74SMauro Carvalho Chehab 
29985bc3cb74SMauro Carvalho Chehab 			if (copy_from_user(parg, (void __user *)arg, n))
29995bc3cb74SMauro Carvalho Chehab 				goto out;
30005bc3cb74SMauro Carvalho Chehab 
30015bc3cb74SMauro Carvalho Chehab 			/* zero out anything we don't copy from userspace */
3002f8a695c4SMauro Carvalho Chehab 			if (n < ioc_size)
3003f8a695c4SMauro Carvalho Chehab 				memset((u8 *)parg + n, 0, ioc_size - n);
30045bc3cb74SMauro Carvalho Chehab 		} else {
30055bc3cb74SMauro Carvalho Chehab 			/* read-only ioctl */
3006f8a695c4SMauro Carvalho Chehab 			memset(parg, 0, ioc_size);
30075bc3cb74SMauro Carvalho Chehab 		}
30085bc3cb74SMauro Carvalho Chehab 	}
30095bc3cb74SMauro Carvalho Chehab 
30105bc3cb74SMauro Carvalho Chehab 	err = check_array_args(cmd, parg, &array_size, &user_ptr, &kernel_ptr);
30115bc3cb74SMauro Carvalho Chehab 	if (err < 0)
30125bc3cb74SMauro Carvalho Chehab 		goto out;
30135bc3cb74SMauro Carvalho Chehab 	has_array_args = err;
30145bc3cb74SMauro Carvalho Chehab 
30155bc3cb74SMauro Carvalho Chehab 	if (has_array_args) {
30165bc3cb74SMauro Carvalho Chehab 		/*
30175bc3cb74SMauro Carvalho Chehab 		 * When adding new types of array args, make sure that the
30185bc3cb74SMauro Carvalho Chehab 		 * parent argument to ioctl (which contains the pointer to the
30195bc3cb74SMauro Carvalho Chehab 		 * array) fits into sbuf (so that mbuf will still remain
30205bc3cb74SMauro Carvalho Chehab 		 * unused up to here).
30215bc3cb74SMauro Carvalho Chehab 		 */
3022758d90e1STomasz Figa 		mbuf = kvmalloc(array_size, GFP_KERNEL);
30235bc3cb74SMauro Carvalho Chehab 		err = -ENOMEM;
30245bc3cb74SMauro Carvalho Chehab 		if (NULL == mbuf)
30255bc3cb74SMauro Carvalho Chehab 			goto out_array_args;
30265bc3cb74SMauro Carvalho Chehab 		err = -EFAULT;
30275bc3cb74SMauro Carvalho Chehab 		if (copy_from_user(mbuf, user_ptr, array_size))
30285bc3cb74SMauro Carvalho Chehab 			goto out_array_args;
30295bc3cb74SMauro Carvalho Chehab 		*kernel_ptr = mbuf;
30305bc3cb74SMauro Carvalho Chehab 	}
30315bc3cb74SMauro Carvalho Chehab 
30325bc3cb74SMauro Carvalho Chehab 	/* Handles IOCTL */
30335bc3cb74SMauro Carvalho Chehab 	err = func(file, cmd, parg);
3034181a4a2dSHans Verkuil 	if (err == -ENOTTY || err == -ENOIOCTLCMD) {
30355bc3cb74SMauro Carvalho Chehab 		err = -ENOTTY;
3036181a4a2dSHans Verkuil 		goto out;
3037181a4a2dSHans Verkuil 	}
3038181a4a2dSHans Verkuil 
3039aa32f4c0SHans Verkuil 	if (err == 0) {
3040aa32f4c0SHans Verkuil 		if (cmd == VIDIOC_DQBUF)
3041aa32f4c0SHans Verkuil 			trace_v4l2_dqbuf(video_devdata(file)->minor, parg);
3042aa32f4c0SHans Verkuil 		else if (cmd == VIDIOC_QBUF)
3043aa32f4c0SHans Verkuil 			trace_v4l2_qbuf(video_devdata(file)->minor, parg);
3044aa32f4c0SHans Verkuil 	}
30455bc3cb74SMauro Carvalho Chehab 
30465bc3cb74SMauro Carvalho Chehab 	if (has_array_args) {
3047ba2d35c1SHans Verkuil 		*kernel_ptr = (void __force *)user_ptr;
30485bc3cb74SMauro Carvalho Chehab 		if (copy_to_user(user_ptr, mbuf, array_size))
30495bc3cb74SMauro Carvalho Chehab 			err = -EFAULT;
30505bc3cb74SMauro Carvalho Chehab 		goto out_array_args;
30515bc3cb74SMauro Carvalho Chehab 	}
3052043f77edSHans Verkuil 	/*
3053043f77edSHans Verkuil 	 * Some ioctls can return an error, but still have valid
3054043f77edSHans Verkuil 	 * results that must be returned.
3055043f77edSHans Verkuil 	 */
3056043f77edSHans Verkuil 	if (err < 0 && !always_copy)
30575bc3cb74SMauro Carvalho Chehab 		goto out;
30585bc3cb74SMauro Carvalho Chehab 
30595bc3cb74SMauro Carvalho Chehab out_array_args:
30605bc3cb74SMauro Carvalho Chehab 	/*  Copy results into user buffer  */
30615bc3cb74SMauro Carvalho Chehab 	switch (_IOC_DIR(cmd)) {
30625bc3cb74SMauro Carvalho Chehab 	case _IOC_READ:
30635bc3cb74SMauro Carvalho Chehab 	case (_IOC_WRITE | _IOC_READ):
3064f8a695c4SMauro Carvalho Chehab 		if (copy_to_user((void __user *)arg, parg, ioc_size))
30655bc3cb74SMauro Carvalho Chehab 			err = -EFAULT;
30665bc3cb74SMauro Carvalho Chehab 		break;
30675bc3cb74SMauro Carvalho Chehab 	}
30685bc3cb74SMauro Carvalho Chehab 
30695bc3cb74SMauro Carvalho Chehab out:
3070758d90e1STomasz Figa 	kvfree(mbuf);
30715bc3cb74SMauro Carvalho Chehab 	return err;
30725bc3cb74SMauro Carvalho Chehab }
30735bc3cb74SMauro Carvalho Chehab 
30745bc3cb74SMauro Carvalho Chehab long video_ioctl2(struct file *file,
30755bc3cb74SMauro Carvalho Chehab 	       unsigned int cmd, unsigned long arg)
30765bc3cb74SMauro Carvalho Chehab {
30775bc3cb74SMauro Carvalho Chehab 	return video_usercopy(file, cmd, arg, __video_do_ioctl);
30785bc3cb74SMauro Carvalho Chehab }
30795bc3cb74SMauro Carvalho Chehab EXPORT_SYMBOL(video_ioctl2);
3080