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)
125bc3cb74SMauro Carvalho Chehab  *              Mauro Carvalho Chehab <mchehab@infradead.org> (version 2)
135bc3cb74SMauro Carvalho Chehab  */
145bc3cb74SMauro Carvalho Chehab 
155bc3cb74SMauro Carvalho Chehab #include <linux/module.h>
165bc3cb74SMauro Carvalho Chehab #include <linux/slab.h>
175bc3cb74SMauro Carvalho Chehab #include <linux/types.h>
185bc3cb74SMauro Carvalho Chehab #include <linux/kernel.h>
195bc3cb74SMauro Carvalho Chehab #include <linux/version.h>
205bc3cb74SMauro Carvalho Chehab 
215bc3cb74SMauro Carvalho Chehab #include <linux/videodev2.h>
225bc3cb74SMauro Carvalho Chehab 
235bc3cb74SMauro Carvalho Chehab #include <media/v4l2-common.h>
245bc3cb74SMauro Carvalho Chehab #include <media/v4l2-ioctl.h>
255bc3cb74SMauro Carvalho Chehab #include <media/v4l2-ctrls.h>
265bc3cb74SMauro Carvalho Chehab #include <media/v4l2-fh.h>
275bc3cb74SMauro Carvalho Chehab #include <media/v4l2-event.h>
285bc3cb74SMauro Carvalho Chehab #include <media/v4l2-device.h>
29c139990eSJunghak Sung #include <media/videobuf2-v4l2.h>
3077fa4e07SShuah Khan #include <media/v4l2-mc.h>
315bc3cb74SMauro Carvalho Chehab 
32aa32f4c0SHans Verkuil #include <trace/events/v4l2.h>
33aa32f4c0SHans Verkuil 
345bc3cb74SMauro Carvalho Chehab /* Zero out the end of the struct pointed to by p.  Everything after, but
355bc3cb74SMauro Carvalho Chehab  * not including, the specified field is cleared. */
365bc3cb74SMauro Carvalho Chehab #define CLEAR_AFTER_FIELD(p, field) \
375bc3cb74SMauro Carvalho Chehab 	memset((u8 *)(p) + offsetof(typeof(*(p)), field) + sizeof((p)->field), \
385bc3cb74SMauro Carvalho Chehab 	0, sizeof(*(p)) - offsetof(typeof(*(p)), field) - sizeof((p)->field))
395bc3cb74SMauro Carvalho Chehab 
4073f35418SHans Verkuil #define is_valid_ioctl(vfd, cmd) test_bit(_IOC_NR(cmd), (vfd)->valid_ioctls)
4173f35418SHans Verkuil 
425bc3cb74SMauro Carvalho Chehab struct std_descr {
435bc3cb74SMauro Carvalho Chehab 	v4l2_std_id std;
445bc3cb74SMauro Carvalho Chehab 	const char *descr;
455bc3cb74SMauro Carvalho Chehab };
465bc3cb74SMauro Carvalho Chehab 
475bc3cb74SMauro Carvalho Chehab static const struct std_descr standards[] = {
485bc3cb74SMauro Carvalho Chehab 	{ V4L2_STD_NTSC, 	"NTSC"      },
495bc3cb74SMauro Carvalho Chehab 	{ V4L2_STD_NTSC_M, 	"NTSC-M"    },
505bc3cb74SMauro Carvalho Chehab 	{ V4L2_STD_NTSC_M_JP, 	"NTSC-M-JP" },
515bc3cb74SMauro Carvalho Chehab 	{ V4L2_STD_NTSC_M_KR,	"NTSC-M-KR" },
525bc3cb74SMauro Carvalho Chehab 	{ V4L2_STD_NTSC_443, 	"NTSC-443"  },
535bc3cb74SMauro Carvalho Chehab 	{ V4L2_STD_PAL, 	"PAL"       },
545bc3cb74SMauro Carvalho Chehab 	{ V4L2_STD_PAL_BG, 	"PAL-BG"    },
555bc3cb74SMauro Carvalho Chehab 	{ V4L2_STD_PAL_B, 	"PAL-B"     },
565bc3cb74SMauro Carvalho Chehab 	{ V4L2_STD_PAL_B1, 	"PAL-B1"    },
575bc3cb74SMauro Carvalho Chehab 	{ V4L2_STD_PAL_G, 	"PAL-G"     },
585bc3cb74SMauro Carvalho Chehab 	{ V4L2_STD_PAL_H, 	"PAL-H"     },
595bc3cb74SMauro Carvalho Chehab 	{ V4L2_STD_PAL_I, 	"PAL-I"     },
605bc3cb74SMauro Carvalho Chehab 	{ V4L2_STD_PAL_DK, 	"PAL-DK"    },
615bc3cb74SMauro Carvalho Chehab 	{ V4L2_STD_PAL_D, 	"PAL-D"     },
625bc3cb74SMauro Carvalho Chehab 	{ V4L2_STD_PAL_D1, 	"PAL-D1"    },
635bc3cb74SMauro Carvalho Chehab 	{ V4L2_STD_PAL_K, 	"PAL-K"     },
645bc3cb74SMauro Carvalho Chehab 	{ V4L2_STD_PAL_M, 	"PAL-M"     },
655bc3cb74SMauro Carvalho Chehab 	{ V4L2_STD_PAL_N, 	"PAL-N"     },
665bc3cb74SMauro Carvalho Chehab 	{ V4L2_STD_PAL_Nc, 	"PAL-Nc"    },
675bc3cb74SMauro Carvalho Chehab 	{ V4L2_STD_PAL_60, 	"PAL-60"    },
685bc3cb74SMauro Carvalho Chehab 	{ V4L2_STD_SECAM, 	"SECAM"     },
695bc3cb74SMauro Carvalho Chehab 	{ V4L2_STD_SECAM_B, 	"SECAM-B"   },
705bc3cb74SMauro Carvalho Chehab 	{ V4L2_STD_SECAM_G, 	"SECAM-G"   },
715bc3cb74SMauro Carvalho Chehab 	{ V4L2_STD_SECAM_H, 	"SECAM-H"   },
725bc3cb74SMauro Carvalho Chehab 	{ V4L2_STD_SECAM_DK, 	"SECAM-DK"  },
735bc3cb74SMauro Carvalho Chehab 	{ V4L2_STD_SECAM_D, 	"SECAM-D"   },
745bc3cb74SMauro Carvalho Chehab 	{ V4L2_STD_SECAM_K, 	"SECAM-K"   },
755bc3cb74SMauro Carvalho Chehab 	{ V4L2_STD_SECAM_K1, 	"SECAM-K1"  },
765bc3cb74SMauro Carvalho Chehab 	{ V4L2_STD_SECAM_L, 	"SECAM-L"   },
775bc3cb74SMauro Carvalho Chehab 	{ V4L2_STD_SECAM_LC, 	"SECAM-Lc"  },
785bc3cb74SMauro Carvalho Chehab 	{ 0, 			"Unknown"   }
795bc3cb74SMauro Carvalho Chehab };
805bc3cb74SMauro Carvalho Chehab 
815bc3cb74SMauro Carvalho Chehab /* video4linux standard ID conversion to standard name
825bc3cb74SMauro Carvalho Chehab  */
835bc3cb74SMauro Carvalho Chehab const char *v4l2_norm_to_name(v4l2_std_id id)
845bc3cb74SMauro Carvalho Chehab {
855bc3cb74SMauro Carvalho Chehab 	u32 myid = id;
865bc3cb74SMauro Carvalho Chehab 	int i;
875bc3cb74SMauro Carvalho Chehab 
885bc3cb74SMauro Carvalho Chehab 	/* HACK: ppc32 architecture doesn't have __ucmpdi2 function to handle
895bc3cb74SMauro Carvalho Chehab 	   64 bit comparations. So, on that architecture, with some gcc
905bc3cb74SMauro Carvalho Chehab 	   variants, compilation fails. Currently, the max value is 30bit wide.
915bc3cb74SMauro Carvalho Chehab 	 */
925bc3cb74SMauro Carvalho Chehab 	BUG_ON(myid != id);
935bc3cb74SMauro Carvalho Chehab 
945bc3cb74SMauro Carvalho Chehab 	for (i = 0; standards[i].std; i++)
955bc3cb74SMauro Carvalho Chehab 		if (myid == standards[i].std)
965bc3cb74SMauro Carvalho Chehab 			break;
975bc3cb74SMauro Carvalho Chehab 	return standards[i].descr;
985bc3cb74SMauro Carvalho Chehab }
995bc3cb74SMauro Carvalho Chehab EXPORT_SYMBOL(v4l2_norm_to_name);
1005bc3cb74SMauro Carvalho Chehab 
1015bc3cb74SMauro Carvalho Chehab /* Returns frame period for the given standard */
1025bc3cb74SMauro Carvalho Chehab void v4l2_video_std_frame_period(int id, struct v4l2_fract *frameperiod)
1035bc3cb74SMauro Carvalho Chehab {
1045bc3cb74SMauro Carvalho Chehab 	if (id & V4L2_STD_525_60) {
1055bc3cb74SMauro Carvalho Chehab 		frameperiod->numerator = 1001;
1065bc3cb74SMauro Carvalho Chehab 		frameperiod->denominator = 30000;
1075bc3cb74SMauro Carvalho Chehab 	} else {
1085bc3cb74SMauro Carvalho Chehab 		frameperiod->numerator = 1;
1095bc3cb74SMauro Carvalho Chehab 		frameperiod->denominator = 25;
1105bc3cb74SMauro Carvalho Chehab 	}
1115bc3cb74SMauro Carvalho Chehab }
1125bc3cb74SMauro Carvalho Chehab EXPORT_SYMBOL(v4l2_video_std_frame_period);
1135bc3cb74SMauro Carvalho Chehab 
1145bc3cb74SMauro Carvalho Chehab /* Fill in the fields of a v4l2_standard structure according to the
1155bc3cb74SMauro Carvalho Chehab    'id' and 'transmission' parameters.  Returns negative on error.  */
1165bc3cb74SMauro Carvalho Chehab int v4l2_video_std_construct(struct v4l2_standard *vs,
1175bc3cb74SMauro Carvalho Chehab 			     int id, const char *name)
1185bc3cb74SMauro Carvalho Chehab {
1195bc3cb74SMauro Carvalho Chehab 	vs->id = id;
1205bc3cb74SMauro Carvalho Chehab 	v4l2_video_std_frame_period(id, &vs->frameperiod);
1215bc3cb74SMauro Carvalho Chehab 	vs->framelines = (id & V4L2_STD_525_60) ? 525 : 625;
1225bc3cb74SMauro Carvalho Chehab 	strlcpy(vs->name, name, sizeof(vs->name));
1235bc3cb74SMauro Carvalho Chehab 	return 0;
1245bc3cb74SMauro Carvalho Chehab }
1255bc3cb74SMauro Carvalho Chehab EXPORT_SYMBOL(v4l2_video_std_construct);
1265bc3cb74SMauro Carvalho Chehab 
1275bc3cb74SMauro Carvalho Chehab /* ----------------------------------------------------------------- */
1285bc3cb74SMauro Carvalho Chehab /* some arrays for pretty-printing debug messages of enum types      */
1295bc3cb74SMauro Carvalho Chehab 
1305bc3cb74SMauro Carvalho Chehab const char *v4l2_field_names[] = {
1315bc3cb74SMauro Carvalho Chehab 	[V4L2_FIELD_ANY]        = "any",
1325bc3cb74SMauro Carvalho Chehab 	[V4L2_FIELD_NONE]       = "none",
1335bc3cb74SMauro Carvalho Chehab 	[V4L2_FIELD_TOP]        = "top",
1345bc3cb74SMauro Carvalho Chehab 	[V4L2_FIELD_BOTTOM]     = "bottom",
1355bc3cb74SMauro Carvalho Chehab 	[V4L2_FIELD_INTERLACED] = "interlaced",
1365bc3cb74SMauro Carvalho Chehab 	[V4L2_FIELD_SEQ_TB]     = "seq-tb",
1375bc3cb74SMauro Carvalho Chehab 	[V4L2_FIELD_SEQ_BT]     = "seq-bt",
1385bc3cb74SMauro Carvalho Chehab 	[V4L2_FIELD_ALTERNATE]  = "alternate",
1395bc3cb74SMauro Carvalho Chehab 	[V4L2_FIELD_INTERLACED_TB] = "interlaced-tb",
1405bc3cb74SMauro Carvalho Chehab 	[V4L2_FIELD_INTERLACED_BT] = "interlaced-bt",
1415bc3cb74SMauro Carvalho Chehab };
1425bc3cb74SMauro Carvalho Chehab EXPORT_SYMBOL(v4l2_field_names);
1435bc3cb74SMauro Carvalho Chehab 
1445bc3cb74SMauro Carvalho Chehab const char *v4l2_type_names[] = {
145839aa56dSHans Verkuil 	[0]				   = "0",
1465bc3cb74SMauro Carvalho Chehab 	[V4L2_BUF_TYPE_VIDEO_CAPTURE]      = "vid-cap",
1475bc3cb74SMauro Carvalho Chehab 	[V4L2_BUF_TYPE_VIDEO_OVERLAY]      = "vid-overlay",
1485bc3cb74SMauro Carvalho Chehab 	[V4L2_BUF_TYPE_VIDEO_OUTPUT]       = "vid-out",
1495bc3cb74SMauro Carvalho Chehab 	[V4L2_BUF_TYPE_VBI_CAPTURE]        = "vbi-cap",
1505bc3cb74SMauro Carvalho Chehab 	[V4L2_BUF_TYPE_VBI_OUTPUT]         = "vbi-out",
1515bc3cb74SMauro Carvalho Chehab 	[V4L2_BUF_TYPE_SLICED_VBI_CAPTURE] = "sliced-vbi-cap",
1525bc3cb74SMauro Carvalho Chehab 	[V4L2_BUF_TYPE_SLICED_VBI_OUTPUT]  = "sliced-vbi-out",
1535bc3cb74SMauro Carvalho Chehab 	[V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY] = "vid-out-overlay",
1545bc3cb74SMauro Carvalho Chehab 	[V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE] = "vid-cap-mplane",
1555bc3cb74SMauro Carvalho Chehab 	[V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE] = "vid-out-mplane",
1566f3073b8SAntti Palosaari 	[V4L2_BUF_TYPE_SDR_CAPTURE]        = "sdr-cap",
1579effc72fSAntti Palosaari 	[V4L2_BUF_TYPE_SDR_OUTPUT]         = "sdr-out",
1585bc3cb74SMauro Carvalho Chehab };
1595bc3cb74SMauro Carvalho Chehab EXPORT_SYMBOL(v4l2_type_names);
1605bc3cb74SMauro Carvalho Chehab 
1615bc3cb74SMauro Carvalho Chehab static const char *v4l2_memory_names[] = {
1625bc3cb74SMauro Carvalho Chehab 	[V4L2_MEMORY_MMAP]    = "mmap",
1635bc3cb74SMauro Carvalho Chehab 	[V4L2_MEMORY_USERPTR] = "userptr",
1645bc3cb74SMauro Carvalho Chehab 	[V4L2_MEMORY_OVERLAY] = "overlay",
165051c7788SSumit Semwal 	[V4L2_MEMORY_DMABUF] = "dmabuf",
1665bc3cb74SMauro Carvalho Chehab };
1675bc3cb74SMauro Carvalho Chehab 
168d9246240SHans Verkuil #define prt_names(a, arr) (((unsigned)(a)) < ARRAY_SIZE(arr) ? arr[a] : "unknown")
1695bc3cb74SMauro Carvalho Chehab 
1705bc3cb74SMauro Carvalho Chehab /* ------------------------------------------------------------------ */
1715bc3cb74SMauro Carvalho Chehab /* debug help functions                                               */
1725bc3cb74SMauro Carvalho Chehab 
1735bc3cb74SMauro Carvalho Chehab static void v4l_print_querycap(const void *arg, bool write_only)
1745bc3cb74SMauro Carvalho Chehab {
1755bc3cb74SMauro Carvalho Chehab 	const struct v4l2_capability *p = arg;
1765bc3cb74SMauro Carvalho Chehab 
17727d5a87cSHans Verkuil 	pr_cont("driver=%.*s, card=%.*s, bus=%.*s, version=0x%08x, "
1785bc3cb74SMauro Carvalho Chehab 		"capabilities=0x%08x, device_caps=0x%08x\n",
17927d5a87cSHans Verkuil 		(int)sizeof(p->driver), p->driver,
18027d5a87cSHans Verkuil 		(int)sizeof(p->card), p->card,
18127d5a87cSHans Verkuil 		(int)sizeof(p->bus_info), p->bus_info,
1825bc3cb74SMauro Carvalho Chehab 		p->version, p->capabilities, p->device_caps);
1835bc3cb74SMauro Carvalho Chehab }
1845bc3cb74SMauro Carvalho Chehab 
1855bc3cb74SMauro Carvalho Chehab static void v4l_print_enuminput(const void *arg, bool write_only)
1865bc3cb74SMauro Carvalho Chehab {
1875bc3cb74SMauro Carvalho Chehab 	const struct v4l2_input *p = arg;
1885bc3cb74SMauro Carvalho Chehab 
18927d5a87cSHans Verkuil 	pr_cont("index=%u, name=%.*s, type=%u, audioset=0x%x, tuner=%u, "
1905bc3cb74SMauro Carvalho Chehab 		"std=0x%08Lx, status=0x%x, capabilities=0x%x\n",
19127d5a87cSHans Verkuil 		p->index, (int)sizeof(p->name), p->name, p->type, p->audioset,
19227d5a87cSHans Verkuil 		p->tuner, (unsigned long long)p->std, p->status,
19327d5a87cSHans Verkuil 		p->capabilities);
1945bc3cb74SMauro Carvalho Chehab }
1955bc3cb74SMauro Carvalho Chehab 
1965bc3cb74SMauro Carvalho Chehab static void v4l_print_enumoutput(const void *arg, bool write_only)
1975bc3cb74SMauro Carvalho Chehab {
1985bc3cb74SMauro Carvalho Chehab 	const struct v4l2_output *p = arg;
1995bc3cb74SMauro Carvalho Chehab 
20027d5a87cSHans Verkuil 	pr_cont("index=%u, name=%.*s, type=%u, audioset=0x%x, "
2015bc3cb74SMauro Carvalho Chehab 		"modulator=%u, std=0x%08Lx, capabilities=0x%x\n",
20227d5a87cSHans Verkuil 		p->index, (int)sizeof(p->name), p->name, p->type, p->audioset,
20327d5a87cSHans Verkuil 		p->modulator, (unsigned long long)p->std, p->capabilities);
2045bc3cb74SMauro Carvalho Chehab }
2055bc3cb74SMauro Carvalho Chehab 
2065bc3cb74SMauro Carvalho Chehab static void v4l_print_audio(const void *arg, bool write_only)
2075bc3cb74SMauro Carvalho Chehab {
2085bc3cb74SMauro Carvalho Chehab 	const struct v4l2_audio *p = arg;
2095bc3cb74SMauro Carvalho Chehab 
2105bc3cb74SMauro Carvalho Chehab 	if (write_only)
2115bc3cb74SMauro Carvalho Chehab 		pr_cont("index=%u, mode=0x%x\n", p->index, p->mode);
2125bc3cb74SMauro Carvalho Chehab 	else
21327d5a87cSHans Verkuil 		pr_cont("index=%u, name=%.*s, capability=0x%x, mode=0x%x\n",
21427d5a87cSHans Verkuil 			p->index, (int)sizeof(p->name), p->name,
21527d5a87cSHans Verkuil 			p->capability, p->mode);
2165bc3cb74SMauro Carvalho Chehab }
2175bc3cb74SMauro Carvalho Chehab 
2185bc3cb74SMauro Carvalho Chehab static void v4l_print_audioout(const void *arg, bool write_only)
2195bc3cb74SMauro Carvalho Chehab {
2205bc3cb74SMauro Carvalho Chehab 	const struct v4l2_audioout *p = arg;
2215bc3cb74SMauro Carvalho Chehab 
2225bc3cb74SMauro Carvalho Chehab 	if (write_only)
2235bc3cb74SMauro Carvalho Chehab 		pr_cont("index=%u\n", p->index);
2245bc3cb74SMauro Carvalho Chehab 	else
22527d5a87cSHans Verkuil 		pr_cont("index=%u, name=%.*s, capability=0x%x, mode=0x%x\n",
22627d5a87cSHans Verkuil 			p->index, (int)sizeof(p->name), p->name,
22727d5a87cSHans Verkuil 			p->capability, p->mode);
2285bc3cb74SMauro Carvalho Chehab }
2295bc3cb74SMauro Carvalho Chehab 
2305bc3cb74SMauro Carvalho Chehab static void v4l_print_fmtdesc(const void *arg, bool write_only)
2315bc3cb74SMauro Carvalho Chehab {
2325bc3cb74SMauro Carvalho Chehab 	const struct v4l2_fmtdesc *p = arg;
2335bc3cb74SMauro Carvalho Chehab 
23427d5a87cSHans Verkuil 	pr_cont("index=%u, type=%s, flags=0x%x, pixelformat=%c%c%c%c, description='%.*s'\n",
2355bc3cb74SMauro Carvalho Chehab 		p->index, prt_names(p->type, v4l2_type_names),
2365bc3cb74SMauro Carvalho Chehab 		p->flags, (p->pixelformat & 0xff),
2375bc3cb74SMauro Carvalho Chehab 		(p->pixelformat >>  8) & 0xff,
2385bc3cb74SMauro Carvalho Chehab 		(p->pixelformat >> 16) & 0xff,
2395bc3cb74SMauro Carvalho Chehab 		(p->pixelformat >> 24) & 0xff,
24027d5a87cSHans Verkuil 		(int)sizeof(p->description), p->description);
2415bc3cb74SMauro Carvalho Chehab }
2425bc3cb74SMauro Carvalho Chehab 
2435bc3cb74SMauro Carvalho Chehab static void v4l_print_format(const void *arg, bool write_only)
2445bc3cb74SMauro Carvalho Chehab {
2455bc3cb74SMauro Carvalho Chehab 	const struct v4l2_format *p = arg;
2465bc3cb74SMauro Carvalho Chehab 	const struct v4l2_pix_format *pix;
2475bc3cb74SMauro Carvalho Chehab 	const struct v4l2_pix_format_mplane *mp;
2485bc3cb74SMauro Carvalho Chehab 	const struct v4l2_vbi_format *vbi;
2495bc3cb74SMauro Carvalho Chehab 	const struct v4l2_sliced_vbi_format *sliced;
2505bc3cb74SMauro Carvalho Chehab 	const struct v4l2_window *win;
25187185c95SAntti Palosaari 	const struct v4l2_sdr_format *sdr;
2525bc3cb74SMauro Carvalho Chehab 	unsigned i;
2535bc3cb74SMauro Carvalho Chehab 
2545bc3cb74SMauro Carvalho Chehab 	pr_cont("type=%s", prt_names(p->type, v4l2_type_names));
2555bc3cb74SMauro Carvalho Chehab 	switch (p->type) {
2565bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_CAPTURE:
2575bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_OUTPUT:
2585bc3cb74SMauro Carvalho Chehab 		pix = &p->fmt.pix;
2595bc3cb74SMauro Carvalho Chehab 		pr_cont(", width=%u, height=%u, "
2605bc3cb74SMauro Carvalho Chehab 			"pixelformat=%c%c%c%c, field=%s, "
261c96fd46aSLaurent Pinchart 			"bytesperline=%u, sizeimage=%u, colorspace=%d, "
26274fdcb2eSHans Verkuil 			"flags=0x%x, ycbcr_enc=%u, quantization=%u, "
26374fdcb2eSHans Verkuil 			"xfer_func=%u\n",
2645bc3cb74SMauro Carvalho Chehab 			pix->width, pix->height,
2655bc3cb74SMauro Carvalho Chehab 			(pix->pixelformat & 0xff),
2665bc3cb74SMauro Carvalho Chehab 			(pix->pixelformat >>  8) & 0xff,
2675bc3cb74SMauro Carvalho Chehab 			(pix->pixelformat >> 16) & 0xff,
2685bc3cb74SMauro Carvalho Chehab 			(pix->pixelformat >> 24) & 0xff,
2695bc3cb74SMauro Carvalho Chehab 			prt_names(pix->field, v4l2_field_names),
2705bc3cb74SMauro Carvalho Chehab 			pix->bytesperline, pix->sizeimage,
271736d96b5SHans Verkuil 			pix->colorspace, pix->flags, pix->ycbcr_enc,
27274fdcb2eSHans Verkuil 			pix->quantization, pix->xfer_func);
2735bc3cb74SMauro Carvalho Chehab 		break;
2745bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
2755bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
2765bc3cb74SMauro Carvalho Chehab 		mp = &p->fmt.pix_mp;
2775bc3cb74SMauro Carvalho Chehab 		pr_cont(", width=%u, height=%u, "
2785bc3cb74SMauro Carvalho Chehab 			"format=%c%c%c%c, field=%s, "
2791e8faa59SHans Verkuil 			"colorspace=%d, num_planes=%u, flags=0x%x, "
28074fdcb2eSHans Verkuil 			"ycbcr_enc=%u, quantization=%u, xfer_func=%u\n",
2815bc3cb74SMauro Carvalho Chehab 			mp->width, mp->height,
2825bc3cb74SMauro Carvalho Chehab 			(mp->pixelformat & 0xff),
2835bc3cb74SMauro Carvalho Chehab 			(mp->pixelformat >>  8) & 0xff,
2845bc3cb74SMauro Carvalho Chehab 			(mp->pixelformat >> 16) & 0xff,
2855bc3cb74SMauro Carvalho Chehab 			(mp->pixelformat >> 24) & 0xff,
2865bc3cb74SMauro Carvalho Chehab 			prt_names(mp->field, v4l2_field_names),
287736d96b5SHans Verkuil 			mp->colorspace, mp->num_planes, mp->flags,
28874fdcb2eSHans Verkuil 			mp->ycbcr_enc, mp->quantization, mp->xfer_func);
2895bc3cb74SMauro Carvalho Chehab 		for (i = 0; i < mp->num_planes; i++)
2905bc3cb74SMauro Carvalho Chehab 			printk(KERN_DEBUG "plane %u: bytesperline=%u sizeimage=%u\n", i,
2915bc3cb74SMauro Carvalho Chehab 					mp->plane_fmt[i].bytesperline,
2925bc3cb74SMauro Carvalho Chehab 					mp->plane_fmt[i].sizeimage);
2935bc3cb74SMauro Carvalho Chehab 		break;
2945bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_OVERLAY:
2955bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
2965bc3cb74SMauro Carvalho Chehab 		win = &p->fmt.win;
297560dde24SHans Verkuil 		/* Note: we can't print the clip list here since the clips
298560dde24SHans Verkuil 		 * pointer is a userspace pointer, not a kernelspace
299560dde24SHans Verkuil 		 * pointer. */
300560dde24SHans 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",
301560dde24SHans Verkuil 			win->w.width, win->w.height, win->w.left, win->w.top,
3025bc3cb74SMauro Carvalho Chehab 			prt_names(win->field, v4l2_field_names),
303560dde24SHans Verkuil 			win->chromakey, win->clipcount, win->clips,
304560dde24SHans Verkuil 			win->bitmap, win->global_alpha);
3055bc3cb74SMauro Carvalho Chehab 		break;
3065bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VBI_CAPTURE:
3075bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VBI_OUTPUT:
3085bc3cb74SMauro Carvalho Chehab 		vbi = &p->fmt.vbi;
3095bc3cb74SMauro Carvalho Chehab 		pr_cont(", sampling_rate=%u, offset=%u, samples_per_line=%u, "
3105bc3cb74SMauro Carvalho Chehab 			"sample_format=%c%c%c%c, start=%u,%u, count=%u,%u\n",
3115bc3cb74SMauro Carvalho Chehab 			vbi->sampling_rate, vbi->offset,
3125bc3cb74SMauro Carvalho Chehab 			vbi->samples_per_line,
3135bc3cb74SMauro Carvalho Chehab 			(vbi->sample_format & 0xff),
3145bc3cb74SMauro Carvalho Chehab 			(vbi->sample_format >>  8) & 0xff,
3155bc3cb74SMauro Carvalho Chehab 			(vbi->sample_format >> 16) & 0xff,
3165bc3cb74SMauro Carvalho Chehab 			(vbi->sample_format >> 24) & 0xff,
3175bc3cb74SMauro Carvalho Chehab 			vbi->start[0], vbi->start[1],
3185bc3cb74SMauro Carvalho Chehab 			vbi->count[0], vbi->count[1]);
3195bc3cb74SMauro Carvalho Chehab 		break;
3205bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
3215bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
3225bc3cb74SMauro Carvalho Chehab 		sliced = &p->fmt.sliced;
3235bc3cb74SMauro Carvalho Chehab 		pr_cont(", service_set=0x%08x, io_size=%d\n",
3245bc3cb74SMauro Carvalho Chehab 				sliced->service_set, sliced->io_size);
3255bc3cb74SMauro Carvalho Chehab 		for (i = 0; i < 24; i++)
3265bc3cb74SMauro Carvalho Chehab 			printk(KERN_DEBUG "line[%02u]=0x%04x, 0x%04x\n", i,
3275bc3cb74SMauro Carvalho Chehab 				sliced->service_lines[0][i],
3285bc3cb74SMauro Carvalho Chehab 				sliced->service_lines[1][i]);
3295bc3cb74SMauro Carvalho Chehab 		break;
330582c52cbSAntti Palosaari 	case V4L2_BUF_TYPE_SDR_CAPTURE:
3319effc72fSAntti Palosaari 	case V4L2_BUF_TYPE_SDR_OUTPUT:
332582c52cbSAntti Palosaari 		sdr = &p->fmt.sdr;
333582c52cbSAntti Palosaari 		pr_cont(", pixelformat=%c%c%c%c\n",
334582c52cbSAntti Palosaari 			(sdr->pixelformat >>  0) & 0xff,
335582c52cbSAntti Palosaari 			(sdr->pixelformat >>  8) & 0xff,
336582c52cbSAntti Palosaari 			(sdr->pixelformat >> 16) & 0xff,
337582c52cbSAntti Palosaari 			(sdr->pixelformat >> 24) & 0xff);
338582c52cbSAntti Palosaari 		break;
3395bc3cb74SMauro Carvalho Chehab 	}
3405bc3cb74SMauro Carvalho Chehab }
3415bc3cb74SMauro Carvalho Chehab 
3425bc3cb74SMauro Carvalho Chehab static void v4l_print_framebuffer(const void *arg, bool write_only)
3435bc3cb74SMauro Carvalho Chehab {
3445bc3cb74SMauro Carvalho Chehab 	const struct v4l2_framebuffer *p = arg;
3455bc3cb74SMauro Carvalho Chehab 
3465bc3cb74SMauro Carvalho Chehab 	pr_cont("capability=0x%x, flags=0x%x, base=0x%p, width=%u, "
3475bc3cb74SMauro Carvalho Chehab 		"height=%u, pixelformat=%c%c%c%c, "
348560dde24SHans Verkuil 		"bytesperline=%u, sizeimage=%u, colorspace=%d\n",
3495bc3cb74SMauro Carvalho Chehab 			p->capability, p->flags, p->base,
3505bc3cb74SMauro Carvalho Chehab 			p->fmt.width, p->fmt.height,
3515bc3cb74SMauro Carvalho Chehab 			(p->fmt.pixelformat & 0xff),
3525bc3cb74SMauro Carvalho Chehab 			(p->fmt.pixelformat >>  8) & 0xff,
3535bc3cb74SMauro Carvalho Chehab 			(p->fmt.pixelformat >> 16) & 0xff,
3545bc3cb74SMauro Carvalho Chehab 			(p->fmt.pixelformat >> 24) & 0xff,
3555bc3cb74SMauro Carvalho Chehab 			p->fmt.bytesperline, p->fmt.sizeimage,
3565bc3cb74SMauro Carvalho Chehab 			p->fmt.colorspace);
3575bc3cb74SMauro Carvalho Chehab }
3585bc3cb74SMauro Carvalho Chehab 
3595bc3cb74SMauro Carvalho Chehab static void v4l_print_buftype(const void *arg, bool write_only)
3605bc3cb74SMauro Carvalho Chehab {
3615bc3cb74SMauro Carvalho Chehab 	pr_cont("type=%s\n", prt_names(*(u32 *)arg, v4l2_type_names));
3625bc3cb74SMauro Carvalho Chehab }
3635bc3cb74SMauro Carvalho Chehab 
3645bc3cb74SMauro Carvalho Chehab static void v4l_print_modulator(const void *arg, bool write_only)
3655bc3cb74SMauro Carvalho Chehab {
3665bc3cb74SMauro Carvalho Chehab 	const struct v4l2_modulator *p = arg;
3675bc3cb74SMauro Carvalho Chehab 
3685bc3cb74SMauro Carvalho Chehab 	if (write_only)
369560dde24SHans Verkuil 		pr_cont("index=%u, txsubchans=0x%x\n", p->index, p->txsubchans);
3705bc3cb74SMauro Carvalho Chehab 	else
37127d5a87cSHans Verkuil 		pr_cont("index=%u, name=%.*s, capability=0x%x, "
3725bc3cb74SMauro Carvalho Chehab 			"rangelow=%u, rangehigh=%u, txsubchans=0x%x\n",
37327d5a87cSHans Verkuil 			p->index, (int)sizeof(p->name), p->name, p->capability,
3745bc3cb74SMauro Carvalho Chehab 			p->rangelow, p->rangehigh, p->txsubchans);
3755bc3cb74SMauro Carvalho Chehab }
3765bc3cb74SMauro Carvalho Chehab 
3775bc3cb74SMauro Carvalho Chehab static void v4l_print_tuner(const void *arg, bool write_only)
3785bc3cb74SMauro Carvalho Chehab {
3795bc3cb74SMauro Carvalho Chehab 	const struct v4l2_tuner *p = arg;
3805bc3cb74SMauro Carvalho Chehab 
3815bc3cb74SMauro Carvalho Chehab 	if (write_only)
3825bc3cb74SMauro Carvalho Chehab 		pr_cont("index=%u, audmode=%u\n", p->index, p->audmode);
3835bc3cb74SMauro Carvalho Chehab 	else
38427d5a87cSHans Verkuil 		pr_cont("index=%u, name=%.*s, type=%u, capability=0x%x, "
3855bc3cb74SMauro Carvalho Chehab 			"rangelow=%u, rangehigh=%u, signal=%u, afc=%d, "
3865bc3cb74SMauro Carvalho Chehab 			"rxsubchans=0x%x, audmode=%u\n",
38727d5a87cSHans Verkuil 			p->index, (int)sizeof(p->name), p->name, p->type,
3885bc3cb74SMauro Carvalho Chehab 			p->capability, p->rangelow,
3895bc3cb74SMauro Carvalho Chehab 			p->rangehigh, p->signal, p->afc,
3905bc3cb74SMauro Carvalho Chehab 			p->rxsubchans, p->audmode);
3915bc3cb74SMauro Carvalho Chehab }
3925bc3cb74SMauro Carvalho Chehab 
3935bc3cb74SMauro Carvalho Chehab static void v4l_print_frequency(const void *arg, bool write_only)
3945bc3cb74SMauro Carvalho Chehab {
3955bc3cb74SMauro Carvalho Chehab 	const struct v4l2_frequency *p = arg;
3965bc3cb74SMauro Carvalho Chehab 
3975bc3cb74SMauro Carvalho Chehab 	pr_cont("tuner=%u, type=%u, frequency=%u\n",
3985bc3cb74SMauro Carvalho Chehab 				p->tuner, p->type, p->frequency);
3995bc3cb74SMauro Carvalho Chehab }
4005bc3cb74SMauro Carvalho Chehab 
4015bc3cb74SMauro Carvalho Chehab static void v4l_print_standard(const void *arg, bool write_only)
4025bc3cb74SMauro Carvalho Chehab {
4035bc3cb74SMauro Carvalho Chehab 	const struct v4l2_standard *p = arg;
4045bc3cb74SMauro Carvalho Chehab 
40527d5a87cSHans Verkuil 	pr_cont("index=%u, id=0x%Lx, name=%.*s, fps=%u/%u, "
4065bc3cb74SMauro Carvalho Chehab 		"framelines=%u\n", p->index,
40727d5a87cSHans Verkuil 		(unsigned long long)p->id, (int)sizeof(p->name), p->name,
4085bc3cb74SMauro Carvalho Chehab 		p->frameperiod.numerator,
4095bc3cb74SMauro Carvalho Chehab 		p->frameperiod.denominator,
4105bc3cb74SMauro Carvalho Chehab 		p->framelines);
4115bc3cb74SMauro Carvalho Chehab }
4125bc3cb74SMauro Carvalho Chehab 
4135bc3cb74SMauro Carvalho Chehab static void v4l_print_std(const void *arg, bool write_only)
4145bc3cb74SMauro Carvalho Chehab {
4155bc3cb74SMauro Carvalho Chehab 	pr_cont("std=0x%08Lx\n", *(const long long unsigned *)arg);
4165bc3cb74SMauro Carvalho Chehab }
4175bc3cb74SMauro Carvalho Chehab 
4185bc3cb74SMauro Carvalho Chehab static void v4l_print_hw_freq_seek(const void *arg, bool write_only)
4195bc3cb74SMauro Carvalho Chehab {
4205bc3cb74SMauro Carvalho Chehab 	const struct v4l2_hw_freq_seek *p = arg;
4215bc3cb74SMauro Carvalho Chehab 
42279e8c7beSMauro Carvalho Chehab 	pr_cont("tuner=%u, type=%u, seek_upward=%u, wrap_around=%u, spacing=%u, "
42379e8c7beSMauro Carvalho Chehab 		"rangelow=%u, rangehigh=%u\n",
42479e8c7beSMauro Carvalho Chehab 		p->tuner, p->type, p->seek_upward, p->wrap_around, p->spacing,
42579e8c7beSMauro Carvalho Chehab 		p->rangelow, p->rangehigh);
4265bc3cb74SMauro Carvalho Chehab }
4275bc3cb74SMauro Carvalho Chehab 
4285bc3cb74SMauro Carvalho Chehab static void v4l_print_requestbuffers(const void *arg, bool write_only)
4295bc3cb74SMauro Carvalho Chehab {
4305bc3cb74SMauro Carvalho Chehab 	const struct v4l2_requestbuffers *p = arg;
4315bc3cb74SMauro Carvalho Chehab 
4325bc3cb74SMauro Carvalho Chehab 	pr_cont("count=%d, type=%s, memory=%s\n",
4335bc3cb74SMauro Carvalho Chehab 		p->count,
4345bc3cb74SMauro Carvalho Chehab 		prt_names(p->type, v4l2_type_names),
4355bc3cb74SMauro Carvalho Chehab 		prt_names(p->memory, v4l2_memory_names));
4365bc3cb74SMauro Carvalho Chehab }
4375bc3cb74SMauro Carvalho Chehab 
4385bc3cb74SMauro Carvalho Chehab static void v4l_print_buffer(const void *arg, bool write_only)
4395bc3cb74SMauro Carvalho Chehab {
4405bc3cb74SMauro Carvalho Chehab 	const struct v4l2_buffer *p = arg;
4415bc3cb74SMauro Carvalho Chehab 	const struct v4l2_timecode *tc = &p->timecode;
4425bc3cb74SMauro Carvalho Chehab 	const struct v4l2_plane *plane;
4435bc3cb74SMauro Carvalho Chehab 	int i;
4445bc3cb74SMauro Carvalho Chehab 
4455bc3cb74SMauro Carvalho Chehab 	pr_cont("%02ld:%02d:%02d.%08ld index=%d, type=%s, "
4465bc3cb74SMauro Carvalho Chehab 		"flags=0x%08x, field=%s, sequence=%d, memory=%s",
4475bc3cb74SMauro Carvalho Chehab 			p->timestamp.tv_sec / 3600,
4485bc3cb74SMauro Carvalho Chehab 			(int)(p->timestamp.tv_sec / 60) % 60,
4495bc3cb74SMauro Carvalho Chehab 			(int)(p->timestamp.tv_sec % 60),
4505bc3cb74SMauro Carvalho Chehab 			(long)p->timestamp.tv_usec,
4515bc3cb74SMauro Carvalho Chehab 			p->index,
4525bc3cb74SMauro Carvalho Chehab 			prt_names(p->type, v4l2_type_names),
4535bc3cb74SMauro Carvalho Chehab 			p->flags, prt_names(p->field, v4l2_field_names),
4545bc3cb74SMauro Carvalho Chehab 			p->sequence, prt_names(p->memory, v4l2_memory_names));
4555bc3cb74SMauro Carvalho Chehab 
4565bc3cb74SMauro Carvalho Chehab 	if (V4L2_TYPE_IS_MULTIPLANAR(p->type) && p->m.planes) {
4575bc3cb74SMauro Carvalho Chehab 		pr_cont("\n");
4585bc3cb74SMauro Carvalho Chehab 		for (i = 0; i < p->length; ++i) {
4595bc3cb74SMauro Carvalho Chehab 			plane = &p->m.planes[i];
4605bc3cb74SMauro Carvalho Chehab 			printk(KERN_DEBUG
461560dde24SHans Verkuil 				"plane %d: bytesused=%d, data_offset=0x%08x, "
4625bc3cb74SMauro Carvalho Chehab 				"offset/userptr=0x%lx, length=%d\n",
4635bc3cb74SMauro Carvalho Chehab 				i, plane->bytesused, plane->data_offset,
4645bc3cb74SMauro Carvalho Chehab 				plane->m.userptr, plane->length);
4655bc3cb74SMauro Carvalho Chehab 		}
4665bc3cb74SMauro Carvalho Chehab 	} else {
467560dde24SHans Verkuil 		pr_cont(", bytesused=%d, offset/userptr=0x%lx, length=%d\n",
4685bc3cb74SMauro Carvalho Chehab 			p->bytesused, p->m.userptr, p->length);
4695bc3cb74SMauro Carvalho Chehab 	}
4705bc3cb74SMauro Carvalho Chehab 
4715bc3cb74SMauro Carvalho Chehab 	printk(KERN_DEBUG "timecode=%02d:%02d:%02d type=%d, "
4725bc3cb74SMauro Carvalho Chehab 		"flags=0x%08x, frames=%d, userbits=0x%08x\n",
4735bc3cb74SMauro Carvalho Chehab 			tc->hours, tc->minutes, tc->seconds,
4745bc3cb74SMauro Carvalho Chehab 			tc->type, tc->flags, tc->frames, *(__u32 *)tc->userbits);
4755bc3cb74SMauro Carvalho Chehab }
4765bc3cb74SMauro Carvalho Chehab 
477b799d09aSTomasz Stanislawski static void v4l_print_exportbuffer(const void *arg, bool write_only)
478b799d09aSTomasz Stanislawski {
479b799d09aSTomasz Stanislawski 	const struct v4l2_exportbuffer *p = arg;
480b799d09aSTomasz Stanislawski 
481b799d09aSTomasz Stanislawski 	pr_cont("fd=%d, type=%s, index=%u, plane=%u, flags=0x%08x\n",
482b799d09aSTomasz Stanislawski 		p->fd, prt_names(p->type, v4l2_type_names),
483b799d09aSTomasz Stanislawski 		p->index, p->plane, p->flags);
484b799d09aSTomasz Stanislawski }
485b799d09aSTomasz Stanislawski 
4865bc3cb74SMauro Carvalho Chehab static void v4l_print_create_buffers(const void *arg, bool write_only)
4875bc3cb74SMauro Carvalho Chehab {
4885bc3cb74SMauro Carvalho Chehab 	const struct v4l2_create_buffers *p = arg;
4895bc3cb74SMauro Carvalho Chehab 
4905bc3cb74SMauro Carvalho Chehab 	pr_cont("index=%d, count=%d, memory=%s, ",
4915bc3cb74SMauro Carvalho Chehab 			p->index, p->count,
4925bc3cb74SMauro Carvalho Chehab 			prt_names(p->memory, v4l2_memory_names));
4935bc3cb74SMauro Carvalho Chehab 	v4l_print_format(&p->format, write_only);
4945bc3cb74SMauro Carvalho Chehab }
4955bc3cb74SMauro Carvalho Chehab 
4965bc3cb74SMauro Carvalho Chehab static void v4l_print_streamparm(const void *arg, bool write_only)
4975bc3cb74SMauro Carvalho Chehab {
4985bc3cb74SMauro Carvalho Chehab 	const struct v4l2_streamparm *p = arg;
4995bc3cb74SMauro Carvalho Chehab 
5005bc3cb74SMauro Carvalho Chehab 	pr_cont("type=%s", prt_names(p->type, v4l2_type_names));
5015bc3cb74SMauro Carvalho Chehab 
5025bc3cb74SMauro Carvalho Chehab 	if (p->type == V4L2_BUF_TYPE_VIDEO_CAPTURE ||
5035bc3cb74SMauro Carvalho Chehab 	    p->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
5045bc3cb74SMauro Carvalho Chehab 		const struct v4l2_captureparm *c = &p->parm.capture;
5055bc3cb74SMauro Carvalho Chehab 
5065bc3cb74SMauro Carvalho Chehab 		pr_cont(", capability=0x%x, capturemode=0x%x, timeperframe=%d/%d, "
5075bc3cb74SMauro Carvalho Chehab 			"extendedmode=%d, readbuffers=%d\n",
5085bc3cb74SMauro Carvalho Chehab 			c->capability, c->capturemode,
5095bc3cb74SMauro Carvalho Chehab 			c->timeperframe.numerator, c->timeperframe.denominator,
5105bc3cb74SMauro Carvalho Chehab 			c->extendedmode, c->readbuffers);
5115bc3cb74SMauro Carvalho Chehab 	} else if (p->type == V4L2_BUF_TYPE_VIDEO_OUTPUT ||
5125bc3cb74SMauro Carvalho Chehab 		   p->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
5135bc3cb74SMauro Carvalho Chehab 		const struct v4l2_outputparm *c = &p->parm.output;
5145bc3cb74SMauro Carvalho Chehab 
5155bc3cb74SMauro Carvalho Chehab 		pr_cont(", capability=0x%x, outputmode=0x%x, timeperframe=%d/%d, "
5165bc3cb74SMauro Carvalho Chehab 			"extendedmode=%d, writebuffers=%d\n",
5175bc3cb74SMauro Carvalho Chehab 			c->capability, c->outputmode,
5185bc3cb74SMauro Carvalho Chehab 			c->timeperframe.numerator, c->timeperframe.denominator,
5195bc3cb74SMauro Carvalho Chehab 			c->extendedmode, c->writebuffers);
520560dde24SHans Verkuil 	} else {
521560dde24SHans Verkuil 		pr_cont("\n");
5225bc3cb74SMauro Carvalho Chehab 	}
5235bc3cb74SMauro Carvalho Chehab }
5245bc3cb74SMauro Carvalho Chehab 
5255bc3cb74SMauro Carvalho Chehab static void v4l_print_queryctrl(const void *arg, bool write_only)
5265bc3cb74SMauro Carvalho Chehab {
5275bc3cb74SMauro Carvalho Chehab 	const struct v4l2_queryctrl *p = arg;
5285bc3cb74SMauro Carvalho Chehab 
52927d5a87cSHans Verkuil 	pr_cont("id=0x%x, type=%d, name=%.*s, min/max=%d/%d, "
5305bc3cb74SMauro Carvalho Chehab 		"step=%d, default=%d, flags=0x%08x\n",
53127d5a87cSHans Verkuil 			p->id, p->type, (int)sizeof(p->name), p->name,
5325bc3cb74SMauro Carvalho Chehab 			p->minimum, p->maximum,
5335bc3cb74SMauro Carvalho Chehab 			p->step, p->default_value, p->flags);
5345bc3cb74SMauro Carvalho Chehab }
5355bc3cb74SMauro Carvalho Chehab 
536e6bee368SHans Verkuil static void v4l_print_query_ext_ctrl(const void *arg, bool write_only)
537e6bee368SHans Verkuil {
538e6bee368SHans Verkuil 	const struct v4l2_query_ext_ctrl *p = arg;
539e6bee368SHans Verkuil 
540e6bee368SHans Verkuil 	pr_cont("id=0x%x, type=%d, name=%.*s, min/max=%lld/%lld, "
541e6bee368SHans Verkuil 		"step=%lld, default=%lld, flags=0x%08x, elem_size=%u, elems=%u, "
5420176077aSHans Verkuil 		"nr_of_dims=%u, dims=%u,%u,%u,%u\n",
543e6bee368SHans Verkuil 			p->id, p->type, (int)sizeof(p->name), p->name,
544e6bee368SHans Verkuil 			p->minimum, p->maximum,
545e6bee368SHans Verkuil 			p->step, p->default_value, p->flags,
546e6bee368SHans Verkuil 			p->elem_size, p->elems, p->nr_of_dims,
5470176077aSHans Verkuil 			p->dims[0], p->dims[1], p->dims[2], p->dims[3]);
548e6bee368SHans Verkuil }
549e6bee368SHans Verkuil 
5505bc3cb74SMauro Carvalho Chehab static void v4l_print_querymenu(const void *arg, bool write_only)
5515bc3cb74SMauro Carvalho Chehab {
5525bc3cb74SMauro Carvalho Chehab 	const struct v4l2_querymenu *p = arg;
5535bc3cb74SMauro Carvalho Chehab 
5545bc3cb74SMauro Carvalho Chehab 	pr_cont("id=0x%x, index=%d\n", p->id, p->index);
5555bc3cb74SMauro Carvalho Chehab }
5565bc3cb74SMauro Carvalho Chehab 
5575bc3cb74SMauro Carvalho Chehab static void v4l_print_control(const void *arg, bool write_only)
5585bc3cb74SMauro Carvalho Chehab {
5595bc3cb74SMauro Carvalho Chehab 	const struct v4l2_control *p = arg;
5605bc3cb74SMauro Carvalho Chehab 
5615bc3cb74SMauro Carvalho Chehab 	pr_cont("id=0x%x, value=%d\n", p->id, p->value);
5625bc3cb74SMauro Carvalho Chehab }
5635bc3cb74SMauro Carvalho Chehab 
5645bc3cb74SMauro Carvalho Chehab static void v4l_print_ext_controls(const void *arg, bool write_only)
5655bc3cb74SMauro Carvalho Chehab {
5665bc3cb74SMauro Carvalho Chehab 	const struct v4l2_ext_controls *p = arg;
5675bc3cb74SMauro Carvalho Chehab 	int i;
5685bc3cb74SMauro Carvalho Chehab 
5690f8017beSRicardo Ribalda 	pr_cont("which=0x%x, count=%d, error_idx=%d",
5700f8017beSRicardo Ribalda 			p->which, p->count, p->error_idx);
5715bc3cb74SMauro Carvalho Chehab 	for (i = 0; i < p->count; i++) {
572017ab36aSHans Verkuil 		if (!p->controls[i].size)
5735bc3cb74SMauro Carvalho Chehab 			pr_cont(", id/val=0x%x/0x%x",
5745bc3cb74SMauro Carvalho Chehab 				p->controls[i].id, p->controls[i].value);
5755bc3cb74SMauro Carvalho Chehab 		else
5765bc3cb74SMauro Carvalho Chehab 			pr_cont(", id/size=0x%x/%u",
5775bc3cb74SMauro Carvalho Chehab 				p->controls[i].id, p->controls[i].size);
5785bc3cb74SMauro Carvalho Chehab 	}
5795bc3cb74SMauro Carvalho Chehab 	pr_cont("\n");
5805bc3cb74SMauro Carvalho Chehab }
5815bc3cb74SMauro Carvalho Chehab 
5825bc3cb74SMauro Carvalho Chehab static void v4l_print_cropcap(const void *arg, bool write_only)
5835bc3cb74SMauro Carvalho Chehab {
5845bc3cb74SMauro Carvalho Chehab 	const struct v4l2_cropcap *p = arg;
5855bc3cb74SMauro Carvalho Chehab 
5865bc3cb74SMauro Carvalho Chehab 	pr_cont("type=%s, bounds wxh=%dx%d, x,y=%d,%d, "
587a112fbafSHans Verkuil 		"defrect wxh=%dx%d, x,y=%d,%d, "
5885bc3cb74SMauro Carvalho Chehab 		"pixelaspect %d/%d\n",
5895bc3cb74SMauro Carvalho Chehab 		prt_names(p->type, v4l2_type_names),
5905bc3cb74SMauro Carvalho Chehab 		p->bounds.width, p->bounds.height,
5915bc3cb74SMauro Carvalho Chehab 		p->bounds.left, p->bounds.top,
5925bc3cb74SMauro Carvalho Chehab 		p->defrect.width, p->defrect.height,
5935bc3cb74SMauro Carvalho Chehab 		p->defrect.left, p->defrect.top,
5945bc3cb74SMauro Carvalho Chehab 		p->pixelaspect.numerator, p->pixelaspect.denominator);
5955bc3cb74SMauro Carvalho Chehab }
5965bc3cb74SMauro Carvalho Chehab 
5975bc3cb74SMauro Carvalho Chehab static void v4l_print_crop(const void *arg, bool write_only)
5985bc3cb74SMauro Carvalho Chehab {
5995bc3cb74SMauro Carvalho Chehab 	const struct v4l2_crop *p = arg;
6005bc3cb74SMauro Carvalho Chehab 
6015bc3cb74SMauro Carvalho Chehab 	pr_cont("type=%s, wxh=%dx%d, x,y=%d,%d\n",
6025bc3cb74SMauro Carvalho Chehab 		prt_names(p->type, v4l2_type_names),
6035bc3cb74SMauro Carvalho Chehab 		p->c.width, p->c.height,
6045bc3cb74SMauro Carvalho Chehab 		p->c.left, p->c.top);
6055bc3cb74SMauro Carvalho Chehab }
6065bc3cb74SMauro Carvalho Chehab 
6075bc3cb74SMauro Carvalho Chehab static void v4l_print_selection(const void *arg, bool write_only)
6085bc3cb74SMauro Carvalho Chehab {
6095bc3cb74SMauro Carvalho Chehab 	const struct v4l2_selection *p = arg;
6105bc3cb74SMauro Carvalho Chehab 
6115bc3cb74SMauro Carvalho Chehab 	pr_cont("type=%s, target=%d, flags=0x%x, wxh=%dx%d, x,y=%d,%d\n",
6125bc3cb74SMauro Carvalho Chehab 		prt_names(p->type, v4l2_type_names),
6135bc3cb74SMauro Carvalho Chehab 		p->target, p->flags,
6145bc3cb74SMauro Carvalho Chehab 		p->r.width, p->r.height, p->r.left, p->r.top);
6155bc3cb74SMauro Carvalho Chehab }
6165bc3cb74SMauro Carvalho Chehab 
6175bc3cb74SMauro Carvalho Chehab static void v4l_print_jpegcompression(const void *arg, bool write_only)
6185bc3cb74SMauro Carvalho Chehab {
6195bc3cb74SMauro Carvalho Chehab 	const struct v4l2_jpegcompression *p = arg;
6205bc3cb74SMauro Carvalho Chehab 
6215bc3cb74SMauro Carvalho Chehab 	pr_cont("quality=%d, APPn=%d, APP_len=%d, "
6225bc3cb74SMauro Carvalho Chehab 		"COM_len=%d, jpeg_markers=0x%x\n",
6235bc3cb74SMauro Carvalho Chehab 		p->quality, p->APPn, p->APP_len,
6245bc3cb74SMauro Carvalho Chehab 		p->COM_len, p->jpeg_markers);
6255bc3cb74SMauro Carvalho Chehab }
6265bc3cb74SMauro Carvalho Chehab 
6275bc3cb74SMauro Carvalho Chehab static void v4l_print_enc_idx(const void *arg, bool write_only)
6285bc3cb74SMauro Carvalho Chehab {
6295bc3cb74SMauro Carvalho Chehab 	const struct v4l2_enc_idx *p = arg;
6305bc3cb74SMauro Carvalho Chehab 
6315bc3cb74SMauro Carvalho Chehab 	pr_cont("entries=%d, entries_cap=%d\n",
6325bc3cb74SMauro Carvalho Chehab 			p->entries, p->entries_cap);
6335bc3cb74SMauro Carvalho Chehab }
6345bc3cb74SMauro Carvalho Chehab 
6355bc3cb74SMauro Carvalho Chehab static void v4l_print_encoder_cmd(const void *arg, bool write_only)
6365bc3cb74SMauro Carvalho Chehab {
6375bc3cb74SMauro Carvalho Chehab 	const struct v4l2_encoder_cmd *p = arg;
6385bc3cb74SMauro Carvalho Chehab 
6395bc3cb74SMauro Carvalho Chehab 	pr_cont("cmd=%d, flags=0x%x\n",
6405bc3cb74SMauro Carvalho Chehab 			p->cmd, p->flags);
6415bc3cb74SMauro Carvalho Chehab }
6425bc3cb74SMauro Carvalho Chehab 
6435bc3cb74SMauro Carvalho Chehab static void v4l_print_decoder_cmd(const void *arg, bool write_only)
6445bc3cb74SMauro Carvalho Chehab {
6455bc3cb74SMauro Carvalho Chehab 	const struct v4l2_decoder_cmd *p = arg;
6465bc3cb74SMauro Carvalho Chehab 
6475bc3cb74SMauro Carvalho Chehab 	pr_cont("cmd=%d, flags=0x%x\n", p->cmd, p->flags);
6485bc3cb74SMauro Carvalho Chehab 
6495bc3cb74SMauro Carvalho Chehab 	if (p->cmd == V4L2_DEC_CMD_START)
6505bc3cb74SMauro Carvalho Chehab 		pr_info("speed=%d, format=%u\n",
6515bc3cb74SMauro Carvalho Chehab 				p->start.speed, p->start.format);
6525bc3cb74SMauro Carvalho Chehab 	else if (p->cmd == V4L2_DEC_CMD_STOP)
6535bc3cb74SMauro Carvalho Chehab 		pr_info("pts=%llu\n", p->stop.pts);
6545bc3cb74SMauro Carvalho Chehab }
6555bc3cb74SMauro Carvalho Chehab 
65696b03d2aSHans Verkuil static void v4l_print_dbg_chip_info(const void *arg, bool write_only)
65779b0c640SHans Verkuil {
65896b03d2aSHans Verkuil 	const struct v4l2_dbg_chip_info *p = arg;
65979b0c640SHans Verkuil 
66079b0c640SHans Verkuil 	pr_cont("type=%u, ", p->match.type);
6613eef2510SHans Verkuil 	if (p->match.type == V4L2_CHIP_MATCH_I2C_DRIVER)
66279b0c640SHans Verkuil 		pr_cont("name=%.*s, ",
66379b0c640SHans Verkuil 				(int)sizeof(p->match.name), p->match.name);
66479b0c640SHans Verkuil 	else
66579b0c640SHans Verkuil 		pr_cont("addr=%u, ", p->match.addr);
66679b0c640SHans Verkuil 	pr_cont("name=%.*s\n", (int)sizeof(p->name), p->name);
66779b0c640SHans Verkuil }
66879b0c640SHans Verkuil 
6695bc3cb74SMauro Carvalho Chehab static void v4l_print_dbg_register(const void *arg, bool write_only)
6705bc3cb74SMauro Carvalho Chehab {
6715bc3cb74SMauro Carvalho Chehab 	const struct v4l2_dbg_register *p = arg;
6725bc3cb74SMauro Carvalho Chehab 
6735bc3cb74SMauro Carvalho Chehab 	pr_cont("type=%u, ", p->match.type);
6743eef2510SHans Verkuil 	if (p->match.type == V4L2_CHIP_MATCH_I2C_DRIVER)
67527d5a87cSHans Verkuil 		pr_cont("name=%.*s, ",
67627d5a87cSHans Verkuil 				(int)sizeof(p->match.name), p->match.name);
6775bc3cb74SMauro Carvalho Chehab 	else
6785bc3cb74SMauro Carvalho Chehab 		pr_cont("addr=%u, ", p->match.addr);
6795bc3cb74SMauro Carvalho Chehab 	pr_cont("reg=0x%llx, val=0x%llx\n",
6805bc3cb74SMauro Carvalho Chehab 			p->reg, p->val);
6815bc3cb74SMauro Carvalho Chehab }
6825bc3cb74SMauro Carvalho Chehab 
6835bc3cb74SMauro Carvalho Chehab static void v4l_print_dv_timings(const void *arg, bool write_only)
6845bc3cb74SMauro Carvalho Chehab {
6855bc3cb74SMauro Carvalho Chehab 	const struct v4l2_dv_timings *p = arg;
6865bc3cb74SMauro Carvalho Chehab 
6875bc3cb74SMauro Carvalho Chehab 	switch (p->type) {
6885bc3cb74SMauro Carvalho Chehab 	case V4L2_DV_BT_656_1120:
6895bc3cb74SMauro Carvalho Chehab 		pr_cont("type=bt-656/1120, interlaced=%u, "
6905bc3cb74SMauro Carvalho Chehab 			"pixelclock=%llu, "
6915bc3cb74SMauro Carvalho Chehab 			"width=%u, height=%u, polarities=0x%x, "
6925bc3cb74SMauro Carvalho Chehab 			"hfrontporch=%u, hsync=%u, "
6935bc3cb74SMauro Carvalho Chehab 			"hbackporch=%u, vfrontporch=%u, "
6945bc3cb74SMauro Carvalho Chehab 			"vsync=%u, vbackporch=%u, "
6955bc3cb74SMauro Carvalho Chehab 			"il_vfrontporch=%u, il_vsync=%u, "
6965bc3cb74SMauro Carvalho Chehab 			"il_vbackporch=%u, standards=0x%x, flags=0x%x\n",
6975bc3cb74SMauro Carvalho Chehab 				p->bt.interlaced, p->bt.pixelclock,
6985bc3cb74SMauro Carvalho Chehab 				p->bt.width, p->bt.height,
6995bc3cb74SMauro Carvalho Chehab 				p->bt.polarities, p->bt.hfrontporch,
7005bc3cb74SMauro Carvalho Chehab 				p->bt.hsync, p->bt.hbackporch,
7015bc3cb74SMauro Carvalho Chehab 				p->bt.vfrontporch, p->bt.vsync,
7025bc3cb74SMauro Carvalho Chehab 				p->bt.vbackporch, p->bt.il_vfrontporch,
7035bc3cb74SMauro Carvalho Chehab 				p->bt.il_vsync, p->bt.il_vbackporch,
7045bc3cb74SMauro Carvalho Chehab 				p->bt.standards, p->bt.flags);
7055bc3cb74SMauro Carvalho Chehab 		break;
7065bc3cb74SMauro Carvalho Chehab 	default:
7075bc3cb74SMauro Carvalho Chehab 		pr_cont("type=%d\n", p->type);
7085bc3cb74SMauro Carvalho Chehab 		break;
7095bc3cb74SMauro Carvalho Chehab 	}
7105bc3cb74SMauro Carvalho Chehab }
7115bc3cb74SMauro Carvalho Chehab 
7125bc3cb74SMauro Carvalho Chehab static void v4l_print_enum_dv_timings(const void *arg, bool write_only)
7135bc3cb74SMauro Carvalho Chehab {
7145bc3cb74SMauro Carvalho Chehab 	const struct v4l2_enum_dv_timings *p = arg;
7155bc3cb74SMauro Carvalho Chehab 
7165bc3cb74SMauro Carvalho Chehab 	pr_cont("index=%u, ", p->index);
7175bc3cb74SMauro Carvalho Chehab 	v4l_print_dv_timings(&p->timings, write_only);
7185bc3cb74SMauro Carvalho Chehab }
7195bc3cb74SMauro Carvalho Chehab 
7205bc3cb74SMauro Carvalho Chehab static void v4l_print_dv_timings_cap(const void *arg, bool write_only)
7215bc3cb74SMauro Carvalho Chehab {
7225bc3cb74SMauro Carvalho Chehab 	const struct v4l2_dv_timings_cap *p = arg;
7235bc3cb74SMauro Carvalho Chehab 
7245bc3cb74SMauro Carvalho Chehab 	switch (p->type) {
7255bc3cb74SMauro Carvalho Chehab 	case V4L2_DV_BT_656_1120:
7265bc3cb74SMauro Carvalho Chehab 		pr_cont("type=bt-656/1120, width=%u-%u, height=%u-%u, "
7275bc3cb74SMauro Carvalho Chehab 			"pixelclock=%llu-%llu, standards=0x%x, capabilities=0x%x\n",
7285bc3cb74SMauro Carvalho Chehab 			p->bt.min_width, p->bt.max_width,
7295bc3cb74SMauro Carvalho Chehab 			p->bt.min_height, p->bt.max_height,
7305bc3cb74SMauro Carvalho Chehab 			p->bt.min_pixelclock, p->bt.max_pixelclock,
7315bc3cb74SMauro Carvalho Chehab 			p->bt.standards, p->bt.capabilities);
7325bc3cb74SMauro Carvalho Chehab 		break;
7335bc3cb74SMauro Carvalho Chehab 	default:
7345bc3cb74SMauro Carvalho Chehab 		pr_cont("type=%u\n", p->type);
7355bc3cb74SMauro Carvalho Chehab 		break;
7365bc3cb74SMauro Carvalho Chehab 	}
7375bc3cb74SMauro Carvalho Chehab }
7385bc3cb74SMauro Carvalho Chehab 
7395bc3cb74SMauro Carvalho Chehab static void v4l_print_frmsizeenum(const void *arg, bool write_only)
7405bc3cb74SMauro Carvalho Chehab {
7415bc3cb74SMauro Carvalho Chehab 	const struct v4l2_frmsizeenum *p = arg;
7425bc3cb74SMauro Carvalho Chehab 
7435bc3cb74SMauro Carvalho Chehab 	pr_cont("index=%u, pixelformat=%c%c%c%c, type=%u",
7445bc3cb74SMauro Carvalho Chehab 			p->index,
7455bc3cb74SMauro Carvalho Chehab 			(p->pixel_format & 0xff),
7465bc3cb74SMauro Carvalho Chehab 			(p->pixel_format >>  8) & 0xff,
7475bc3cb74SMauro Carvalho Chehab 			(p->pixel_format >> 16) & 0xff,
7485bc3cb74SMauro Carvalho Chehab 			(p->pixel_format >> 24) & 0xff,
7495bc3cb74SMauro Carvalho Chehab 			p->type);
7505bc3cb74SMauro Carvalho Chehab 	switch (p->type) {
7515bc3cb74SMauro Carvalho Chehab 	case V4L2_FRMSIZE_TYPE_DISCRETE:
752560dde24SHans Verkuil 		pr_cont(", wxh=%ux%u\n",
7535bc3cb74SMauro Carvalho Chehab 			p->discrete.width, p->discrete.height);
7545bc3cb74SMauro Carvalho Chehab 		break;
7555bc3cb74SMauro Carvalho Chehab 	case V4L2_FRMSIZE_TYPE_STEPWISE:
756560dde24SHans Verkuil 		pr_cont(", min=%ux%u, max=%ux%u, step=%ux%u\n",
7575bc3cb74SMauro Carvalho Chehab 				p->stepwise.min_width,  p->stepwise.min_height,
7585bc3cb74SMauro Carvalho Chehab 				p->stepwise.step_width, p->stepwise.step_height,
7595bc3cb74SMauro Carvalho Chehab 				p->stepwise.max_width,  p->stepwise.max_height);
7605bc3cb74SMauro Carvalho Chehab 		break;
7615bc3cb74SMauro Carvalho Chehab 	case V4L2_FRMSIZE_TYPE_CONTINUOUS:
7625bc3cb74SMauro Carvalho Chehab 		/* fall through */
7635bc3cb74SMauro Carvalho Chehab 	default:
7645bc3cb74SMauro Carvalho Chehab 		pr_cont("\n");
7655bc3cb74SMauro Carvalho Chehab 		break;
7665bc3cb74SMauro Carvalho Chehab 	}
7675bc3cb74SMauro Carvalho Chehab }
7685bc3cb74SMauro Carvalho Chehab 
7695bc3cb74SMauro Carvalho Chehab static void v4l_print_frmivalenum(const void *arg, bool write_only)
7705bc3cb74SMauro Carvalho Chehab {
7715bc3cb74SMauro Carvalho Chehab 	const struct v4l2_frmivalenum *p = arg;
7725bc3cb74SMauro Carvalho Chehab 
7735bc3cb74SMauro Carvalho Chehab 	pr_cont("index=%u, pixelformat=%c%c%c%c, wxh=%ux%u, type=%u",
7745bc3cb74SMauro Carvalho Chehab 			p->index,
7755bc3cb74SMauro Carvalho Chehab 			(p->pixel_format & 0xff),
7765bc3cb74SMauro Carvalho Chehab 			(p->pixel_format >>  8) & 0xff,
7775bc3cb74SMauro Carvalho Chehab 			(p->pixel_format >> 16) & 0xff,
7785bc3cb74SMauro Carvalho Chehab 			(p->pixel_format >> 24) & 0xff,
7795bc3cb74SMauro Carvalho Chehab 			p->width, p->height, p->type);
7805bc3cb74SMauro Carvalho Chehab 	switch (p->type) {
7815bc3cb74SMauro Carvalho Chehab 	case V4L2_FRMIVAL_TYPE_DISCRETE:
782560dde24SHans Verkuil 		pr_cont(", fps=%d/%d\n",
7835bc3cb74SMauro Carvalho Chehab 				p->discrete.numerator,
7845bc3cb74SMauro Carvalho Chehab 				p->discrete.denominator);
7855bc3cb74SMauro Carvalho Chehab 		break;
7865bc3cb74SMauro Carvalho Chehab 	case V4L2_FRMIVAL_TYPE_STEPWISE:
787560dde24SHans Verkuil 		pr_cont(", min=%d/%d, max=%d/%d, step=%d/%d\n",
7885bc3cb74SMauro Carvalho Chehab 				p->stepwise.min.numerator,
7895bc3cb74SMauro Carvalho Chehab 				p->stepwise.min.denominator,
7905bc3cb74SMauro Carvalho Chehab 				p->stepwise.max.numerator,
7915bc3cb74SMauro Carvalho Chehab 				p->stepwise.max.denominator,
7925bc3cb74SMauro Carvalho Chehab 				p->stepwise.step.numerator,
7935bc3cb74SMauro Carvalho Chehab 				p->stepwise.step.denominator);
7945bc3cb74SMauro Carvalho Chehab 		break;
7955bc3cb74SMauro Carvalho Chehab 	case V4L2_FRMIVAL_TYPE_CONTINUOUS:
7965bc3cb74SMauro Carvalho Chehab 		/* fall through */
7975bc3cb74SMauro Carvalho Chehab 	default:
7985bc3cb74SMauro Carvalho Chehab 		pr_cont("\n");
7995bc3cb74SMauro Carvalho Chehab 		break;
8005bc3cb74SMauro Carvalho Chehab 	}
8015bc3cb74SMauro Carvalho Chehab }
8025bc3cb74SMauro Carvalho Chehab 
8035bc3cb74SMauro Carvalho Chehab static void v4l_print_event(const void *arg, bool write_only)
8045bc3cb74SMauro Carvalho Chehab {
8055bc3cb74SMauro Carvalho Chehab 	const struct v4l2_event *p = arg;
8065bc3cb74SMauro Carvalho Chehab 	const struct v4l2_event_ctrl *c;
8075bc3cb74SMauro Carvalho Chehab 
8085bc3cb74SMauro Carvalho Chehab 	pr_cont("type=0x%x, pending=%u, sequence=%u, id=%u, "
8095bc3cb74SMauro Carvalho Chehab 		"timestamp=%lu.%9.9lu\n",
8105bc3cb74SMauro Carvalho Chehab 			p->type, p->pending, p->sequence, p->id,
8115bc3cb74SMauro Carvalho Chehab 			p->timestamp.tv_sec, p->timestamp.tv_nsec);
8125bc3cb74SMauro Carvalho Chehab 	switch (p->type) {
8135bc3cb74SMauro Carvalho Chehab 	case V4L2_EVENT_VSYNC:
8145bc3cb74SMauro Carvalho Chehab 		printk(KERN_DEBUG "field=%s\n",
8155bc3cb74SMauro Carvalho Chehab 			prt_names(p->u.vsync.field, v4l2_field_names));
8165bc3cb74SMauro Carvalho Chehab 		break;
8175bc3cb74SMauro Carvalho Chehab 	case V4L2_EVENT_CTRL:
8185bc3cb74SMauro Carvalho Chehab 		c = &p->u.ctrl;
8195bc3cb74SMauro Carvalho Chehab 		printk(KERN_DEBUG "changes=0x%x, type=%u, ",
8205bc3cb74SMauro Carvalho Chehab 			c->changes, c->type);
8215bc3cb74SMauro Carvalho Chehab 		if (c->type == V4L2_CTRL_TYPE_INTEGER64)
8225bc3cb74SMauro Carvalho Chehab 			pr_cont("value64=%lld, ", c->value64);
8235bc3cb74SMauro Carvalho Chehab 		else
8245bc3cb74SMauro Carvalho Chehab 			pr_cont("value=%d, ", c->value);
8255bc3cb74SMauro Carvalho Chehab 		pr_cont("flags=0x%x, minimum=%d, maximum=%d, step=%d, "
8265bc3cb74SMauro Carvalho Chehab 			"default_value=%d\n",
8275bc3cb74SMauro Carvalho Chehab 			c->flags, c->minimum, c->maximum,
8285bc3cb74SMauro Carvalho Chehab 			c->step, c->default_value);
8295bc3cb74SMauro Carvalho Chehab 		break;
8305bc3cb74SMauro Carvalho Chehab 	case V4L2_EVENT_FRAME_SYNC:
8315bc3cb74SMauro Carvalho Chehab 		pr_cont("frame_sequence=%u\n",
8325bc3cb74SMauro Carvalho Chehab 			p->u.frame_sync.frame_sequence);
8335bc3cb74SMauro Carvalho Chehab 		break;
8345bc3cb74SMauro Carvalho Chehab 	}
8355bc3cb74SMauro Carvalho Chehab }
8365bc3cb74SMauro Carvalho Chehab 
8375bc3cb74SMauro Carvalho Chehab static void v4l_print_event_subscription(const void *arg, bool write_only)
8385bc3cb74SMauro Carvalho Chehab {
8395bc3cb74SMauro Carvalho Chehab 	const struct v4l2_event_subscription *p = arg;
8405bc3cb74SMauro Carvalho Chehab 
8415bc3cb74SMauro Carvalho Chehab 	pr_cont("type=0x%x, id=0x%x, flags=0x%x\n",
8425bc3cb74SMauro Carvalho Chehab 			p->type, p->id, p->flags);
8435bc3cb74SMauro Carvalho Chehab }
8445bc3cb74SMauro Carvalho Chehab 
8455bc3cb74SMauro Carvalho Chehab static void v4l_print_sliced_vbi_cap(const void *arg, bool write_only)
8465bc3cb74SMauro Carvalho Chehab {
8475bc3cb74SMauro Carvalho Chehab 	const struct v4l2_sliced_vbi_cap *p = arg;
8485bc3cb74SMauro Carvalho Chehab 	int i;
8495bc3cb74SMauro Carvalho Chehab 
8505bc3cb74SMauro Carvalho Chehab 	pr_cont("type=%s, service_set=0x%08x\n",
8515bc3cb74SMauro Carvalho Chehab 			prt_names(p->type, v4l2_type_names), p->service_set);
8525bc3cb74SMauro Carvalho Chehab 	for (i = 0; i < 24; i++)
8535bc3cb74SMauro Carvalho Chehab 		printk(KERN_DEBUG "line[%02u]=0x%04x, 0x%04x\n", i,
8545bc3cb74SMauro Carvalho Chehab 				p->service_lines[0][i],
8555bc3cb74SMauro Carvalho Chehab 				p->service_lines[1][i]);
8565bc3cb74SMauro Carvalho Chehab }
8575bc3cb74SMauro Carvalho Chehab 
8585bc3cb74SMauro Carvalho Chehab static void v4l_print_freq_band(const void *arg, bool write_only)
8595bc3cb74SMauro Carvalho Chehab {
8605bc3cb74SMauro Carvalho Chehab 	const struct v4l2_frequency_band *p = arg;
8615bc3cb74SMauro Carvalho Chehab 
8625bc3cb74SMauro Carvalho Chehab 	pr_cont("tuner=%u, type=%u, index=%u, capability=0x%x, "
8635bc3cb74SMauro Carvalho Chehab 		"rangelow=%u, rangehigh=%u, modulation=0x%x\n",
8645bc3cb74SMauro Carvalho Chehab 			p->tuner, p->type, p->index,
8655bc3cb74SMauro Carvalho Chehab 			p->capability, p->rangelow,
8665bc3cb74SMauro Carvalho Chehab 			p->rangehigh, p->modulation);
8675bc3cb74SMauro Carvalho Chehab }
8685bc3cb74SMauro Carvalho Chehab 
869dd519bb3SHans Verkuil static void v4l_print_edid(const void *arg, bool write_only)
870dd519bb3SHans Verkuil {
871dd519bb3SHans Verkuil 	const struct v4l2_edid *p = arg;
872dd519bb3SHans Verkuil 
873dd519bb3SHans Verkuil 	pr_cont("pad=%u, start_block=%u, blocks=%u\n",
874dd519bb3SHans Verkuil 		p->pad, p->start_block, p->blocks);
875dd519bb3SHans Verkuil }
876dd519bb3SHans Verkuil 
8775bc3cb74SMauro Carvalho Chehab static void v4l_print_u32(const void *arg, bool write_only)
8785bc3cb74SMauro Carvalho Chehab {
8795bc3cb74SMauro Carvalho Chehab 	pr_cont("value=%u\n", *(const u32 *)arg);
8805bc3cb74SMauro Carvalho Chehab }
8815bc3cb74SMauro Carvalho Chehab 
8825bc3cb74SMauro Carvalho Chehab static void v4l_print_newline(const void *arg, bool write_only)
8835bc3cb74SMauro Carvalho Chehab {
8845bc3cb74SMauro Carvalho Chehab 	pr_cont("\n");
8855bc3cb74SMauro Carvalho Chehab }
8865bc3cb74SMauro Carvalho Chehab 
8875bc3cb74SMauro Carvalho Chehab static void v4l_print_default(const void *arg, bool write_only)
8885bc3cb74SMauro Carvalho Chehab {
8895bc3cb74SMauro Carvalho Chehab 	pr_cont("driver-specific ioctl\n");
8905bc3cb74SMauro Carvalho Chehab }
8915bc3cb74SMauro Carvalho Chehab 
8925bc3cb74SMauro Carvalho Chehab static int check_ext_ctrls(struct v4l2_ext_controls *c, int allow_priv)
8935bc3cb74SMauro Carvalho Chehab {
8945bc3cb74SMauro Carvalho Chehab 	__u32 i;
8955bc3cb74SMauro Carvalho Chehab 
8965bc3cb74SMauro Carvalho Chehab 	/* zero the reserved fields */
8975bc3cb74SMauro Carvalho Chehab 	c->reserved[0] = c->reserved[1] = 0;
8985bc3cb74SMauro Carvalho Chehab 	for (i = 0; i < c->count; i++)
8995bc3cb74SMauro Carvalho Chehab 		c->controls[i].reserved2[0] = 0;
9005bc3cb74SMauro Carvalho Chehab 
9015bc3cb74SMauro Carvalho Chehab 	/* V4L2_CID_PRIVATE_BASE cannot be used as control class
9025bc3cb74SMauro Carvalho Chehab 	   when using extended controls.
9035bc3cb74SMauro Carvalho Chehab 	   Only when passed in through VIDIOC_G_CTRL and VIDIOC_S_CTRL
9045bc3cb74SMauro Carvalho Chehab 	   is it allowed for backwards compatibility.
9055bc3cb74SMauro Carvalho Chehab 	 */
9060f8017beSRicardo Ribalda 	if (!allow_priv && c->which == V4L2_CID_PRIVATE_BASE)
9075bc3cb74SMauro Carvalho Chehab 		return 0;
9080f8017beSRicardo Ribalda 	if (!c->which)
9099b239b22SHans Verkuil 		return 1;
9105bc3cb74SMauro Carvalho Chehab 	/* Check that all controls are from the same control class. */
9115bc3cb74SMauro Carvalho Chehab 	for (i = 0; i < c->count; i++) {
9120f8017beSRicardo Ribalda 		if (V4L2_CTRL_ID2WHICH(c->controls[i].id) != c->which) {
9135bc3cb74SMauro Carvalho Chehab 			c->error_idx = i;
9145bc3cb74SMauro Carvalho Chehab 			return 0;
9155bc3cb74SMauro Carvalho Chehab 		}
9165bc3cb74SMauro Carvalho Chehab 	}
9175bc3cb74SMauro Carvalho Chehab 	return 1;
9185bc3cb74SMauro Carvalho Chehab }
9195bc3cb74SMauro Carvalho Chehab 
9204b20259fSHans Verkuil static int check_fmt(struct file *file, enum v4l2_buf_type type)
9215bc3cb74SMauro Carvalho Chehab {
9224b20259fSHans Verkuil 	struct video_device *vfd = video_devdata(file);
9234b20259fSHans Verkuil 	const struct v4l2_ioctl_ops *ops = vfd->ioctl_ops;
9244b20259fSHans Verkuil 	bool is_vid = vfd->vfl_type == VFL_TYPE_GRABBER;
9254b20259fSHans Verkuil 	bool is_vbi = vfd->vfl_type == VFL_TYPE_VBI;
926582c52cbSAntti Palosaari 	bool is_sdr = vfd->vfl_type == VFL_TYPE_SDR;
9274b20259fSHans Verkuil 	bool is_rx = vfd->vfl_dir != VFL_DIR_TX;
9284b20259fSHans Verkuil 	bool is_tx = vfd->vfl_dir != VFL_DIR_RX;
9294b20259fSHans Verkuil 
9305bc3cb74SMauro Carvalho Chehab 	if (ops == NULL)
9315bc3cb74SMauro Carvalho Chehab 		return -EINVAL;
9325bc3cb74SMauro Carvalho Chehab 
9335bc3cb74SMauro Carvalho Chehab 	switch (type) {
9345bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_CAPTURE:
9354b20259fSHans Verkuil 		if (is_vid && is_rx &&
9364b20259fSHans Verkuil 		    (ops->vidioc_g_fmt_vid_cap || ops->vidioc_g_fmt_vid_cap_mplane))
9375bc3cb74SMauro Carvalho Chehab 			return 0;
9385bc3cb74SMauro Carvalho Chehab 		break;
9395bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
9404b20259fSHans Verkuil 		if (is_vid && is_rx && ops->vidioc_g_fmt_vid_cap_mplane)
9415bc3cb74SMauro Carvalho Chehab 			return 0;
9425bc3cb74SMauro Carvalho Chehab 		break;
9435bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_OVERLAY:
9444b20259fSHans Verkuil 		if (is_vid && is_rx && ops->vidioc_g_fmt_vid_overlay)
9455bc3cb74SMauro Carvalho Chehab 			return 0;
9465bc3cb74SMauro Carvalho Chehab 		break;
9475bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_OUTPUT:
9484b20259fSHans Verkuil 		if (is_vid && is_tx &&
9494b20259fSHans Verkuil 		    (ops->vidioc_g_fmt_vid_out || ops->vidioc_g_fmt_vid_out_mplane))
9505bc3cb74SMauro Carvalho Chehab 			return 0;
9515bc3cb74SMauro Carvalho Chehab 		break;
9525bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
9534b20259fSHans Verkuil 		if (is_vid && is_tx && ops->vidioc_g_fmt_vid_out_mplane)
9545bc3cb74SMauro Carvalho Chehab 			return 0;
9555bc3cb74SMauro Carvalho Chehab 		break;
9565bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
9574b20259fSHans Verkuil 		if (is_vid && is_tx && ops->vidioc_g_fmt_vid_out_overlay)
9585bc3cb74SMauro Carvalho Chehab 			return 0;
9595bc3cb74SMauro Carvalho Chehab 		break;
9605bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VBI_CAPTURE:
9614b20259fSHans Verkuil 		if (is_vbi && is_rx && ops->vidioc_g_fmt_vbi_cap)
9625bc3cb74SMauro Carvalho Chehab 			return 0;
9635bc3cb74SMauro Carvalho Chehab 		break;
9645bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VBI_OUTPUT:
9654b20259fSHans Verkuil 		if (is_vbi && is_tx && ops->vidioc_g_fmt_vbi_out)
9665bc3cb74SMauro Carvalho Chehab 			return 0;
9675bc3cb74SMauro Carvalho Chehab 		break;
9685bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
9694b20259fSHans Verkuil 		if (is_vbi && is_rx && ops->vidioc_g_fmt_sliced_vbi_cap)
9705bc3cb74SMauro Carvalho Chehab 			return 0;
9715bc3cb74SMauro Carvalho Chehab 		break;
9725bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
9734b20259fSHans Verkuil 		if (is_vbi && is_tx && ops->vidioc_g_fmt_sliced_vbi_out)
9745bc3cb74SMauro Carvalho Chehab 			return 0;
9755bc3cb74SMauro Carvalho Chehab 		break;
976582c52cbSAntti Palosaari 	case V4L2_BUF_TYPE_SDR_CAPTURE:
977582c52cbSAntti Palosaari 		if (is_sdr && is_rx && ops->vidioc_g_fmt_sdr_cap)
978582c52cbSAntti Palosaari 			return 0;
979582c52cbSAntti Palosaari 		break;
9809effc72fSAntti Palosaari 	case V4L2_BUF_TYPE_SDR_OUTPUT:
9819effc72fSAntti Palosaari 		if (is_sdr && is_tx && ops->vidioc_g_fmt_sdr_out)
9829effc72fSAntti Palosaari 			return 0;
9839effc72fSAntti Palosaari 		break;
984633c98e5SHans Verkuil 	default:
9855bc3cb74SMauro Carvalho Chehab 		break;
9865bc3cb74SMauro Carvalho Chehab 	}
9875bc3cb74SMauro Carvalho Chehab 	return -EINVAL;
9885bc3cb74SMauro Carvalho Chehab }
9895bc3cb74SMauro Carvalho Chehab 
990d52e2381SLaurent Pinchart static void v4l_sanitize_format(struct v4l2_format *fmt)
991d52e2381SLaurent Pinchart {
992d52e2381SLaurent Pinchart 	unsigned int offset;
993d52e2381SLaurent Pinchart 
994d52e2381SLaurent Pinchart 	/*
995d52e2381SLaurent Pinchart 	 * The v4l2_pix_format structure has been extended with fields that were
996d52e2381SLaurent Pinchart 	 * not previously required to be set to zero by applications. The priv
997d52e2381SLaurent Pinchart 	 * field, when set to a magic value, indicates the the extended fields
998d52e2381SLaurent Pinchart 	 * are valid. Otherwise they will contain undefined values. To simplify
999d52e2381SLaurent Pinchart 	 * the API towards drivers zero the extended fields and set the priv
1000d52e2381SLaurent Pinchart 	 * field to the magic value when the extended pixel format structure
1001d52e2381SLaurent Pinchart 	 * isn't used by applications.
1002d52e2381SLaurent Pinchart 	 */
1003d52e2381SLaurent Pinchart 
1004d52e2381SLaurent Pinchart 	if (fmt->type != V4L2_BUF_TYPE_VIDEO_CAPTURE &&
1005d52e2381SLaurent Pinchart 	    fmt->type != V4L2_BUF_TYPE_VIDEO_OUTPUT)
1006d52e2381SLaurent Pinchart 		return;
1007d52e2381SLaurent Pinchart 
1008d52e2381SLaurent Pinchart 	if (fmt->fmt.pix.priv == V4L2_PIX_FMT_PRIV_MAGIC)
1009d52e2381SLaurent Pinchart 		return;
1010d52e2381SLaurent Pinchart 
1011d52e2381SLaurent Pinchart 	fmt->fmt.pix.priv = V4L2_PIX_FMT_PRIV_MAGIC;
1012d52e2381SLaurent Pinchart 
1013d52e2381SLaurent Pinchart 	offset = offsetof(struct v4l2_pix_format, priv)
1014d52e2381SLaurent Pinchart 	       + sizeof(fmt->fmt.pix.priv);
1015d52e2381SLaurent Pinchart 	memset(((void *)&fmt->fmt.pix) + offset, 0,
1016d52e2381SLaurent Pinchart 	       sizeof(fmt->fmt.pix) - offset);
1017d52e2381SLaurent Pinchart }
1018d52e2381SLaurent Pinchart 
10195bc3cb74SMauro Carvalho Chehab static int v4l_querycap(const struct v4l2_ioctl_ops *ops,
10205bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
10215bc3cb74SMauro Carvalho Chehab {
10225bc3cb74SMauro Carvalho Chehab 	struct v4l2_capability *cap = (struct v4l2_capability *)arg;
10237bbe7813SHans Verkuil 	struct video_device *vfd = video_devdata(file);
1024d52e2381SLaurent Pinchart 	int ret;
10255bc3cb74SMauro Carvalho Chehab 
10265bc3cb74SMauro Carvalho Chehab 	cap->version = LINUX_VERSION_CODE;
10277bbe7813SHans Verkuil 	cap->device_caps = vfd->device_caps;
10287bbe7813SHans Verkuil 	cap->capabilities = vfd->device_caps | V4L2_CAP_DEVICE_CAPS;
1029d52e2381SLaurent Pinchart 
1030d52e2381SLaurent Pinchart 	ret = ops->vidioc_querycap(file, fh, cap);
1031d52e2381SLaurent Pinchart 
1032d52e2381SLaurent Pinchart 	cap->capabilities |= V4L2_CAP_EXT_PIX_FORMAT;
1033454a4e72SHans Verkuil 	/*
1034454a4e72SHans Verkuil 	 * Drivers MUST fill in device_caps, so check for this and
1035454a4e72SHans Verkuil 	 * warn if it was forgotten.
1036454a4e72SHans Verkuil 	 */
10376d7570c4SLaura Abbott 	WARN(!(cap->capabilities & V4L2_CAP_DEVICE_CAPS) ||
10386d7570c4SLaura Abbott 		!cap->device_caps, "Bad caps for driver %s, %x %x",
10396d7570c4SLaura Abbott 		cap->driver, cap->capabilities, cap->device_caps);
1040796a2bd2SHans Verkuil 	cap->device_caps |= V4L2_CAP_EXT_PIX_FORMAT;
1041d52e2381SLaurent Pinchart 
1042d52e2381SLaurent Pinchart 	return ret;
10435bc3cb74SMauro Carvalho Chehab }
10445bc3cb74SMauro Carvalho Chehab 
10455bc3cb74SMauro Carvalho Chehab static int v4l_s_input(const struct v4l2_ioctl_ops *ops,
10465bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
10475bc3cb74SMauro Carvalho Chehab {
104877fa4e07SShuah Khan 	struct video_device *vfd = video_devdata(file);
104977fa4e07SShuah Khan 	int ret;
105077fa4e07SShuah Khan 
105177fa4e07SShuah Khan 	ret = v4l_enable_media_source(vfd);
105277fa4e07SShuah Khan 	if (ret)
105377fa4e07SShuah Khan 		return ret;
10545bc3cb74SMauro Carvalho Chehab 	return ops->vidioc_s_input(file, fh, *(unsigned int *)arg);
10555bc3cb74SMauro Carvalho Chehab }
10565bc3cb74SMauro Carvalho Chehab 
10575bc3cb74SMauro Carvalho Chehab static int v4l_s_output(const struct v4l2_ioctl_ops *ops,
10585bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
10595bc3cb74SMauro Carvalho Chehab {
10605bc3cb74SMauro Carvalho Chehab 	return ops->vidioc_s_output(file, fh, *(unsigned int *)arg);
10615bc3cb74SMauro Carvalho Chehab }
10625bc3cb74SMauro Carvalho Chehab 
10635bc3cb74SMauro Carvalho Chehab static int v4l_g_priority(const struct v4l2_ioctl_ops *ops,
10645bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
10655bc3cb74SMauro Carvalho Chehab {
10665bc3cb74SMauro Carvalho Chehab 	struct video_device *vfd;
10675bc3cb74SMauro Carvalho Chehab 	u32 *p = arg;
10685bc3cb74SMauro Carvalho Chehab 
10695bc3cb74SMauro Carvalho Chehab 	vfd = video_devdata(file);
107059b702eaSLaurent Pinchart 	*p = v4l2_prio_max(vfd->prio);
10715bc3cb74SMauro Carvalho Chehab 	return 0;
10725bc3cb74SMauro Carvalho Chehab }
10735bc3cb74SMauro Carvalho Chehab 
10745bc3cb74SMauro Carvalho Chehab static int v4l_s_priority(const struct v4l2_ioctl_ops *ops,
10755bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
10765bc3cb74SMauro Carvalho Chehab {
10775bc3cb74SMauro Carvalho Chehab 	struct video_device *vfd;
10785bc3cb74SMauro Carvalho Chehab 	struct v4l2_fh *vfh;
10795bc3cb74SMauro Carvalho Chehab 	u32 *p = arg;
10805bc3cb74SMauro Carvalho Chehab 
10815bc3cb74SMauro Carvalho Chehab 	vfd = video_devdata(file);
10822438e78aSHans Verkuil 	if (!test_bit(V4L2_FL_USES_V4L2_FH, &vfd->flags))
10832438e78aSHans Verkuil 		return -ENOTTY;
10845bc3cb74SMauro Carvalho Chehab 	vfh = file->private_data;
108559b702eaSLaurent Pinchart 	return v4l2_prio_change(vfd->prio, &vfh->prio, *p);
10865bc3cb74SMauro Carvalho Chehab }
10875bc3cb74SMauro Carvalho Chehab 
10885bc3cb74SMauro Carvalho Chehab static int v4l_enuminput(const struct v4l2_ioctl_ops *ops,
10895bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
10905bc3cb74SMauro Carvalho Chehab {
109173f35418SHans Verkuil 	struct video_device *vfd = video_devdata(file);
10925bc3cb74SMauro Carvalho Chehab 	struct v4l2_input *p = arg;
10935bc3cb74SMauro Carvalho Chehab 
10945bc3cb74SMauro Carvalho Chehab 	/*
109502fa6282SHans Verkuil 	 * We set the flags for CAP_DV_TIMINGS &
10965bc3cb74SMauro Carvalho Chehab 	 * CAP_STD here based on ioctl handler provided by the
10975bc3cb74SMauro Carvalho Chehab 	 * driver. If the driver doesn't support these
10985bc3cb74SMauro Carvalho Chehab 	 * for a specific input, it must override these flags.
10995bc3cb74SMauro Carvalho Chehab 	 */
110073f35418SHans Verkuil 	if (is_valid_ioctl(vfd, VIDIOC_S_STD))
11015bc3cb74SMauro Carvalho Chehab 		p->capabilities |= V4L2_IN_CAP_STD;
11025bc3cb74SMauro Carvalho Chehab 
11035bc3cb74SMauro Carvalho Chehab 	return ops->vidioc_enum_input(file, fh, p);
11045bc3cb74SMauro Carvalho Chehab }
11055bc3cb74SMauro Carvalho Chehab 
11065bc3cb74SMauro Carvalho Chehab static int v4l_enumoutput(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_output *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 output, it must override these flags.
11175bc3cb74SMauro Carvalho Chehab 	 */
111873f35418SHans Verkuil 	if (is_valid_ioctl(vfd, VIDIOC_S_STD))
11195bc3cb74SMauro Carvalho Chehab 		p->capabilities |= V4L2_OUT_CAP_STD;
11205bc3cb74SMauro Carvalho Chehab 
11215bc3cb74SMauro Carvalho Chehab 	return ops->vidioc_enum_output(file, fh, p);
11225bc3cb74SMauro Carvalho Chehab }
11235bc3cb74SMauro Carvalho Chehab 
1124ba300204SHans Verkuil static void v4l_fill_fmtdesc(struct v4l2_fmtdesc *fmt)
1125ba300204SHans Verkuil {
1126ba300204SHans Verkuil 	const unsigned sz = sizeof(fmt->description);
1127ba300204SHans Verkuil 	const char *descr = NULL;
1128ba300204SHans Verkuil 	u32 flags = 0;
1129ba300204SHans Verkuil 
1130ba300204SHans Verkuil 	/*
1131ba300204SHans Verkuil 	 * We depart from the normal coding style here since the descriptions
1132ba300204SHans Verkuil 	 * should be aligned so it is easy to see which descriptions will be
1133ba300204SHans Verkuil 	 * longer than 31 characters (the max length for a description).
1134ba300204SHans Verkuil 	 * And frankly, this is easier to read anyway.
1135ba300204SHans Verkuil 	 *
1136ba300204SHans Verkuil 	 * Note that gcc will use O(log N) comparisons to find the right case.
1137ba300204SHans Verkuil 	 */
1138ba300204SHans Verkuil 	switch (fmt->pixelformat) {
1139ba300204SHans Verkuil 	/* Max description length mask:	descr = "0123456789012345678901234567890" */
1140ba300204SHans Verkuil 	case V4L2_PIX_FMT_RGB332:	descr = "8-bit RGB 3-3-2"; break;
1141ba300204SHans Verkuil 	case V4L2_PIX_FMT_RGB444:	descr = "16-bit A/XRGB 4-4-4-4"; break;
1142ba300204SHans Verkuil 	case V4L2_PIX_FMT_ARGB444:	descr = "16-bit ARGB 4-4-4-4"; break;
1143ba300204SHans Verkuil 	case V4L2_PIX_FMT_XRGB444:	descr = "16-bit XRGB 4-4-4-4"; break;
1144ba300204SHans Verkuil 	case V4L2_PIX_FMT_RGB555:	descr = "16-bit A/XRGB 1-5-5-5"; break;
1145ba300204SHans Verkuil 	case V4L2_PIX_FMT_ARGB555:	descr = "16-bit ARGB 1-5-5-5"; break;
1146ba300204SHans Verkuil 	case V4L2_PIX_FMT_XRGB555:	descr = "16-bit XRGB 1-5-5-5"; break;
1147ba300204SHans Verkuil 	case V4L2_PIX_FMT_RGB565:	descr = "16-bit RGB 5-6-5"; break;
1148ba300204SHans Verkuil 	case V4L2_PIX_FMT_RGB555X:	descr = "16-bit A/XRGB 1-5-5-5 BE"; break;
1149ba300204SHans Verkuil 	case V4L2_PIX_FMT_ARGB555X:	descr = "16-bit ARGB 1-5-5-5 BE"; break;
1150ba300204SHans Verkuil 	case V4L2_PIX_FMT_XRGB555X:	descr = "16-bit XRGB 1-5-5-5 BE"; break;
1151ba300204SHans Verkuil 	case V4L2_PIX_FMT_RGB565X:	descr = "16-bit RGB 5-6-5 BE"; break;
1152ba300204SHans Verkuil 	case V4L2_PIX_FMT_BGR666:	descr = "18-bit BGRX 6-6-6-14"; break;
1153ba300204SHans Verkuil 	case V4L2_PIX_FMT_BGR24:	descr = "24-bit BGR 8-8-8"; break;
1154ba300204SHans Verkuil 	case V4L2_PIX_FMT_RGB24:	descr = "24-bit RGB 8-8-8"; break;
1155ba300204SHans Verkuil 	case V4L2_PIX_FMT_BGR32:	descr = "32-bit BGRA/X 8-8-8-8"; break;
1156ba300204SHans Verkuil 	case V4L2_PIX_FMT_ABGR32:	descr = "32-bit BGRA 8-8-8-8"; break;
1157ba300204SHans Verkuil 	case V4L2_PIX_FMT_XBGR32:	descr = "32-bit BGRX 8-8-8-8"; break;
1158ba300204SHans Verkuil 	case V4L2_PIX_FMT_RGB32:	descr = "32-bit A/XRGB 8-8-8-8"; break;
1159ba300204SHans Verkuil 	case V4L2_PIX_FMT_ARGB32:	descr = "32-bit ARGB 8-8-8-8"; break;
1160ba300204SHans Verkuil 	case V4L2_PIX_FMT_XRGB32:	descr = "32-bit XRGB 8-8-8-8"; break;
1161ba300204SHans Verkuil 	case V4L2_PIX_FMT_GREY:		descr = "8-bit Greyscale"; break;
1162ba300204SHans Verkuil 	case V4L2_PIX_FMT_Y4:		descr = "4-bit Greyscale"; break;
1163ba300204SHans Verkuil 	case V4L2_PIX_FMT_Y6:		descr = "6-bit Greyscale"; break;
1164ba300204SHans Verkuil 	case V4L2_PIX_FMT_Y10:		descr = "10-bit Greyscale"; break;
1165ba300204SHans Verkuil 	case V4L2_PIX_FMT_Y12:		descr = "12-bit Greyscale"; break;
1166ba300204SHans Verkuil 	case V4L2_PIX_FMT_Y16:		descr = "16-bit Greyscale"; break;
11672e5e435fSRicardo Ribalda 	case V4L2_PIX_FMT_Y16_BE:	descr = "16-bit Greyscale BE"; break;
1168ba300204SHans Verkuil 	case V4L2_PIX_FMT_Y10BPACK:	descr = "10-bit Greyscale (Packed)"; break;
1169ba300204SHans Verkuil 	case V4L2_PIX_FMT_PAL8:		descr = "8-bit Palette"; break;
1170ba300204SHans Verkuil 	case V4L2_PIX_FMT_UV8:		descr = "8-bit Chrominance UV 4-4"; break;
1171ba300204SHans Verkuil 	case V4L2_PIX_FMT_YVU410:	descr = "Planar YVU 4:1:0"; break;
1172ba300204SHans Verkuil 	case V4L2_PIX_FMT_YVU420:	descr = "Planar YVU 4:2:0"; break;
1173ba300204SHans Verkuil 	case V4L2_PIX_FMT_YUYV:		descr = "YUYV 4:2:2"; break;
1174ba300204SHans Verkuil 	case V4L2_PIX_FMT_YYUV:		descr = "YYUV 4:2:2"; break;
1175ba300204SHans Verkuil 	case V4L2_PIX_FMT_YVYU:		descr = "YVYU 4:2:2"; break;
1176ba300204SHans Verkuil 	case V4L2_PIX_FMT_UYVY:		descr = "UYVY 4:2:2"; break;
1177ba300204SHans Verkuil 	case V4L2_PIX_FMT_VYUY:		descr = "VYUY 4:2:2"; break;
1178fcbafafbSPhilipp Zabel 	case V4L2_PIX_FMT_YUV422P:	descr = "Planar YUV 4:2:2"; break;
1179ba300204SHans Verkuil 	case V4L2_PIX_FMT_YUV411P:	descr = "Planar YUV 4:1:1"; break;
1180ba300204SHans Verkuil 	case V4L2_PIX_FMT_Y41P:		descr = "YUV 4:1:1 (Packed)"; break;
1181ba300204SHans Verkuil 	case V4L2_PIX_FMT_YUV444:	descr = "16-bit A/XYUV 4-4-4-4"; break;
1182ba300204SHans Verkuil 	case V4L2_PIX_FMT_YUV555:	descr = "16-bit A/XYUV 1-5-5-5"; break;
1183ba300204SHans Verkuil 	case V4L2_PIX_FMT_YUV565:	descr = "16-bit YUV 5-6-5"; break;
1184ba300204SHans Verkuil 	case V4L2_PIX_FMT_YUV32:	descr = "32-bit A/XYUV 8-8-8-8"; break;
1185ba300204SHans Verkuil 	case V4L2_PIX_FMT_YUV410:	descr = "Planar YUV 4:1:0"; break;
1186ba300204SHans Verkuil 	case V4L2_PIX_FMT_YUV420:	descr = "Planar YUV 4:2:0"; break;
1187ba300204SHans Verkuil 	case V4L2_PIX_FMT_HI240:	descr = "8-bit Dithered RGB (BTTV)"; break;
1188ba300204SHans Verkuil 	case V4L2_PIX_FMT_HM12:		descr = "YUV 4:2:0 (16x16 Macroblocks)"; break;
1189ba300204SHans Verkuil 	case V4L2_PIX_FMT_M420:		descr = "YUV 4:2:0 (M420)"; break;
1190ba300204SHans Verkuil 	case V4L2_PIX_FMT_NV12:		descr = "Y/CbCr 4:2:0"; break;
1191ba300204SHans Verkuil 	case V4L2_PIX_FMT_NV21:		descr = "Y/CrCb 4:2:0"; break;
1192ba300204SHans Verkuil 	case V4L2_PIX_FMT_NV16:		descr = "Y/CbCr 4:2:2"; break;
1193ba300204SHans Verkuil 	case V4L2_PIX_FMT_NV61:		descr = "Y/CrCb 4:2:2"; break;
1194ba300204SHans Verkuil 	case V4L2_PIX_FMT_NV24:		descr = "Y/CbCr 4:4:4"; break;
1195ba300204SHans Verkuil 	case V4L2_PIX_FMT_NV42:		descr = "Y/CrCb 4:4:4"; break;
1196ba300204SHans Verkuil 	case V4L2_PIX_FMT_NV12M:	descr = "Y/CbCr 4:2:0 (N-C)"; break;
1197ba300204SHans Verkuil 	case V4L2_PIX_FMT_NV21M:	descr = "Y/CrCb 4:2:0 (N-C)"; break;
1198ba300204SHans Verkuil 	case V4L2_PIX_FMT_NV16M:	descr = "Y/CbCr 4:2:2 (N-C)"; break;
1199ba300204SHans Verkuil 	case V4L2_PIX_FMT_NV61M:	descr = "Y/CrCb 4:2:2 (N-C)"; break;
1200ba300204SHans Verkuil 	case V4L2_PIX_FMT_NV12MT:	descr = "Y/CbCr 4:2:0 (64x32 MB, N-C)"; break;
1201ba300204SHans Verkuil 	case V4L2_PIX_FMT_NV12MT_16X16:	descr = "Y/CbCr 4:2:0 (16x16 MB, N-C)"; break;
1202ba300204SHans Verkuil 	case V4L2_PIX_FMT_YUV420M:	descr = "Planar YUV 4:2:0 (N-C)"; break;
1203ba300204SHans Verkuil 	case V4L2_PIX_FMT_YVU420M:	descr = "Planar YVU 4:2:0 (N-C)"; break;
1204d65fae92SLaurent Pinchart 	case V4L2_PIX_FMT_YUV422M:	descr = "Planar YUV 4:2:2 (N-C)"; break;
1205d65fae92SLaurent Pinchart 	case V4L2_PIX_FMT_YVU422M:	descr = "Planar YVU 4:2:2 (N-C)"; break;
1206d65fae92SLaurent Pinchart 	case V4L2_PIX_FMT_YUV444M:	descr = "Planar YUV 4:4:4 (N-C)"; break;
1207d65fae92SLaurent Pinchart 	case V4L2_PIX_FMT_YVU444M:	descr = "Planar YVU 4:4:4 (N-C)"; break;
1208ba300204SHans Verkuil 	case V4L2_PIX_FMT_SBGGR8:	descr = "8-bit Bayer BGBG/GRGR"; break;
1209ba300204SHans Verkuil 	case V4L2_PIX_FMT_SGBRG8:	descr = "8-bit Bayer GBGB/RGRG"; break;
1210ba300204SHans Verkuil 	case V4L2_PIX_FMT_SGRBG8:	descr = "8-bit Bayer GRGR/BGBG"; break;
1211ba300204SHans Verkuil 	case V4L2_PIX_FMT_SRGGB8:	descr = "8-bit Bayer RGRG/GBGB"; break;
1212ba300204SHans Verkuil 	case V4L2_PIX_FMT_SBGGR10:	descr = "10-bit Bayer BGBG/GRGR"; break;
1213ba300204SHans Verkuil 	case V4L2_PIX_FMT_SGBRG10:	descr = "10-bit Bayer GBGB/RGRG"; break;
1214ba300204SHans Verkuil 	case V4L2_PIX_FMT_SGRBG10:	descr = "10-bit Bayer GRGR/BGBG"; break;
1215ba300204SHans Verkuil 	case V4L2_PIX_FMT_SRGGB10:	descr = "10-bit Bayer RGRG/GBGB"; break;
1216ba300204SHans Verkuil 	case V4L2_PIX_FMT_SBGGR12:	descr = "12-bit Bayer BGBG/GRGR"; break;
1217ba300204SHans Verkuil 	case V4L2_PIX_FMT_SGBRG12:	descr = "12-bit Bayer GBGB/RGRG"; break;
1218ba300204SHans Verkuil 	case V4L2_PIX_FMT_SGRBG12:	descr = "12-bit Bayer GRGR/BGBG"; break;
1219ba300204SHans Verkuil 	case V4L2_PIX_FMT_SRGGB12:	descr = "12-bit Bayer RGRG/GBGB"; break;
1220ba300204SHans Verkuil 	case V4L2_PIX_FMT_SBGGR10P:	descr = "10-bit Bayer BGBG/GRGR Packed"; break;
1221ba300204SHans Verkuil 	case V4L2_PIX_FMT_SGBRG10P:	descr = "10-bit Bayer GBGB/RGRG Packed"; break;
1222ba300204SHans Verkuil 	case V4L2_PIX_FMT_SGRBG10P:	descr = "10-bit Bayer GRGR/BGBG Packed"; break;
1223ba300204SHans Verkuil 	case V4L2_PIX_FMT_SRGGB10P:	descr = "10-bit Bayer RGRG/GBGB Packed"; break;
1224ba300204SHans Verkuil 	case V4L2_PIX_FMT_SBGGR10ALAW8:	descr = "8-bit Bayer BGBG/GRGR (A-law)"; break;
1225ba300204SHans Verkuil 	case V4L2_PIX_FMT_SGBRG10ALAW8:	descr = "8-bit Bayer GBGB/RGRG (A-law)"; break;
1226ba300204SHans Verkuil 	case V4L2_PIX_FMT_SGRBG10ALAW8:	descr = "8-bit Bayer GRGR/BGBG (A-law)"; break;
1227ba300204SHans Verkuil 	case V4L2_PIX_FMT_SRGGB10ALAW8:	descr = "8-bit Bayer RGRG/GBGB (A-law)"; break;
1228ba300204SHans Verkuil 	case V4L2_PIX_FMT_SBGGR10DPCM8:	descr = "8-bit Bayer BGBG/GRGR (DPCM)"; break;
1229ba300204SHans Verkuil 	case V4L2_PIX_FMT_SGBRG10DPCM8:	descr = "8-bit Bayer GBGB/RGRG (DPCM)"; break;
1230ba300204SHans Verkuil 	case V4L2_PIX_FMT_SGRBG10DPCM8:	descr = "8-bit Bayer GRGR/BGBG (DPCM)"; break;
1231ba300204SHans Verkuil 	case V4L2_PIX_FMT_SRGGB10DPCM8:	descr = "8-bit Bayer RGRG/GBGB (DPCM)"; break;
1232ba300204SHans Verkuil 	case V4L2_PIX_FMT_SBGGR16:	descr = "16-bit Bayer BGBG/GRGR (Exp.)"; break;
123399b74277SMauro Carvalho Chehab 	case V4L2_PIX_FMT_SN9C20X_I420:	descr = "GSPCA SN9C20X I420"; break;
1234ba300204SHans Verkuil 	case V4L2_PIX_FMT_SPCA501:	descr = "GSPCA SPCA501"; break;
1235ba300204SHans Verkuil 	case V4L2_PIX_FMT_SPCA505:	descr = "GSPCA SPCA505"; break;
1236ba300204SHans Verkuil 	case V4L2_PIX_FMT_SPCA508:	descr = "GSPCA SPCA508"; break;
1237ba300204SHans Verkuil 	case V4L2_PIX_FMT_STV0680:	descr = "GSPCA STV0680"; break;
1238ba300204SHans Verkuil 	case V4L2_PIX_FMT_TM6000:	descr = "A/V + VBI Mux Packet"; break;
1239ba300204SHans Verkuil 	case V4L2_PIX_FMT_CIT_YYVYUY:	descr = "GSPCA CIT YYVYUY"; break;
1240ba300204SHans Verkuil 	case V4L2_PIX_FMT_KONICA420:	descr = "GSPCA KONICA420"; break;
124148fc10aaSAntti Palosaari 	case V4L2_SDR_FMT_CU8:		descr = "Complex U8"; break;
124248fc10aaSAntti Palosaari 	case V4L2_SDR_FMT_CU16LE:	descr = "Complex U16LE"; break;
1243ba300204SHans Verkuil 	case V4L2_SDR_FMT_CS8:		descr = "Complex S8"; break;
1244ba300204SHans Verkuil 	case V4L2_SDR_FMT_CS14LE:	descr = "Complex S14LE"; break;
1245ba300204SHans Verkuil 	case V4L2_SDR_FMT_RU12LE:	descr = "Real U12LE"; break;
1246ba300204SHans Verkuil 
1247ba300204SHans Verkuil 	default:
1248ba300204SHans Verkuil 		/* Compressed formats */
1249ba300204SHans Verkuil 		flags = V4L2_FMT_FLAG_COMPRESSED;
1250ba300204SHans Verkuil 		switch (fmt->pixelformat) {
1251ba300204SHans Verkuil 		/* Max description length mask:	descr = "0123456789012345678901234567890" */
1252ba300204SHans Verkuil 		case V4L2_PIX_FMT_MJPEG:	descr = "Motion-JPEG"; break;
1253ba300204SHans Verkuil 		case V4L2_PIX_FMT_JPEG:		descr = "JFIF JPEG"; break;
1254ba300204SHans Verkuil 		case V4L2_PIX_FMT_DV:		descr = "1394"; break;
1255ba300204SHans Verkuil 		case V4L2_PIX_FMT_MPEG:		descr = "MPEG-1/2/4"; break;
1256ba300204SHans Verkuil 		case V4L2_PIX_FMT_H264:		descr = "H.264"; break;
1257ba300204SHans Verkuil 		case V4L2_PIX_FMT_H264_NO_SC:	descr = "H.264 (No Start Codes)"; break;
1258ba300204SHans Verkuil 		case V4L2_PIX_FMT_H264_MVC:	descr = "H.264 MVC"; break;
1259ba300204SHans Verkuil 		case V4L2_PIX_FMT_H263:		descr = "H.263"; break;
1260ba300204SHans Verkuil 		case V4L2_PIX_FMT_MPEG1:	descr = "MPEG-1 ES"; break;
1261ba300204SHans Verkuil 		case V4L2_PIX_FMT_MPEG2:	descr = "MPEG-2 ES"; break;
1262ba300204SHans Verkuil 		case V4L2_PIX_FMT_MPEG4:	descr = "MPEG-4 part 2 ES"; break;
1263ba300204SHans Verkuil 		case V4L2_PIX_FMT_XVID:		descr = "Xvid"; break;
1264ba300204SHans Verkuil 		case V4L2_PIX_FMT_VC1_ANNEX_G:	descr = "VC-1 (SMPTE 412M Annex G)"; break;
1265ba300204SHans Verkuil 		case V4L2_PIX_FMT_VC1_ANNEX_L:	descr = "VC-1 (SMPTE 412M Annex L)"; break;
1266ba300204SHans Verkuil 		case V4L2_PIX_FMT_VP8:		descr = "VP8"; break;
1267ba300204SHans Verkuil 		case V4L2_PIX_FMT_CPIA1:	descr = "GSPCA CPiA YUV"; break;
1268ba300204SHans Verkuil 		case V4L2_PIX_FMT_WNVA:		descr = "WNVA"; break;
1269ba300204SHans Verkuil 		case V4L2_PIX_FMT_SN9C10X:	descr = "GSPCA SN9C10X"; break;
1270ba300204SHans Verkuil 		case V4L2_PIX_FMT_PWC1:		descr = "Raw Philips Webcam Type (Old)"; break;
1271ba300204SHans Verkuil 		case V4L2_PIX_FMT_PWC2:		descr = "Raw Philips Webcam Type (New)"; break;
1272ba300204SHans Verkuil 		case V4L2_PIX_FMT_ET61X251:	descr = "GSPCA ET61X251"; break;
1273ba300204SHans Verkuil 		case V4L2_PIX_FMT_SPCA561:	descr = "GSPCA SPCA561"; break;
1274ba300204SHans Verkuil 		case V4L2_PIX_FMT_PAC207:	descr = "GSPCA PAC207"; break;
1275ba300204SHans Verkuil 		case V4L2_PIX_FMT_MR97310A:	descr = "GSPCA MR97310A"; break;
1276ba300204SHans Verkuil 		case V4L2_PIX_FMT_JL2005BCD:	descr = "GSPCA JL2005BCD"; break;
1277ba300204SHans Verkuil 		case V4L2_PIX_FMT_SN9C2028:	descr = "GSPCA SN9C2028"; break;
1278ba300204SHans Verkuil 		case V4L2_PIX_FMT_SQ905C:	descr = "GSPCA SQ905C"; break;
1279ba300204SHans Verkuil 		case V4L2_PIX_FMT_PJPG:		descr = "GSPCA PJPG"; break;
1280ba300204SHans Verkuil 		case V4L2_PIX_FMT_OV511:	descr = "GSPCA OV511"; break;
1281ba300204SHans Verkuil 		case V4L2_PIX_FMT_OV518:	descr = "GSPCA OV518"; break;
1282ba300204SHans Verkuil 		case V4L2_PIX_FMT_JPGL:		descr = "JPEG Lite"; break;
1283ba300204SHans Verkuil 		case V4L2_PIX_FMT_SE401:	descr = "GSPCA SE401"; break;
1284ba300204SHans Verkuil 		case V4L2_PIX_FMT_S5C_UYVY_JPG:	descr = "S5C73MX interleaved UYVY/JPEG"; break;
1285ba300204SHans Verkuil 		default:
1286ba300204SHans Verkuil 			WARN(1, "Unknown pixelformat 0x%08x\n", fmt->pixelformat);
1287ba300204SHans Verkuil 			if (fmt->description[0])
1288ba300204SHans Verkuil 				return;
1289ba300204SHans Verkuil 			flags = 0;
1290ba300204SHans Verkuil 			snprintf(fmt->description, sz, "%c%c%c%c%s",
1291ba300204SHans Verkuil 					(char)(fmt->pixelformat & 0x7f),
1292ba300204SHans Verkuil 					(char)((fmt->pixelformat >> 8) & 0x7f),
1293ba300204SHans Verkuil 					(char)((fmt->pixelformat >> 16) & 0x7f),
1294ba300204SHans Verkuil 					(char)((fmt->pixelformat >> 24) & 0x7f),
1295ba300204SHans Verkuil 					(fmt->pixelformat & (1 << 31)) ? "-BE" : "");
1296ba300204SHans Verkuil 			break;
1297ba300204SHans Verkuil 		}
1298ba300204SHans Verkuil 	}
1299ba300204SHans Verkuil 
1300ba300204SHans Verkuil 	if (descr)
1301ba300204SHans Verkuil 		WARN_ON(strlcpy(fmt->description, descr, sz) >= sz);
1302ba300204SHans Verkuil 	fmt->flags = flags;
1303ba300204SHans Verkuil }
1304ba300204SHans Verkuil 
13055bc3cb74SMauro Carvalho Chehab static int v4l_enum_fmt(const struct v4l2_ioctl_ops *ops,
13065bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
13075bc3cb74SMauro Carvalho Chehab {
13085bc3cb74SMauro Carvalho Chehab 	struct v4l2_fmtdesc *p = arg;
13094b20259fSHans Verkuil 	struct video_device *vfd = video_devdata(file);
1310ce71bbc9SHans Verkuil 	bool is_vid = vfd->vfl_type == VFL_TYPE_GRABBER;
1311ce71bbc9SHans Verkuil 	bool is_sdr = vfd->vfl_type == VFL_TYPE_SDR;
13124b20259fSHans Verkuil 	bool is_rx = vfd->vfl_dir != VFL_DIR_TX;
13134b20259fSHans Verkuil 	bool is_tx = vfd->vfl_dir != VFL_DIR_RX;
1314ba300204SHans Verkuil 	int ret = -EINVAL;
13155bc3cb74SMauro Carvalho Chehab 
13165bc3cb74SMauro Carvalho Chehab 	switch (p->type) {
13175bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_CAPTURE:
1318ce71bbc9SHans Verkuil 		if (unlikely(!is_rx || !is_vid || !ops->vidioc_enum_fmt_vid_cap))
13195bc3cb74SMauro Carvalho Chehab 			break;
1320ba300204SHans Verkuil 		ret = ops->vidioc_enum_fmt_vid_cap(file, fh, arg);
1321ba300204SHans Verkuil 		break;
13225bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
1323ce71bbc9SHans Verkuil 		if (unlikely(!is_rx || !is_vid || !ops->vidioc_enum_fmt_vid_cap_mplane))
13245bc3cb74SMauro Carvalho Chehab 			break;
1325ba300204SHans Verkuil 		ret = ops->vidioc_enum_fmt_vid_cap_mplane(file, fh, arg);
1326ba300204SHans Verkuil 		break;
13275bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_OVERLAY:
1328ce71bbc9SHans Verkuil 		if (unlikely(!is_rx || !is_vid || !ops->vidioc_enum_fmt_vid_overlay))
13295bc3cb74SMauro Carvalho Chehab 			break;
1330ba300204SHans Verkuil 		ret = ops->vidioc_enum_fmt_vid_overlay(file, fh, arg);
1331ba300204SHans Verkuil 		break;
13325bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_OUTPUT:
1333ce71bbc9SHans Verkuil 		if (unlikely(!is_tx || !is_vid || !ops->vidioc_enum_fmt_vid_out))
13345bc3cb74SMauro Carvalho Chehab 			break;
1335ba300204SHans Verkuil 		ret = ops->vidioc_enum_fmt_vid_out(file, fh, arg);
1336ba300204SHans Verkuil 		break;
13375bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
1338ce71bbc9SHans Verkuil 		if (unlikely(!is_tx || !is_vid || !ops->vidioc_enum_fmt_vid_out_mplane))
13395bc3cb74SMauro Carvalho Chehab 			break;
1340ba300204SHans Verkuil 		ret = ops->vidioc_enum_fmt_vid_out_mplane(file, fh, arg);
1341ba300204SHans Verkuil 		break;
1342582c52cbSAntti Palosaari 	case V4L2_BUF_TYPE_SDR_CAPTURE:
1343ce71bbc9SHans Verkuil 		if (unlikely(!is_rx || !is_sdr || !ops->vidioc_enum_fmt_sdr_cap))
1344582c52cbSAntti Palosaari 			break;
1345ba300204SHans Verkuil 		ret = ops->vidioc_enum_fmt_sdr_cap(file, fh, arg);
1346ba300204SHans Verkuil 		break;
13479effc72fSAntti Palosaari 	case V4L2_BUF_TYPE_SDR_OUTPUT:
13489effc72fSAntti Palosaari 		if (unlikely(!is_tx || !is_sdr || !ops->vidioc_enum_fmt_sdr_out))
13499effc72fSAntti Palosaari 			break;
13509effc72fSAntti Palosaari 		ret = ops->vidioc_enum_fmt_sdr_out(file, fh, arg);
13519effc72fSAntti Palosaari 		break;
13525bc3cb74SMauro Carvalho Chehab 	}
1353ba300204SHans Verkuil 	if (ret == 0)
1354ba300204SHans Verkuil 		v4l_fill_fmtdesc(p);
1355ba300204SHans Verkuil 	return ret;
13565bc3cb74SMauro Carvalho Chehab }
13575bc3cb74SMauro Carvalho Chehab 
13585bc3cb74SMauro Carvalho Chehab static int v4l_g_fmt(const struct v4l2_ioctl_ops *ops,
13595bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
13605bc3cb74SMauro Carvalho Chehab {
13615bc3cb74SMauro Carvalho Chehab 	struct v4l2_format *p = arg;
13624b20259fSHans Verkuil 	struct video_device *vfd = video_devdata(file);
13634b20259fSHans Verkuil 	bool is_vid = vfd->vfl_type == VFL_TYPE_GRABBER;
1364582c52cbSAntti Palosaari 	bool is_sdr = vfd->vfl_type == VFL_TYPE_SDR;
13654b20259fSHans Verkuil 	bool is_rx = vfd->vfl_dir != VFL_DIR_TX;
13664b20259fSHans Verkuil 	bool is_tx = vfd->vfl_dir != VFL_DIR_RX;
1367d52e2381SLaurent Pinchart 	int ret;
1368d52e2381SLaurent Pinchart 
1369e5ce558aSHans Verkuil 	/*
1370e5ce558aSHans Verkuil 	 * fmt can't be cleared for these overlay types due to the 'clips'
1371e5ce558aSHans Verkuil 	 * 'clipcount' and 'bitmap' pointers in struct v4l2_window.
1372e5ce558aSHans Verkuil 	 * Those are provided by the user. So handle these two overlay types
1373e5ce558aSHans Verkuil 	 * first, and then just do a simple memset for the other types.
1374e5ce558aSHans Verkuil 	 */
1375e5ce558aSHans Verkuil 	switch (p->type) {
1376e5ce558aSHans Verkuil 	case V4L2_BUF_TYPE_VIDEO_OVERLAY:
1377e5ce558aSHans Verkuil 	case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY: {
13784d1afa51SHans Verkuil 		struct v4l2_clip __user *clips = p->fmt.win.clips;
1379e5ce558aSHans Verkuil 		u32 clipcount = p->fmt.win.clipcount;
13804d1afa51SHans Verkuil 		void __user *bitmap = p->fmt.win.bitmap;
1381e5ce558aSHans Verkuil 
1382e5ce558aSHans Verkuil 		memset(&p->fmt, 0, sizeof(p->fmt));
1383e5ce558aSHans Verkuil 		p->fmt.win.clips = clips;
1384e5ce558aSHans Verkuil 		p->fmt.win.clipcount = clipcount;
1385e5ce558aSHans Verkuil 		p->fmt.win.bitmap = bitmap;
1386e5ce558aSHans Verkuil 		break;
1387e5ce558aSHans Verkuil 	}
1388e5ce558aSHans Verkuil 	default:
1389e5ce558aSHans Verkuil 		memset(&p->fmt, 0, sizeof(p->fmt));
1390e5ce558aSHans Verkuil 		break;
1391e5ce558aSHans Verkuil 	}
1392e5ce558aSHans Verkuil 
13935bc3cb74SMauro Carvalho Chehab 	switch (p->type) {
13945bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_CAPTURE:
13954b20259fSHans Verkuil 		if (unlikely(!is_rx || !is_vid || !ops->vidioc_g_fmt_vid_cap))
13965bc3cb74SMauro Carvalho Chehab 			break;
139748f2650aSHans Verkuil 		p->fmt.pix.priv = V4L2_PIX_FMT_PRIV_MAGIC;
1398d52e2381SLaurent Pinchart 		ret = ops->vidioc_g_fmt_vid_cap(file, fh, arg);
139948f2650aSHans Verkuil 		/* just in case the driver zeroed it again */
1400d52e2381SLaurent Pinchart 		p->fmt.pix.priv = V4L2_PIX_FMT_PRIV_MAGIC;
1401d52e2381SLaurent Pinchart 		return ret;
14025bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
14034b20259fSHans Verkuil 		if (unlikely(!is_rx || !is_vid || !ops->vidioc_g_fmt_vid_cap_mplane))
14045bc3cb74SMauro Carvalho Chehab 			break;
14055bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_g_fmt_vid_cap_mplane(file, fh, arg);
14065bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_OVERLAY:
14074b20259fSHans Verkuil 		if (unlikely(!is_rx || !is_vid || !ops->vidioc_g_fmt_vid_overlay))
14085bc3cb74SMauro Carvalho Chehab 			break;
14095bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_g_fmt_vid_overlay(file, fh, arg);
14104b20259fSHans Verkuil 	case V4L2_BUF_TYPE_VBI_CAPTURE:
14114b20259fSHans Verkuil 		if (unlikely(!is_rx || is_vid || !ops->vidioc_g_fmt_vbi_cap))
14124b20259fSHans Verkuil 			break;
14134b20259fSHans Verkuil 		return ops->vidioc_g_fmt_vbi_cap(file, fh, arg);
14144b20259fSHans Verkuil 	case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
14154b20259fSHans Verkuil 		if (unlikely(!is_rx || is_vid || !ops->vidioc_g_fmt_sliced_vbi_cap))
14164b20259fSHans Verkuil 			break;
14174b20259fSHans Verkuil 		return ops->vidioc_g_fmt_sliced_vbi_cap(file, fh, arg);
14185bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_OUTPUT:
14194b20259fSHans Verkuil 		if (unlikely(!is_tx || !is_vid || !ops->vidioc_g_fmt_vid_out))
14205bc3cb74SMauro Carvalho Chehab 			break;
142148f2650aSHans Verkuil 		p->fmt.pix.priv = V4L2_PIX_FMT_PRIV_MAGIC;
1422d52e2381SLaurent Pinchart 		ret = ops->vidioc_g_fmt_vid_out(file, fh, arg);
142348f2650aSHans Verkuil 		/* just in case the driver zeroed it again */
1424d52e2381SLaurent Pinchart 		p->fmt.pix.priv = V4L2_PIX_FMT_PRIV_MAGIC;
1425d52e2381SLaurent Pinchart 		return ret;
14265bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
14274b20259fSHans Verkuil 		if (unlikely(!is_tx || !is_vid || !ops->vidioc_g_fmt_vid_out_mplane))
14285bc3cb74SMauro Carvalho Chehab 			break;
14295bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_g_fmt_vid_out_mplane(file, fh, arg);
14305bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
14314b20259fSHans Verkuil 		if (unlikely(!is_tx || !is_vid || !ops->vidioc_g_fmt_vid_out_overlay))
14325bc3cb74SMauro Carvalho Chehab 			break;
14335bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_g_fmt_vid_out_overlay(file, fh, arg);
14345bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VBI_OUTPUT:
14354b20259fSHans Verkuil 		if (unlikely(!is_tx || is_vid || !ops->vidioc_g_fmt_vbi_out))
14365bc3cb74SMauro Carvalho Chehab 			break;
14375bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_g_fmt_vbi_out(file, fh, arg);
14385bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
14394b20259fSHans Verkuil 		if (unlikely(!is_tx || is_vid || !ops->vidioc_g_fmt_sliced_vbi_out))
14405bc3cb74SMauro Carvalho Chehab 			break;
14415bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_g_fmt_sliced_vbi_out(file, fh, arg);
1442582c52cbSAntti Palosaari 	case V4L2_BUF_TYPE_SDR_CAPTURE:
1443582c52cbSAntti Palosaari 		if (unlikely(!is_rx || !is_sdr || !ops->vidioc_g_fmt_sdr_cap))
1444582c52cbSAntti Palosaari 			break;
1445582c52cbSAntti Palosaari 		return ops->vidioc_g_fmt_sdr_cap(file, fh, arg);
14469effc72fSAntti Palosaari 	case V4L2_BUF_TYPE_SDR_OUTPUT:
14479effc72fSAntti Palosaari 		if (unlikely(!is_tx || !is_sdr || !ops->vidioc_g_fmt_sdr_out))
14489effc72fSAntti Palosaari 			break;
14499effc72fSAntti Palosaari 		return ops->vidioc_g_fmt_sdr_out(file, fh, arg);
14505bc3cb74SMauro Carvalho Chehab 	}
14515bc3cb74SMauro Carvalho Chehab 	return -EINVAL;
14525bc3cb74SMauro Carvalho Chehab }
14535bc3cb74SMauro Carvalho Chehab 
14545bc3cb74SMauro Carvalho Chehab static int v4l_s_fmt(const struct v4l2_ioctl_ops *ops,
14555bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
14565bc3cb74SMauro Carvalho Chehab {
14575bc3cb74SMauro Carvalho Chehab 	struct v4l2_format *p = arg;
14584b20259fSHans Verkuil 	struct video_device *vfd = video_devdata(file);
14594b20259fSHans Verkuil 	bool is_vid = vfd->vfl_type == VFL_TYPE_GRABBER;
1460582c52cbSAntti Palosaari 	bool is_sdr = vfd->vfl_type == VFL_TYPE_SDR;
14614b20259fSHans Verkuil 	bool is_rx = vfd->vfl_dir != VFL_DIR_TX;
14624b20259fSHans Verkuil 	bool is_tx = vfd->vfl_dir != VFL_DIR_RX;
146348f2650aSHans Verkuil 	int ret;
14645bc3cb74SMauro Carvalho Chehab 
146577fa4e07SShuah Khan 	ret = v4l_enable_media_source(vfd);
146677fa4e07SShuah Khan 	if (ret)
146777fa4e07SShuah Khan 		return ret;
1468d52e2381SLaurent Pinchart 	v4l_sanitize_format(p);
1469d52e2381SLaurent Pinchart 
14705bc3cb74SMauro Carvalho Chehab 	switch (p->type) {
14715bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_CAPTURE:
14724b20259fSHans Verkuil 		if (unlikely(!is_rx || !is_vid || !ops->vidioc_s_fmt_vid_cap))
14735bc3cb74SMauro Carvalho Chehab 			break;
14745bc3cb74SMauro Carvalho Chehab 		CLEAR_AFTER_FIELD(p, fmt.pix);
147548f2650aSHans Verkuil 		ret = ops->vidioc_s_fmt_vid_cap(file, fh, arg);
147648f2650aSHans Verkuil 		/* just in case the driver zeroed it again */
147748f2650aSHans Verkuil 		p->fmt.pix.priv = V4L2_PIX_FMT_PRIV_MAGIC;
147848f2650aSHans Verkuil 		return ret;
14795bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
14804b20259fSHans Verkuil 		if (unlikely(!is_rx || !is_vid || !ops->vidioc_s_fmt_vid_cap_mplane))
14815bc3cb74SMauro Carvalho Chehab 			break;
14825bc3cb74SMauro Carvalho Chehab 		CLEAR_AFTER_FIELD(p, fmt.pix_mp);
14835bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_s_fmt_vid_cap_mplane(file, fh, arg);
14845bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_OVERLAY:
14854b20259fSHans Verkuil 		if (unlikely(!is_rx || !is_vid || !ops->vidioc_s_fmt_vid_overlay))
14865bc3cb74SMauro Carvalho Chehab 			break;
14875bc3cb74SMauro Carvalho Chehab 		CLEAR_AFTER_FIELD(p, fmt.win);
14885bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_s_fmt_vid_overlay(file, fh, arg);
14894b20259fSHans Verkuil 	case V4L2_BUF_TYPE_VBI_CAPTURE:
14904b20259fSHans Verkuil 		if (unlikely(!is_rx || is_vid || !ops->vidioc_s_fmt_vbi_cap))
14914b20259fSHans Verkuil 			break;
14924b20259fSHans Verkuil 		CLEAR_AFTER_FIELD(p, fmt.vbi);
14934b20259fSHans Verkuil 		return ops->vidioc_s_fmt_vbi_cap(file, fh, arg);
14944b20259fSHans Verkuil 	case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
14954b20259fSHans Verkuil 		if (unlikely(!is_rx || is_vid || !ops->vidioc_s_fmt_sliced_vbi_cap))
14964b20259fSHans Verkuil 			break;
14974b20259fSHans Verkuil 		CLEAR_AFTER_FIELD(p, fmt.sliced);
14984b20259fSHans Verkuil 		return ops->vidioc_s_fmt_sliced_vbi_cap(file, fh, arg);
14995bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_OUTPUT:
15004b20259fSHans Verkuil 		if (unlikely(!is_tx || !is_vid || !ops->vidioc_s_fmt_vid_out))
15015bc3cb74SMauro Carvalho Chehab 			break;
15025bc3cb74SMauro Carvalho Chehab 		CLEAR_AFTER_FIELD(p, fmt.pix);
150348f2650aSHans Verkuil 		ret = ops->vidioc_s_fmt_vid_out(file, fh, arg);
150448f2650aSHans Verkuil 		/* just in case the driver zeroed it again */
150548f2650aSHans Verkuil 		p->fmt.pix.priv = V4L2_PIX_FMT_PRIV_MAGIC;
150648f2650aSHans Verkuil 		return ret;
15075bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
15084b20259fSHans Verkuil 		if (unlikely(!is_tx || !is_vid || !ops->vidioc_s_fmt_vid_out_mplane))
15095bc3cb74SMauro Carvalho Chehab 			break;
15105bc3cb74SMauro Carvalho Chehab 		CLEAR_AFTER_FIELD(p, fmt.pix_mp);
15115bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_s_fmt_vid_out_mplane(file, fh, arg);
15125bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
15134b20259fSHans Verkuil 		if (unlikely(!is_tx || !is_vid || !ops->vidioc_s_fmt_vid_out_overlay))
15145bc3cb74SMauro Carvalho Chehab 			break;
15155bc3cb74SMauro Carvalho Chehab 		CLEAR_AFTER_FIELD(p, fmt.win);
15165bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_s_fmt_vid_out_overlay(file, fh, arg);
15175bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VBI_OUTPUT:
15184b20259fSHans Verkuil 		if (unlikely(!is_tx || is_vid || !ops->vidioc_s_fmt_vbi_out))
15195bc3cb74SMauro Carvalho Chehab 			break;
15205bc3cb74SMauro Carvalho Chehab 		CLEAR_AFTER_FIELD(p, fmt.vbi);
15215bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_s_fmt_vbi_out(file, fh, arg);
15225bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
15234b20259fSHans Verkuil 		if (unlikely(!is_tx || is_vid || !ops->vidioc_s_fmt_sliced_vbi_out))
15245bc3cb74SMauro Carvalho Chehab 			break;
15255bc3cb74SMauro Carvalho Chehab 		CLEAR_AFTER_FIELD(p, fmt.sliced);
15265bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_s_fmt_sliced_vbi_out(file, fh, arg);
1527582c52cbSAntti Palosaari 	case V4L2_BUF_TYPE_SDR_CAPTURE:
1528582c52cbSAntti Palosaari 		if (unlikely(!is_rx || !is_sdr || !ops->vidioc_s_fmt_sdr_cap))
1529582c52cbSAntti Palosaari 			break;
1530582c52cbSAntti Palosaari 		CLEAR_AFTER_FIELD(p, fmt.sdr);
1531582c52cbSAntti Palosaari 		return ops->vidioc_s_fmt_sdr_cap(file, fh, arg);
15329effc72fSAntti Palosaari 	case V4L2_BUF_TYPE_SDR_OUTPUT:
15339effc72fSAntti Palosaari 		if (unlikely(!is_tx || !is_sdr || !ops->vidioc_s_fmt_sdr_out))
15349effc72fSAntti Palosaari 			break;
15359effc72fSAntti Palosaari 		CLEAR_AFTER_FIELD(p, fmt.sdr);
15369effc72fSAntti Palosaari 		return ops->vidioc_s_fmt_sdr_out(file, fh, arg);
15375bc3cb74SMauro Carvalho Chehab 	}
15385bc3cb74SMauro Carvalho Chehab 	return -EINVAL;
15395bc3cb74SMauro Carvalho Chehab }
15405bc3cb74SMauro Carvalho Chehab 
15415bc3cb74SMauro Carvalho Chehab static int v4l_try_fmt(const struct v4l2_ioctl_ops *ops,
15425bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
15435bc3cb74SMauro Carvalho Chehab {
15445bc3cb74SMauro Carvalho Chehab 	struct v4l2_format *p = arg;
15454b20259fSHans Verkuil 	struct video_device *vfd = video_devdata(file);
15464b20259fSHans Verkuil 	bool is_vid = vfd->vfl_type == VFL_TYPE_GRABBER;
1547582c52cbSAntti Palosaari 	bool is_sdr = vfd->vfl_type == VFL_TYPE_SDR;
15484b20259fSHans Verkuil 	bool is_rx = vfd->vfl_dir != VFL_DIR_TX;
15494b20259fSHans Verkuil 	bool is_tx = vfd->vfl_dir != VFL_DIR_RX;
155048f2650aSHans Verkuil 	int ret;
15515bc3cb74SMauro Carvalho Chehab 
1552d52e2381SLaurent Pinchart 	v4l_sanitize_format(p);
1553d52e2381SLaurent Pinchart 
15545bc3cb74SMauro Carvalho Chehab 	switch (p->type) {
15555bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_CAPTURE:
15564b20259fSHans Verkuil 		if (unlikely(!is_rx || !is_vid || !ops->vidioc_try_fmt_vid_cap))
15575bc3cb74SMauro Carvalho Chehab 			break;
15585bc3cb74SMauro Carvalho Chehab 		CLEAR_AFTER_FIELD(p, fmt.pix);
155948f2650aSHans Verkuil 		ret = ops->vidioc_try_fmt_vid_cap(file, fh, arg);
156048f2650aSHans Verkuil 		/* just in case the driver zeroed it again */
156148f2650aSHans Verkuil 		p->fmt.pix.priv = V4L2_PIX_FMT_PRIV_MAGIC;
156248f2650aSHans Verkuil 		return ret;
15635bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
15644b20259fSHans Verkuil 		if (unlikely(!is_rx || !is_vid || !ops->vidioc_try_fmt_vid_cap_mplane))
15655bc3cb74SMauro Carvalho Chehab 			break;
15665bc3cb74SMauro Carvalho Chehab 		CLEAR_AFTER_FIELD(p, fmt.pix_mp);
15675bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_try_fmt_vid_cap_mplane(file, fh, arg);
15685bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_OVERLAY:
15694b20259fSHans Verkuil 		if (unlikely(!is_rx || !is_vid || !ops->vidioc_try_fmt_vid_overlay))
15705bc3cb74SMauro Carvalho Chehab 			break;
15715bc3cb74SMauro Carvalho Chehab 		CLEAR_AFTER_FIELD(p, fmt.win);
15725bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_try_fmt_vid_overlay(file, fh, arg);
15734b20259fSHans Verkuil 	case V4L2_BUF_TYPE_VBI_CAPTURE:
15744b20259fSHans Verkuil 		if (unlikely(!is_rx || is_vid || !ops->vidioc_try_fmt_vbi_cap))
15754b20259fSHans Verkuil 			break;
15764b20259fSHans Verkuil 		CLEAR_AFTER_FIELD(p, fmt.vbi);
15774b20259fSHans Verkuil 		return ops->vidioc_try_fmt_vbi_cap(file, fh, arg);
15784b20259fSHans Verkuil 	case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
15794b20259fSHans Verkuil 		if (unlikely(!is_rx || is_vid || !ops->vidioc_try_fmt_sliced_vbi_cap))
15804b20259fSHans Verkuil 			break;
15814b20259fSHans Verkuil 		CLEAR_AFTER_FIELD(p, fmt.sliced);
15824b20259fSHans Verkuil 		return ops->vidioc_try_fmt_sliced_vbi_cap(file, fh, arg);
15835bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_OUTPUT:
15844b20259fSHans Verkuil 		if (unlikely(!is_tx || !is_vid || !ops->vidioc_try_fmt_vid_out))
15855bc3cb74SMauro Carvalho Chehab 			break;
15865bc3cb74SMauro Carvalho Chehab 		CLEAR_AFTER_FIELD(p, fmt.pix);
158748f2650aSHans Verkuil 		ret = ops->vidioc_try_fmt_vid_out(file, fh, arg);
158848f2650aSHans Verkuil 		/* just in case the driver zeroed it again */
158948f2650aSHans Verkuil 		p->fmt.pix.priv = V4L2_PIX_FMT_PRIV_MAGIC;
159048f2650aSHans Verkuil 		return ret;
15915bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
15924b20259fSHans Verkuil 		if (unlikely(!is_tx || !is_vid || !ops->vidioc_try_fmt_vid_out_mplane))
15935bc3cb74SMauro Carvalho Chehab 			break;
15945bc3cb74SMauro Carvalho Chehab 		CLEAR_AFTER_FIELD(p, fmt.pix_mp);
15955bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_try_fmt_vid_out_mplane(file, fh, arg);
15965bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
15974b20259fSHans Verkuil 		if (unlikely(!is_tx || !is_vid || !ops->vidioc_try_fmt_vid_out_overlay))
15985bc3cb74SMauro Carvalho Chehab 			break;
15995bc3cb74SMauro Carvalho Chehab 		CLEAR_AFTER_FIELD(p, fmt.win);
16005bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_try_fmt_vid_out_overlay(file, fh, arg);
16015bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VBI_OUTPUT:
16024b20259fSHans Verkuil 		if (unlikely(!is_tx || is_vid || !ops->vidioc_try_fmt_vbi_out))
16035bc3cb74SMauro Carvalho Chehab 			break;
16045bc3cb74SMauro Carvalho Chehab 		CLEAR_AFTER_FIELD(p, fmt.vbi);
16055bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_try_fmt_vbi_out(file, fh, arg);
16065bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
16074b20259fSHans Verkuil 		if (unlikely(!is_tx || is_vid || !ops->vidioc_try_fmt_sliced_vbi_out))
16085bc3cb74SMauro Carvalho Chehab 			break;
16095bc3cb74SMauro Carvalho Chehab 		CLEAR_AFTER_FIELD(p, fmt.sliced);
16105bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_try_fmt_sliced_vbi_out(file, fh, arg);
1611582c52cbSAntti Palosaari 	case V4L2_BUF_TYPE_SDR_CAPTURE:
1612582c52cbSAntti Palosaari 		if (unlikely(!is_rx || !is_sdr || !ops->vidioc_try_fmt_sdr_cap))
1613582c52cbSAntti Palosaari 			break;
1614582c52cbSAntti Palosaari 		CLEAR_AFTER_FIELD(p, fmt.sdr);
1615582c52cbSAntti Palosaari 		return ops->vidioc_try_fmt_sdr_cap(file, fh, arg);
16169effc72fSAntti Palosaari 	case V4L2_BUF_TYPE_SDR_OUTPUT:
16179effc72fSAntti Palosaari 		if (unlikely(!is_tx || !is_sdr || !ops->vidioc_try_fmt_sdr_out))
16189effc72fSAntti Palosaari 			break;
16199effc72fSAntti Palosaari 		CLEAR_AFTER_FIELD(p, fmt.sdr);
16209effc72fSAntti Palosaari 		return ops->vidioc_try_fmt_sdr_out(file, fh, arg);
16215bc3cb74SMauro Carvalho Chehab 	}
16225bc3cb74SMauro Carvalho Chehab 	return -EINVAL;
16235bc3cb74SMauro Carvalho Chehab }
16245bc3cb74SMauro Carvalho Chehab 
16255bc3cb74SMauro Carvalho Chehab static int v4l_streamon(const struct v4l2_ioctl_ops *ops,
16265bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
16275bc3cb74SMauro Carvalho Chehab {
16285bc3cb74SMauro Carvalho Chehab 	return ops->vidioc_streamon(file, fh, *(unsigned int *)arg);
16295bc3cb74SMauro Carvalho Chehab }
16305bc3cb74SMauro Carvalho Chehab 
16315bc3cb74SMauro Carvalho Chehab static int v4l_streamoff(const struct v4l2_ioctl_ops *ops,
16325bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
16335bc3cb74SMauro Carvalho Chehab {
16345bc3cb74SMauro Carvalho Chehab 	return ops->vidioc_streamoff(file, fh, *(unsigned int *)arg);
16355bc3cb74SMauro Carvalho Chehab }
16365bc3cb74SMauro Carvalho Chehab 
16375bc3cb74SMauro Carvalho Chehab static int v4l_g_tuner(const struct v4l2_ioctl_ops *ops,
16385bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
16395bc3cb74SMauro Carvalho Chehab {
16405bc3cb74SMauro Carvalho Chehab 	struct video_device *vfd = video_devdata(file);
16415bc3cb74SMauro Carvalho Chehab 	struct v4l2_tuner *p = arg;
16425bc3cb74SMauro Carvalho Chehab 	int err;
16435bc3cb74SMauro Carvalho Chehab 
16445bc3cb74SMauro Carvalho Chehab 	p->type = (vfd->vfl_type == VFL_TYPE_RADIO) ?
16455bc3cb74SMauro Carvalho Chehab 			V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV;
16465bc3cb74SMauro Carvalho Chehab 	err = ops->vidioc_g_tuner(file, fh, p);
16475bc3cb74SMauro Carvalho Chehab 	if (!err)
16485bc3cb74SMauro Carvalho Chehab 		p->capability |= V4L2_TUNER_CAP_FREQ_BANDS;
16495bc3cb74SMauro Carvalho Chehab 	return err;
16505bc3cb74SMauro Carvalho Chehab }
16515bc3cb74SMauro Carvalho Chehab 
16525bc3cb74SMauro Carvalho Chehab static int v4l_s_tuner(const struct v4l2_ioctl_ops *ops,
16535bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
16545bc3cb74SMauro Carvalho Chehab {
16555bc3cb74SMauro Carvalho Chehab 	struct video_device *vfd = video_devdata(file);
16565bc3cb74SMauro Carvalho Chehab 	struct v4l2_tuner *p = arg;
165777fa4e07SShuah Khan 	int ret;
16585bc3cb74SMauro Carvalho Chehab 
165977fa4e07SShuah Khan 	ret = v4l_enable_media_source(vfd);
166077fa4e07SShuah Khan 	if (ret)
166177fa4e07SShuah Khan 		return ret;
16625bc3cb74SMauro Carvalho Chehab 	p->type = (vfd->vfl_type == VFL_TYPE_RADIO) ?
16635bc3cb74SMauro Carvalho Chehab 			V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV;
16645bc3cb74SMauro Carvalho Chehab 	return ops->vidioc_s_tuner(file, fh, p);
16655bc3cb74SMauro Carvalho Chehab }
16665bc3cb74SMauro Carvalho Chehab 
16675bc3cb74SMauro Carvalho Chehab static int v4l_g_modulator(const struct v4l2_ioctl_ops *ops,
16685bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
16695bc3cb74SMauro Carvalho Chehab {
16704124a3c4SAntti Palosaari 	struct video_device *vfd = video_devdata(file);
16715bc3cb74SMauro Carvalho Chehab 	struct v4l2_modulator *p = arg;
16725bc3cb74SMauro Carvalho Chehab 	int err;
16735bc3cb74SMauro Carvalho Chehab 
16744124a3c4SAntti Palosaari 	if (vfd->vfl_type == VFL_TYPE_RADIO)
16754124a3c4SAntti Palosaari 		p->type = V4L2_TUNER_RADIO;
16764124a3c4SAntti Palosaari 
16775bc3cb74SMauro Carvalho Chehab 	err = ops->vidioc_g_modulator(file, fh, p);
16785bc3cb74SMauro Carvalho Chehab 	if (!err)
16795bc3cb74SMauro Carvalho Chehab 		p->capability |= V4L2_TUNER_CAP_FREQ_BANDS;
16805bc3cb74SMauro Carvalho Chehab 	return err;
16815bc3cb74SMauro Carvalho Chehab }
16825bc3cb74SMauro Carvalho Chehab 
16834124a3c4SAntti Palosaari static int v4l_s_modulator(const struct v4l2_ioctl_ops *ops,
16844124a3c4SAntti Palosaari 				struct file *file, void *fh, void *arg)
16854124a3c4SAntti Palosaari {
16864124a3c4SAntti Palosaari 	struct video_device *vfd = video_devdata(file);
16874124a3c4SAntti Palosaari 	struct v4l2_modulator *p = arg;
16884124a3c4SAntti Palosaari 
16894124a3c4SAntti Palosaari 	if (vfd->vfl_type == VFL_TYPE_RADIO)
16904124a3c4SAntti Palosaari 		p->type = V4L2_TUNER_RADIO;
16914124a3c4SAntti Palosaari 
16924124a3c4SAntti Palosaari 	return ops->vidioc_s_modulator(file, fh, p);
16934124a3c4SAntti Palosaari }
16944124a3c4SAntti Palosaari 
16955bc3cb74SMauro Carvalho Chehab static int v4l_g_frequency(const struct v4l2_ioctl_ops *ops,
16965bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
16975bc3cb74SMauro Carvalho Chehab {
16985bc3cb74SMauro Carvalho Chehab 	struct video_device *vfd = video_devdata(file);
16995bc3cb74SMauro Carvalho Chehab 	struct v4l2_frequency *p = arg;
17005bc3cb74SMauro Carvalho Chehab 
170184099a28SAntti Palosaari 	if (vfd->vfl_type == VFL_TYPE_SDR)
1702f3c3ececSAntti Palosaari 		p->type = V4L2_TUNER_SDR;
170384099a28SAntti Palosaari 	else
17045bc3cb74SMauro Carvalho Chehab 		p->type = (vfd->vfl_type == VFL_TYPE_RADIO) ?
17055bc3cb74SMauro Carvalho Chehab 				V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV;
17065bc3cb74SMauro Carvalho Chehab 	return ops->vidioc_g_frequency(file, fh, p);
17075bc3cb74SMauro Carvalho Chehab }
17085bc3cb74SMauro Carvalho Chehab 
17095bc3cb74SMauro Carvalho Chehab static int v4l_s_frequency(const struct v4l2_ioctl_ops *ops,
17105bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
17115bc3cb74SMauro Carvalho Chehab {
17125bc3cb74SMauro Carvalho Chehab 	struct video_device *vfd = video_devdata(file);
1713b530a447SHans Verkuil 	const struct v4l2_frequency *p = arg;
17145bc3cb74SMauro Carvalho Chehab 	enum v4l2_tuner_type type;
171577fa4e07SShuah Khan 	int ret;
17165bc3cb74SMauro Carvalho Chehab 
171777fa4e07SShuah Khan 	ret = v4l_enable_media_source(vfd);
171877fa4e07SShuah Khan 	if (ret)
171977fa4e07SShuah Khan 		return ret;
172084099a28SAntti Palosaari 	if (vfd->vfl_type == VFL_TYPE_SDR) {
1721f3c3ececSAntti Palosaari 		if (p->type != V4L2_TUNER_SDR && p->type != V4L2_TUNER_RF)
172284099a28SAntti Palosaari 			return -EINVAL;
172384099a28SAntti Palosaari 	} else {
17245bc3cb74SMauro Carvalho Chehab 		type = (vfd->vfl_type == VFL_TYPE_RADIO) ?
17255bc3cb74SMauro Carvalho Chehab 				V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV;
172684099a28SAntti Palosaari 		if (type != p->type)
17275bc3cb74SMauro Carvalho Chehab 			return -EINVAL;
172884099a28SAntti Palosaari 	}
17295bc3cb74SMauro Carvalho Chehab 	return ops->vidioc_s_frequency(file, fh, p);
17305bc3cb74SMauro Carvalho Chehab }
17315bc3cb74SMauro Carvalho Chehab 
17325bc3cb74SMauro Carvalho Chehab static int v4l_enumstd(const struct v4l2_ioctl_ops *ops,
17335bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
17345bc3cb74SMauro Carvalho Chehab {
17355bc3cb74SMauro Carvalho Chehab 	struct video_device *vfd = video_devdata(file);
17365bc3cb74SMauro Carvalho Chehab 	struct v4l2_standard *p = arg;
17375bc3cb74SMauro Carvalho Chehab 	v4l2_std_id id = vfd->tvnorms, curr_id = 0;
17385bc3cb74SMauro Carvalho Chehab 	unsigned int index = p->index, i, j = 0;
17395bc3cb74SMauro Carvalho Chehab 	const char *descr = "";
17405bc3cb74SMauro Carvalho Chehab 
1741a5338190SHans Verkuil 	/* Return -ENODATA if the tvnorms for the current input
1742a5338190SHans Verkuil 	   or output is 0, meaning that it doesn't support this API. */
1743a5338190SHans Verkuil 	if (id == 0)
1744a5338190SHans Verkuil 		return -ENODATA;
1745a5338190SHans Verkuil 
17465bc3cb74SMauro Carvalho Chehab 	/* Return norm array in a canonical way */
17475bc3cb74SMauro Carvalho Chehab 	for (i = 0; i <= index && id; i++) {
17485bc3cb74SMauro Carvalho Chehab 		/* last std value in the standards array is 0, so this
17495bc3cb74SMauro Carvalho Chehab 		   while always ends there since (id & 0) == 0. */
17505bc3cb74SMauro Carvalho Chehab 		while ((id & standards[j].std) != standards[j].std)
17515bc3cb74SMauro Carvalho Chehab 			j++;
17525bc3cb74SMauro Carvalho Chehab 		curr_id = standards[j].std;
17535bc3cb74SMauro Carvalho Chehab 		descr = standards[j].descr;
17545bc3cb74SMauro Carvalho Chehab 		j++;
17555bc3cb74SMauro Carvalho Chehab 		if (curr_id == 0)
17565bc3cb74SMauro Carvalho Chehab 			break;
17575bc3cb74SMauro Carvalho Chehab 		if (curr_id != V4L2_STD_PAL &&
17585bc3cb74SMauro Carvalho Chehab 				curr_id != V4L2_STD_SECAM &&
17595bc3cb74SMauro Carvalho Chehab 				curr_id != V4L2_STD_NTSC)
17605bc3cb74SMauro Carvalho Chehab 			id &= ~curr_id;
17615bc3cb74SMauro Carvalho Chehab 	}
17625bc3cb74SMauro Carvalho Chehab 	if (i <= index)
17635bc3cb74SMauro Carvalho Chehab 		return -EINVAL;
17645bc3cb74SMauro Carvalho Chehab 
17655bc3cb74SMauro Carvalho Chehab 	v4l2_video_std_construct(p, curr_id, descr);
17665bc3cb74SMauro Carvalho Chehab 	return 0;
17675bc3cb74SMauro Carvalho Chehab }
17685bc3cb74SMauro Carvalho Chehab 
17695bc3cb74SMauro Carvalho Chehab static int v4l_s_std(const struct v4l2_ioctl_ops *ops,
17705bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
17715bc3cb74SMauro Carvalho Chehab {
17725bc3cb74SMauro Carvalho Chehab 	struct video_device *vfd = video_devdata(file);
1773314527acSHans Verkuil 	v4l2_std_id id = *(v4l2_std_id *)arg, norm;
177477fa4e07SShuah Khan 	int ret;
17755bc3cb74SMauro Carvalho Chehab 
177677fa4e07SShuah Khan 	ret = v4l_enable_media_source(vfd);
177777fa4e07SShuah Khan 	if (ret)
177877fa4e07SShuah Khan 		return ret;
1779314527acSHans Verkuil 	norm = id & vfd->tvnorms;
17805bc3cb74SMauro Carvalho Chehab 	if (vfd->tvnorms && !norm)	/* Check if std is supported */
17815bc3cb74SMauro Carvalho Chehab 		return -EINVAL;
17825bc3cb74SMauro Carvalho Chehab 
17835bc3cb74SMauro Carvalho Chehab 	/* Calls the specific handler */
1784ca371575SHans Verkuil 	return ops->vidioc_s_std(file, fh, norm);
17855bc3cb74SMauro Carvalho Chehab }
17865bc3cb74SMauro Carvalho Chehab 
17875bc3cb74SMauro Carvalho Chehab static int v4l_querystd(const struct v4l2_ioctl_ops *ops,
17885bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
17895bc3cb74SMauro Carvalho Chehab {
17905bc3cb74SMauro Carvalho Chehab 	struct video_device *vfd = video_devdata(file);
17915bc3cb74SMauro Carvalho Chehab 	v4l2_std_id *p = arg;
179277fa4e07SShuah Khan 	int ret;
17935bc3cb74SMauro Carvalho Chehab 
179477fa4e07SShuah Khan 	ret = v4l_enable_media_source(vfd);
179577fa4e07SShuah Khan 	if (ret)
179677fa4e07SShuah Khan 		return ret;
17975bc3cb74SMauro Carvalho Chehab 	/*
17981a2c6866SHans Verkuil 	 * If no signal is detected, then the driver should return
17991a2c6866SHans Verkuil 	 * V4L2_STD_UNKNOWN. Otherwise it should return tvnorms with
18001a2c6866SHans Verkuil 	 * any standards that do not apply removed.
18011a2c6866SHans Verkuil 	 *
18025bc3cb74SMauro Carvalho Chehab 	 * This means that tuners, audio and video decoders can join
18035bc3cb74SMauro Carvalho Chehab 	 * their efforts to improve the standards detection.
18045bc3cb74SMauro Carvalho Chehab 	 */
18055bc3cb74SMauro Carvalho Chehab 	*p = vfd->tvnorms;
18065bc3cb74SMauro Carvalho Chehab 	return ops->vidioc_querystd(file, fh, arg);
18075bc3cb74SMauro Carvalho Chehab }
18085bc3cb74SMauro Carvalho Chehab 
18095bc3cb74SMauro Carvalho Chehab static int v4l_s_hw_freq_seek(const struct v4l2_ioctl_ops *ops,
18105bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
18115bc3cb74SMauro Carvalho Chehab {
18125bc3cb74SMauro Carvalho Chehab 	struct video_device *vfd = video_devdata(file);
18135bc3cb74SMauro Carvalho Chehab 	struct v4l2_hw_freq_seek *p = arg;
18145bc3cb74SMauro Carvalho Chehab 	enum v4l2_tuner_type type;
181577fa4e07SShuah Khan 	int ret;
18165bc3cb74SMauro Carvalho Chehab 
181777fa4e07SShuah Khan 	ret = v4l_enable_media_source(vfd);
181877fa4e07SShuah Khan 	if (ret)
181977fa4e07SShuah Khan 		return ret;
182084099a28SAntti Palosaari 	/* s_hw_freq_seek is not supported for SDR for now */
182184099a28SAntti Palosaari 	if (vfd->vfl_type == VFL_TYPE_SDR)
182284099a28SAntti Palosaari 		return -EINVAL;
182384099a28SAntti Palosaari 
18245bc3cb74SMauro Carvalho Chehab 	type = (vfd->vfl_type == VFL_TYPE_RADIO) ?
18255bc3cb74SMauro Carvalho Chehab 		V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV;
18265bc3cb74SMauro Carvalho Chehab 	if (p->type != type)
18275bc3cb74SMauro Carvalho Chehab 		return -EINVAL;
18285bc3cb74SMauro Carvalho Chehab 	return ops->vidioc_s_hw_freq_seek(file, fh, p);
18295bc3cb74SMauro Carvalho Chehab }
18305bc3cb74SMauro Carvalho Chehab 
1831737c097bSHans Verkuil static int v4l_overlay(const struct v4l2_ioctl_ops *ops,
1832737c097bSHans Verkuil 				struct file *file, void *fh, void *arg)
1833737c097bSHans Verkuil {
1834737c097bSHans Verkuil 	return ops->vidioc_overlay(file, fh, *(unsigned int *)arg);
1835737c097bSHans Verkuil }
1836737c097bSHans Verkuil 
18375bc3cb74SMauro Carvalho Chehab static int v4l_reqbufs(const struct v4l2_ioctl_ops *ops,
18385bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
18395bc3cb74SMauro Carvalho Chehab {
18405bc3cb74SMauro Carvalho Chehab 	struct v4l2_requestbuffers *p = arg;
18414b20259fSHans Verkuil 	int ret = check_fmt(file, p->type);
18425bc3cb74SMauro Carvalho Chehab 
18435bc3cb74SMauro Carvalho Chehab 	if (ret)
18445bc3cb74SMauro Carvalho Chehab 		return ret;
18455bc3cb74SMauro Carvalho Chehab 
18465bc3cb74SMauro Carvalho Chehab 	CLEAR_AFTER_FIELD(p, memory);
18475bc3cb74SMauro Carvalho Chehab 
18485bc3cb74SMauro Carvalho Chehab 	return ops->vidioc_reqbufs(file, fh, p);
18495bc3cb74SMauro Carvalho Chehab }
18505bc3cb74SMauro Carvalho Chehab 
18515bc3cb74SMauro Carvalho Chehab static int v4l_querybuf(const struct v4l2_ioctl_ops *ops,
18525bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
18535bc3cb74SMauro Carvalho Chehab {
18545bc3cb74SMauro Carvalho Chehab 	struct v4l2_buffer *p = arg;
18554b20259fSHans Verkuil 	int ret = check_fmt(file, p->type);
18565bc3cb74SMauro Carvalho Chehab 
18575bc3cb74SMauro Carvalho Chehab 	return ret ? ret : ops->vidioc_querybuf(file, fh, p);
18585bc3cb74SMauro Carvalho Chehab }
18595bc3cb74SMauro Carvalho Chehab 
18605bc3cb74SMauro Carvalho Chehab static int v4l_qbuf(const struct v4l2_ioctl_ops *ops,
18615bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
18625bc3cb74SMauro Carvalho Chehab {
18635bc3cb74SMauro Carvalho Chehab 	struct v4l2_buffer *p = arg;
18644b20259fSHans Verkuil 	int ret = check_fmt(file, p->type);
18655bc3cb74SMauro Carvalho Chehab 
18665bc3cb74SMauro Carvalho Chehab 	return ret ? ret : ops->vidioc_qbuf(file, fh, p);
18675bc3cb74SMauro Carvalho Chehab }
18685bc3cb74SMauro Carvalho Chehab 
18695bc3cb74SMauro Carvalho Chehab static int v4l_dqbuf(const struct v4l2_ioctl_ops *ops,
18705bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
18715bc3cb74SMauro Carvalho Chehab {
18725bc3cb74SMauro Carvalho Chehab 	struct v4l2_buffer *p = arg;
18734b20259fSHans Verkuil 	int ret = check_fmt(file, p->type);
18745bc3cb74SMauro Carvalho Chehab 
18755bc3cb74SMauro Carvalho Chehab 	return ret ? ret : ops->vidioc_dqbuf(file, fh, p);
18765bc3cb74SMauro Carvalho Chehab }
18775bc3cb74SMauro Carvalho Chehab 
18785bc3cb74SMauro Carvalho Chehab static int v4l_create_bufs(const struct v4l2_ioctl_ops *ops,
18795bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
18805bc3cb74SMauro Carvalho Chehab {
18815bc3cb74SMauro Carvalho Chehab 	struct v4l2_create_buffers *create = arg;
18824b20259fSHans Verkuil 	int ret = check_fmt(file, create->format.type);
18835bc3cb74SMauro Carvalho Chehab 
1884d52e2381SLaurent Pinchart 	if (ret)
1885d52e2381SLaurent Pinchart 		return ret;
1886d52e2381SLaurent Pinchart 
18875d351251SHans Verkuil 	CLEAR_AFTER_FIELD(create, format);
18885d351251SHans Verkuil 
1889d52e2381SLaurent Pinchart 	v4l_sanitize_format(&create->format);
1890d52e2381SLaurent Pinchart 
1891d52e2381SLaurent Pinchart 	ret = ops->vidioc_create_bufs(file, fh, create);
1892d52e2381SLaurent Pinchart 
1893d52e2381SLaurent Pinchart 	if (create->format.type == V4L2_BUF_TYPE_VIDEO_CAPTURE ||
1894d52e2381SLaurent Pinchart 	    create->format.type == V4L2_BUF_TYPE_VIDEO_OUTPUT)
1895d52e2381SLaurent Pinchart 		create->format.fmt.pix.priv = V4L2_PIX_FMT_PRIV_MAGIC;
1896d52e2381SLaurent Pinchart 
1897d52e2381SLaurent Pinchart 	return ret;
18985bc3cb74SMauro Carvalho Chehab }
18995bc3cb74SMauro Carvalho Chehab 
19005bc3cb74SMauro Carvalho Chehab static int v4l_prepare_buf(const struct v4l2_ioctl_ops *ops,
19015bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
19025bc3cb74SMauro Carvalho Chehab {
19035bc3cb74SMauro Carvalho Chehab 	struct v4l2_buffer *b = arg;
19044b20259fSHans Verkuil 	int ret = check_fmt(file, b->type);
19055bc3cb74SMauro Carvalho Chehab 
19065bc3cb74SMauro Carvalho Chehab 	return ret ? ret : ops->vidioc_prepare_buf(file, fh, b);
19075bc3cb74SMauro Carvalho Chehab }
19085bc3cb74SMauro Carvalho Chehab 
19095bc3cb74SMauro Carvalho Chehab static int v4l_g_parm(const struct v4l2_ioctl_ops *ops,
19105bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
19115bc3cb74SMauro Carvalho Chehab {
19125bc3cb74SMauro Carvalho Chehab 	struct v4l2_streamparm *p = arg;
19135bc3cb74SMauro Carvalho Chehab 	v4l2_std_id std;
19144b20259fSHans Verkuil 	int ret = check_fmt(file, p->type);
19155bc3cb74SMauro Carvalho Chehab 
19165bc3cb74SMauro Carvalho Chehab 	if (ret)
19175bc3cb74SMauro Carvalho Chehab 		return ret;
19185bc3cb74SMauro Carvalho Chehab 	if (ops->vidioc_g_parm)
19195bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_g_parm(file, fh, p);
19205bc3cb74SMauro Carvalho Chehab 	if (p->type != V4L2_BUF_TYPE_VIDEO_CAPTURE &&
19215bc3cb74SMauro Carvalho Chehab 	    p->type != V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
19225bc3cb74SMauro Carvalho Chehab 		return -EINVAL;
19235bc3cb74SMauro Carvalho Chehab 	p->parm.capture.readbuffers = 2;
19245bc3cb74SMauro Carvalho Chehab 	ret = ops->vidioc_g_std(file, fh, &std);
19255bc3cb74SMauro Carvalho Chehab 	if (ret == 0)
1926ca371575SHans Verkuil 		v4l2_video_std_frame_period(std, &p->parm.capture.timeperframe);
19275bc3cb74SMauro Carvalho Chehab 	return ret;
19285bc3cb74SMauro Carvalho Chehab }
19295bc3cb74SMauro Carvalho Chehab 
19305bc3cb74SMauro Carvalho Chehab static int v4l_s_parm(const struct v4l2_ioctl_ops *ops,
19315bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
19325bc3cb74SMauro Carvalho Chehab {
19335bc3cb74SMauro Carvalho Chehab 	struct v4l2_streamparm *p = arg;
19344b20259fSHans Verkuil 	int ret = check_fmt(file, p->type);
19355bc3cb74SMauro Carvalho Chehab 
19365bc3cb74SMauro Carvalho Chehab 	return ret ? ret : ops->vidioc_s_parm(file, fh, p);
19375bc3cb74SMauro Carvalho Chehab }
19385bc3cb74SMauro Carvalho Chehab 
19395bc3cb74SMauro Carvalho Chehab static int v4l_queryctrl(const struct v4l2_ioctl_ops *ops,
19405bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
19415bc3cb74SMauro Carvalho Chehab {
19425bc3cb74SMauro Carvalho Chehab 	struct video_device *vfd = video_devdata(file);
19435bc3cb74SMauro Carvalho Chehab 	struct v4l2_queryctrl *p = arg;
19445bc3cb74SMauro Carvalho Chehab 	struct v4l2_fh *vfh =
19455bc3cb74SMauro Carvalho Chehab 		test_bit(V4L2_FL_USES_V4L2_FH, &vfd->flags) ? fh : NULL;
19465bc3cb74SMauro Carvalho Chehab 
19475bc3cb74SMauro Carvalho Chehab 	if (vfh && vfh->ctrl_handler)
19485bc3cb74SMauro Carvalho Chehab 		return v4l2_queryctrl(vfh->ctrl_handler, p);
19495bc3cb74SMauro Carvalho Chehab 	if (vfd->ctrl_handler)
19505bc3cb74SMauro Carvalho Chehab 		return v4l2_queryctrl(vfd->ctrl_handler, p);
19515bc3cb74SMauro Carvalho Chehab 	if (ops->vidioc_queryctrl)
19525bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_queryctrl(file, fh, p);
19535bc3cb74SMauro Carvalho Chehab 	return -ENOTTY;
19545bc3cb74SMauro Carvalho Chehab }
19555bc3cb74SMauro Carvalho Chehab 
1956e6bee368SHans Verkuil static int v4l_query_ext_ctrl(const struct v4l2_ioctl_ops *ops,
1957e6bee368SHans Verkuil 				struct file *file, void *fh, void *arg)
1958e6bee368SHans Verkuil {
1959e6bee368SHans Verkuil 	struct video_device *vfd = video_devdata(file);
1960e6bee368SHans Verkuil 	struct v4l2_query_ext_ctrl *p = arg;
1961e6bee368SHans Verkuil 	struct v4l2_fh *vfh =
1962e6bee368SHans Verkuil 		test_bit(V4L2_FL_USES_V4L2_FH, &vfd->flags) ? fh : NULL;
1963e6bee368SHans Verkuil 
1964e6bee368SHans Verkuil 	if (vfh && vfh->ctrl_handler)
1965e6bee368SHans Verkuil 		return v4l2_query_ext_ctrl(vfh->ctrl_handler, p);
1966e6bee368SHans Verkuil 	if (vfd->ctrl_handler)
1967e6bee368SHans Verkuil 		return v4l2_query_ext_ctrl(vfd->ctrl_handler, p);
1968e6bee368SHans Verkuil 	if (ops->vidioc_query_ext_ctrl)
1969e6bee368SHans Verkuil 		return ops->vidioc_query_ext_ctrl(file, fh, p);
1970e6bee368SHans Verkuil 	return -ENOTTY;
1971e6bee368SHans Verkuil }
1972e6bee368SHans Verkuil 
19735bc3cb74SMauro Carvalho Chehab static int v4l_querymenu(const struct v4l2_ioctl_ops *ops,
19745bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
19755bc3cb74SMauro Carvalho Chehab {
19765bc3cb74SMauro Carvalho Chehab 	struct video_device *vfd = video_devdata(file);
19775bc3cb74SMauro Carvalho Chehab 	struct v4l2_querymenu *p = arg;
19785bc3cb74SMauro Carvalho Chehab 	struct v4l2_fh *vfh =
19795bc3cb74SMauro Carvalho Chehab 		test_bit(V4L2_FL_USES_V4L2_FH, &vfd->flags) ? fh : NULL;
19805bc3cb74SMauro Carvalho Chehab 
19815bc3cb74SMauro Carvalho Chehab 	if (vfh && vfh->ctrl_handler)
19825bc3cb74SMauro Carvalho Chehab 		return v4l2_querymenu(vfh->ctrl_handler, p);
19835bc3cb74SMauro Carvalho Chehab 	if (vfd->ctrl_handler)
19845bc3cb74SMauro Carvalho Chehab 		return v4l2_querymenu(vfd->ctrl_handler, p);
19855bc3cb74SMauro Carvalho Chehab 	if (ops->vidioc_querymenu)
19865bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_querymenu(file, fh, p);
19875bc3cb74SMauro Carvalho Chehab 	return -ENOTTY;
19885bc3cb74SMauro Carvalho Chehab }
19895bc3cb74SMauro Carvalho Chehab 
19905bc3cb74SMauro Carvalho Chehab static int v4l_g_ctrl(const struct v4l2_ioctl_ops *ops,
19915bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
19925bc3cb74SMauro Carvalho Chehab {
19935bc3cb74SMauro Carvalho Chehab 	struct video_device *vfd = video_devdata(file);
19945bc3cb74SMauro Carvalho Chehab 	struct v4l2_control *p = arg;
19955bc3cb74SMauro Carvalho Chehab 	struct v4l2_fh *vfh =
19965bc3cb74SMauro Carvalho Chehab 		test_bit(V4L2_FL_USES_V4L2_FH, &vfd->flags) ? fh : NULL;
19975bc3cb74SMauro Carvalho Chehab 	struct v4l2_ext_controls ctrls;
19985bc3cb74SMauro Carvalho Chehab 	struct v4l2_ext_control ctrl;
19995bc3cb74SMauro Carvalho Chehab 
20005bc3cb74SMauro Carvalho Chehab 	if (vfh && vfh->ctrl_handler)
20015bc3cb74SMauro Carvalho Chehab 		return v4l2_g_ctrl(vfh->ctrl_handler, p);
20025bc3cb74SMauro Carvalho Chehab 	if (vfd->ctrl_handler)
20035bc3cb74SMauro Carvalho Chehab 		return v4l2_g_ctrl(vfd->ctrl_handler, p);
20045bc3cb74SMauro Carvalho Chehab 	if (ops->vidioc_g_ctrl)
20055bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_g_ctrl(file, fh, p);
20065bc3cb74SMauro Carvalho Chehab 	if (ops->vidioc_g_ext_ctrls == NULL)
20075bc3cb74SMauro Carvalho Chehab 		return -ENOTTY;
20085bc3cb74SMauro Carvalho Chehab 
20090f8017beSRicardo Ribalda 	ctrls.which = V4L2_CTRL_ID2WHICH(p->id);
20105bc3cb74SMauro Carvalho Chehab 	ctrls.count = 1;
20115bc3cb74SMauro Carvalho Chehab 	ctrls.controls = &ctrl;
20125bc3cb74SMauro Carvalho Chehab 	ctrl.id = p->id;
20135bc3cb74SMauro Carvalho Chehab 	ctrl.value = p->value;
20145bc3cb74SMauro Carvalho Chehab 	if (check_ext_ctrls(&ctrls, 1)) {
20155bc3cb74SMauro Carvalho Chehab 		int ret = ops->vidioc_g_ext_ctrls(file, fh, &ctrls);
20165bc3cb74SMauro Carvalho Chehab 
20175bc3cb74SMauro Carvalho Chehab 		if (ret == 0)
20185bc3cb74SMauro Carvalho Chehab 			p->value = ctrl.value;
20195bc3cb74SMauro Carvalho Chehab 		return ret;
20205bc3cb74SMauro Carvalho Chehab 	}
20215bc3cb74SMauro Carvalho Chehab 	return -EINVAL;
20225bc3cb74SMauro Carvalho Chehab }
20235bc3cb74SMauro Carvalho Chehab 
20245bc3cb74SMauro Carvalho Chehab static int v4l_s_ctrl(const struct v4l2_ioctl_ops *ops,
20255bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
20265bc3cb74SMauro Carvalho Chehab {
20275bc3cb74SMauro Carvalho Chehab 	struct video_device *vfd = video_devdata(file);
20285bc3cb74SMauro Carvalho Chehab 	struct v4l2_control *p = arg;
20295bc3cb74SMauro Carvalho Chehab 	struct v4l2_fh *vfh =
20305bc3cb74SMauro Carvalho Chehab 		test_bit(V4L2_FL_USES_V4L2_FH, &vfd->flags) ? fh : NULL;
20315bc3cb74SMauro Carvalho Chehab 	struct v4l2_ext_controls ctrls;
20325bc3cb74SMauro Carvalho Chehab 	struct v4l2_ext_control ctrl;
20335bc3cb74SMauro Carvalho Chehab 
20345bc3cb74SMauro Carvalho Chehab 	if (vfh && vfh->ctrl_handler)
20355bc3cb74SMauro Carvalho Chehab 		return v4l2_s_ctrl(vfh, vfh->ctrl_handler, p);
20365bc3cb74SMauro Carvalho Chehab 	if (vfd->ctrl_handler)
20375bc3cb74SMauro Carvalho Chehab 		return v4l2_s_ctrl(NULL, vfd->ctrl_handler, p);
20385bc3cb74SMauro Carvalho Chehab 	if (ops->vidioc_s_ctrl)
20395bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_s_ctrl(file, fh, p);
20405bc3cb74SMauro Carvalho Chehab 	if (ops->vidioc_s_ext_ctrls == NULL)
20415bc3cb74SMauro Carvalho Chehab 		return -ENOTTY;
20425bc3cb74SMauro Carvalho Chehab 
20430f8017beSRicardo Ribalda 	ctrls.which = V4L2_CTRL_ID2WHICH(p->id);
20445bc3cb74SMauro Carvalho Chehab 	ctrls.count = 1;
20455bc3cb74SMauro Carvalho Chehab 	ctrls.controls = &ctrl;
20465bc3cb74SMauro Carvalho Chehab 	ctrl.id = p->id;
20475bc3cb74SMauro Carvalho Chehab 	ctrl.value = p->value;
20485bc3cb74SMauro Carvalho Chehab 	if (check_ext_ctrls(&ctrls, 1))
20495bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_s_ext_ctrls(file, fh, &ctrls);
20505bc3cb74SMauro Carvalho Chehab 	return -EINVAL;
20515bc3cb74SMauro Carvalho Chehab }
20525bc3cb74SMauro Carvalho Chehab 
20535bc3cb74SMauro Carvalho Chehab static int v4l_g_ext_ctrls(const struct v4l2_ioctl_ops *ops,
20545bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
20555bc3cb74SMauro Carvalho Chehab {
20565bc3cb74SMauro Carvalho Chehab 	struct video_device *vfd = video_devdata(file);
20575bc3cb74SMauro Carvalho Chehab 	struct v4l2_ext_controls *p = arg;
20585bc3cb74SMauro Carvalho Chehab 	struct v4l2_fh *vfh =
20595bc3cb74SMauro Carvalho Chehab 		test_bit(V4L2_FL_USES_V4L2_FH, &vfd->flags) ? fh : NULL;
20605bc3cb74SMauro Carvalho Chehab 
20615bc3cb74SMauro Carvalho Chehab 	p->error_idx = p->count;
20625bc3cb74SMauro Carvalho Chehab 	if (vfh && vfh->ctrl_handler)
20635bc3cb74SMauro Carvalho Chehab 		return v4l2_g_ext_ctrls(vfh->ctrl_handler, p);
20645bc3cb74SMauro Carvalho Chehab 	if (vfd->ctrl_handler)
20655bc3cb74SMauro Carvalho Chehab 		return v4l2_g_ext_ctrls(vfd->ctrl_handler, p);
20665bc3cb74SMauro Carvalho Chehab 	if (ops->vidioc_g_ext_ctrls == NULL)
20675bc3cb74SMauro Carvalho Chehab 		return -ENOTTY;
20685bc3cb74SMauro Carvalho Chehab 	return check_ext_ctrls(p, 0) ? ops->vidioc_g_ext_ctrls(file, fh, p) :
20695bc3cb74SMauro Carvalho Chehab 					-EINVAL;
20705bc3cb74SMauro Carvalho Chehab }
20715bc3cb74SMauro Carvalho Chehab 
20725bc3cb74SMauro Carvalho Chehab static int v4l_s_ext_ctrls(const struct v4l2_ioctl_ops *ops,
20735bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
20745bc3cb74SMauro Carvalho Chehab {
20755bc3cb74SMauro Carvalho Chehab 	struct video_device *vfd = video_devdata(file);
20765bc3cb74SMauro Carvalho Chehab 	struct v4l2_ext_controls *p = arg;
20775bc3cb74SMauro Carvalho Chehab 	struct v4l2_fh *vfh =
20785bc3cb74SMauro Carvalho Chehab 		test_bit(V4L2_FL_USES_V4L2_FH, &vfd->flags) ? fh : NULL;
20795bc3cb74SMauro Carvalho Chehab 
20805bc3cb74SMauro Carvalho Chehab 	p->error_idx = p->count;
20815bc3cb74SMauro Carvalho Chehab 	if (vfh && vfh->ctrl_handler)
20825bc3cb74SMauro Carvalho Chehab 		return v4l2_s_ext_ctrls(vfh, vfh->ctrl_handler, p);
20835bc3cb74SMauro Carvalho Chehab 	if (vfd->ctrl_handler)
20845bc3cb74SMauro Carvalho Chehab 		return v4l2_s_ext_ctrls(NULL, vfd->ctrl_handler, p);
20855bc3cb74SMauro Carvalho Chehab 	if (ops->vidioc_s_ext_ctrls == NULL)
20865bc3cb74SMauro Carvalho Chehab 		return -ENOTTY;
20875bc3cb74SMauro Carvalho Chehab 	return check_ext_ctrls(p, 0) ? ops->vidioc_s_ext_ctrls(file, fh, p) :
20885bc3cb74SMauro Carvalho Chehab 					-EINVAL;
20895bc3cb74SMauro Carvalho Chehab }
20905bc3cb74SMauro Carvalho Chehab 
20915bc3cb74SMauro Carvalho Chehab static int v4l_try_ext_ctrls(const struct v4l2_ioctl_ops *ops,
20925bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
20935bc3cb74SMauro Carvalho Chehab {
20945bc3cb74SMauro Carvalho Chehab 	struct video_device *vfd = video_devdata(file);
20955bc3cb74SMauro Carvalho Chehab 	struct v4l2_ext_controls *p = arg;
20965bc3cb74SMauro Carvalho Chehab 	struct v4l2_fh *vfh =
20975bc3cb74SMauro Carvalho Chehab 		test_bit(V4L2_FL_USES_V4L2_FH, &vfd->flags) ? fh : NULL;
20985bc3cb74SMauro Carvalho Chehab 
20995bc3cb74SMauro Carvalho Chehab 	p->error_idx = p->count;
21005bc3cb74SMauro Carvalho Chehab 	if (vfh && vfh->ctrl_handler)
21015bc3cb74SMauro Carvalho Chehab 		return v4l2_try_ext_ctrls(vfh->ctrl_handler, p);
21025bc3cb74SMauro Carvalho Chehab 	if (vfd->ctrl_handler)
21035bc3cb74SMauro Carvalho Chehab 		return v4l2_try_ext_ctrls(vfd->ctrl_handler, p);
21045bc3cb74SMauro Carvalho Chehab 	if (ops->vidioc_try_ext_ctrls == NULL)
21055bc3cb74SMauro Carvalho Chehab 		return -ENOTTY;
21065bc3cb74SMauro Carvalho Chehab 	return check_ext_ctrls(p, 0) ? ops->vidioc_try_ext_ctrls(file, fh, p) :
21075bc3cb74SMauro Carvalho Chehab 					-EINVAL;
21085bc3cb74SMauro Carvalho Chehab }
21095bc3cb74SMauro Carvalho Chehab 
21105bc3cb74SMauro Carvalho Chehab static int v4l_g_crop(const struct v4l2_ioctl_ops *ops,
21115bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
21125bc3cb74SMauro Carvalho Chehab {
21135bc3cb74SMauro Carvalho Chehab 	struct v4l2_crop *p = arg;
21145bc3cb74SMauro Carvalho Chehab 	struct v4l2_selection s = {
21155bc3cb74SMauro Carvalho Chehab 		.type = p->type,
21165bc3cb74SMauro Carvalho Chehab 	};
21175bc3cb74SMauro Carvalho Chehab 	int ret;
21185bc3cb74SMauro Carvalho Chehab 
21195bc3cb74SMauro Carvalho Chehab 	if (ops->vidioc_g_crop)
21205bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_g_crop(file, fh, p);
21215bc3cb74SMauro Carvalho Chehab 	/* simulate capture crop using selection api */
21225bc3cb74SMauro Carvalho Chehab 
21235bc3cb74SMauro Carvalho Chehab 	/* crop means compose for output devices */
21245bc3cb74SMauro Carvalho Chehab 	if (V4L2_TYPE_IS_OUTPUT(p->type))
21255bc3cb74SMauro Carvalho Chehab 		s.target = V4L2_SEL_TGT_COMPOSE_ACTIVE;
21265bc3cb74SMauro Carvalho Chehab 	else
21275bc3cb74SMauro Carvalho Chehab 		s.target = V4L2_SEL_TGT_CROP_ACTIVE;
21285bc3cb74SMauro Carvalho Chehab 
21295bc3cb74SMauro Carvalho Chehab 	ret = ops->vidioc_g_selection(file, fh, &s);
21305bc3cb74SMauro Carvalho Chehab 
21315bc3cb74SMauro Carvalho Chehab 	/* copying results to old structure on success */
21325bc3cb74SMauro Carvalho Chehab 	if (!ret)
21335bc3cb74SMauro Carvalho Chehab 		p->c = s.r;
21345bc3cb74SMauro Carvalho Chehab 	return ret;
21355bc3cb74SMauro Carvalho Chehab }
21365bc3cb74SMauro Carvalho Chehab 
21375bc3cb74SMauro Carvalho Chehab static int v4l_s_crop(const struct v4l2_ioctl_ops *ops,
21385bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
21395bc3cb74SMauro Carvalho Chehab {
21405bc3cb74SMauro Carvalho Chehab 	struct v4l2_crop *p = arg;
21415bc3cb74SMauro Carvalho Chehab 	struct v4l2_selection s = {
21425bc3cb74SMauro Carvalho Chehab 		.type = p->type,
21435bc3cb74SMauro Carvalho Chehab 		.r = p->c,
21445bc3cb74SMauro Carvalho Chehab 	};
21455bc3cb74SMauro Carvalho Chehab 
21465bc3cb74SMauro Carvalho Chehab 	if (ops->vidioc_s_crop)
21475bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_s_crop(file, fh, p);
21485bc3cb74SMauro Carvalho Chehab 	/* simulate capture crop using selection api */
21495bc3cb74SMauro Carvalho Chehab 
21505bc3cb74SMauro Carvalho Chehab 	/* crop means compose for output devices */
21515bc3cb74SMauro Carvalho Chehab 	if (V4L2_TYPE_IS_OUTPUT(p->type))
21525bc3cb74SMauro Carvalho Chehab 		s.target = V4L2_SEL_TGT_COMPOSE_ACTIVE;
21535bc3cb74SMauro Carvalho Chehab 	else
21545bc3cb74SMauro Carvalho Chehab 		s.target = V4L2_SEL_TGT_CROP_ACTIVE;
21555bc3cb74SMauro Carvalho Chehab 
21565bc3cb74SMauro Carvalho Chehab 	return ops->vidioc_s_selection(file, fh, &s);
21575bc3cb74SMauro Carvalho Chehab }
21585bc3cb74SMauro Carvalho Chehab 
21595bc3cb74SMauro Carvalho Chehab static int v4l_cropcap(const struct v4l2_ioctl_ops *ops,
21605bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
21615bc3cb74SMauro Carvalho Chehab {
21625bc3cb74SMauro Carvalho Chehab 	struct v4l2_cropcap *p = arg;
21639409945cSHans Verkuil 
21649409945cSHans Verkuil 	if (ops->vidioc_g_selection) {
21655bc3cb74SMauro Carvalho Chehab 		struct v4l2_selection s = { .type = p->type };
21665bc3cb74SMauro Carvalho Chehab 		int ret;
21675bc3cb74SMauro Carvalho Chehab 
21685bc3cb74SMauro Carvalho Chehab 		/* obtaining bounds */
21695bc3cb74SMauro Carvalho Chehab 		if (V4L2_TYPE_IS_OUTPUT(p->type))
21705bc3cb74SMauro Carvalho Chehab 			s.target = V4L2_SEL_TGT_COMPOSE_BOUNDS;
21715bc3cb74SMauro Carvalho Chehab 		else
21725bc3cb74SMauro Carvalho Chehab 			s.target = V4L2_SEL_TGT_CROP_BOUNDS;
21735bc3cb74SMauro Carvalho Chehab 
21745bc3cb74SMauro Carvalho Chehab 		ret = ops->vidioc_g_selection(file, fh, &s);
21755bc3cb74SMauro Carvalho Chehab 		if (ret)
21765bc3cb74SMauro Carvalho Chehab 			return ret;
21775bc3cb74SMauro Carvalho Chehab 		p->bounds = s.r;
21785bc3cb74SMauro Carvalho Chehab 
21795bc3cb74SMauro Carvalho Chehab 		/* obtaining defrect */
21805bc3cb74SMauro Carvalho Chehab 		if (V4L2_TYPE_IS_OUTPUT(p->type))
21815bc3cb74SMauro Carvalho Chehab 			s.target = V4L2_SEL_TGT_COMPOSE_DEFAULT;
21825bc3cb74SMauro Carvalho Chehab 		else
21835bc3cb74SMauro Carvalho Chehab 			s.target = V4L2_SEL_TGT_CROP_DEFAULT;
21845bc3cb74SMauro Carvalho Chehab 
21855bc3cb74SMauro Carvalho Chehab 		ret = ops->vidioc_g_selection(file, fh, &s);
21865bc3cb74SMauro Carvalho Chehab 		if (ret)
21875bc3cb74SMauro Carvalho Chehab 			return ret;
21885bc3cb74SMauro Carvalho Chehab 		p->defrect = s.r;
21899409945cSHans Verkuil 	}
21905bc3cb74SMauro Carvalho Chehab 
21915bc3cb74SMauro Carvalho Chehab 	/* setting trivial pixelaspect */
21925bc3cb74SMauro Carvalho Chehab 	p->pixelaspect.numerator = 1;
21935bc3cb74SMauro Carvalho Chehab 	p->pixelaspect.denominator = 1;
21949409945cSHans Verkuil 
21959409945cSHans Verkuil 	if (ops->vidioc_cropcap)
21969409945cSHans Verkuil 		return ops->vidioc_cropcap(file, fh, p);
21979409945cSHans Verkuil 
21985bc3cb74SMauro Carvalho Chehab 	return 0;
21995bc3cb74SMauro Carvalho Chehab }
22005bc3cb74SMauro Carvalho Chehab 
22015bc3cb74SMauro Carvalho Chehab static int v4l_log_status(const struct v4l2_ioctl_ops *ops,
22025bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
22035bc3cb74SMauro Carvalho Chehab {
22045bc3cb74SMauro Carvalho Chehab 	struct video_device *vfd = video_devdata(file);
22055bc3cb74SMauro Carvalho Chehab 	int ret;
22065bc3cb74SMauro Carvalho Chehab 
22075bc3cb74SMauro Carvalho Chehab 	if (vfd->v4l2_dev)
22085bc3cb74SMauro Carvalho Chehab 		pr_info("%s: =================  START STATUS  =================\n",
22095bc3cb74SMauro Carvalho Chehab 			vfd->v4l2_dev->name);
22105bc3cb74SMauro Carvalho Chehab 	ret = ops->vidioc_log_status(file, fh);
22115bc3cb74SMauro Carvalho Chehab 	if (vfd->v4l2_dev)
22125bc3cb74SMauro Carvalho Chehab 		pr_info("%s: ==================  END STATUS  ==================\n",
22135bc3cb74SMauro Carvalho Chehab 			vfd->v4l2_dev->name);
22145bc3cb74SMauro Carvalho Chehab 	return ret;
22155bc3cb74SMauro Carvalho Chehab }
22165bc3cb74SMauro Carvalho Chehab 
22175bc3cb74SMauro Carvalho Chehab static int v4l_dbg_g_register(const struct v4l2_ioctl_ops *ops,
22185bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
22195bc3cb74SMauro Carvalho Chehab {
22205bc3cb74SMauro Carvalho Chehab #ifdef CONFIG_VIDEO_ADV_DEBUG
22215bc3cb74SMauro Carvalho Chehab 	struct v4l2_dbg_register *p = arg;
222279b0c640SHans Verkuil 	struct video_device *vfd = video_devdata(file);
222379b0c640SHans Verkuil 	struct v4l2_subdev *sd;
222479b0c640SHans Verkuil 	int idx = 0;
22255bc3cb74SMauro Carvalho Chehab 
22265bc3cb74SMauro Carvalho Chehab 	if (!capable(CAP_SYS_ADMIN))
22275bc3cb74SMauro Carvalho Chehab 		return -EPERM;
22283eef2510SHans Verkuil 	if (p->match.type == V4L2_CHIP_MATCH_SUBDEV) {
222979b0c640SHans Verkuil 		if (vfd->v4l2_dev == NULL)
223079b0c640SHans Verkuil 			return -EINVAL;
22313eef2510SHans Verkuil 		v4l2_device_for_each_subdev(sd, vfd->v4l2_dev)
22323eef2510SHans Verkuil 			if (p->match.addr == idx++)
223379b0c640SHans Verkuil 				return v4l2_subdev_call(sd, core, g_register, p);
223479b0c640SHans Verkuil 		return -EINVAL;
223579b0c640SHans Verkuil 	}
2236191b79b0SHans Verkuil 	if (ops->vidioc_g_register && p->match.type == V4L2_CHIP_MATCH_BRIDGE &&
2237191b79b0SHans Verkuil 	    (ops->vidioc_g_chip_info || p->match.addr == 0))
22385bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_g_register(file, fh, p);
223979b0c640SHans Verkuil 	return -EINVAL;
22405bc3cb74SMauro Carvalho Chehab #else
22415bc3cb74SMauro Carvalho Chehab 	return -ENOTTY;
22425bc3cb74SMauro Carvalho Chehab #endif
22435bc3cb74SMauro Carvalho Chehab }
22445bc3cb74SMauro Carvalho Chehab 
22455bc3cb74SMauro Carvalho Chehab static int v4l_dbg_s_register(const struct v4l2_ioctl_ops *ops,
22465bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
22475bc3cb74SMauro Carvalho Chehab {
22485bc3cb74SMauro Carvalho Chehab #ifdef CONFIG_VIDEO_ADV_DEBUG
2249977ba3b1SHans Verkuil 	const struct v4l2_dbg_register *p = arg;
225079b0c640SHans Verkuil 	struct video_device *vfd = video_devdata(file);
225179b0c640SHans Verkuil 	struct v4l2_subdev *sd;
225279b0c640SHans Verkuil 	int idx = 0;
22535bc3cb74SMauro Carvalho Chehab 
22545bc3cb74SMauro Carvalho Chehab 	if (!capable(CAP_SYS_ADMIN))
22555bc3cb74SMauro Carvalho Chehab 		return -EPERM;
22563eef2510SHans Verkuil 	if (p->match.type == V4L2_CHIP_MATCH_SUBDEV) {
225779b0c640SHans Verkuil 		if (vfd->v4l2_dev == NULL)
225879b0c640SHans Verkuil 			return -EINVAL;
22593eef2510SHans Verkuil 		v4l2_device_for_each_subdev(sd, vfd->v4l2_dev)
22603eef2510SHans Verkuil 			if (p->match.addr == idx++)
226179b0c640SHans Verkuil 				return v4l2_subdev_call(sd, core, s_register, p);
226279b0c640SHans Verkuil 		return -EINVAL;
226379b0c640SHans Verkuil 	}
2264191b79b0SHans Verkuil 	if (ops->vidioc_s_register && p->match.type == V4L2_CHIP_MATCH_BRIDGE &&
2265191b79b0SHans Verkuil 	    (ops->vidioc_g_chip_info || p->match.addr == 0))
22665bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_s_register(file, fh, p);
226779b0c640SHans Verkuil 	return -EINVAL;
22685bc3cb74SMauro Carvalho Chehab #else
22695bc3cb74SMauro Carvalho Chehab 	return -ENOTTY;
22705bc3cb74SMauro Carvalho Chehab #endif
22715bc3cb74SMauro Carvalho Chehab }
22725bc3cb74SMauro Carvalho Chehab 
227396b03d2aSHans Verkuil static int v4l_dbg_g_chip_info(const struct v4l2_ioctl_ops *ops,
227479b0c640SHans Verkuil 				struct file *file, void *fh, void *arg)
227579b0c640SHans Verkuil {
2276cd634f1bSHans Verkuil #ifdef CONFIG_VIDEO_ADV_DEBUG
227779b0c640SHans Verkuil 	struct video_device *vfd = video_devdata(file);
227896b03d2aSHans Verkuil 	struct v4l2_dbg_chip_info *p = arg;
227979b0c640SHans Verkuil 	struct v4l2_subdev *sd;
228079b0c640SHans Verkuil 	int idx = 0;
228179b0c640SHans Verkuil 
228279b0c640SHans Verkuil 	switch (p->match.type) {
228379b0c640SHans Verkuil 	case V4L2_CHIP_MATCH_BRIDGE:
228479b0c640SHans Verkuil 		if (ops->vidioc_s_register)
228579b0c640SHans Verkuil 			p->flags |= V4L2_CHIP_FL_WRITABLE;
228679b0c640SHans Verkuil 		if (ops->vidioc_g_register)
228779b0c640SHans Verkuil 			p->flags |= V4L2_CHIP_FL_READABLE;
228879b0c640SHans Verkuil 		strlcpy(p->name, vfd->v4l2_dev->name, sizeof(p->name));
228996b03d2aSHans Verkuil 		if (ops->vidioc_g_chip_info)
229096b03d2aSHans Verkuil 			return ops->vidioc_g_chip_info(file, fh, arg);
22910f0fe4b9SHans Verkuil 		if (p->match.addr)
22920f0fe4b9SHans Verkuil 			return -EINVAL;
229379b0c640SHans Verkuil 		return 0;
229479b0c640SHans Verkuil 
22953eef2510SHans Verkuil 	case V4L2_CHIP_MATCH_SUBDEV:
229679b0c640SHans Verkuil 		if (vfd->v4l2_dev == NULL)
229779b0c640SHans Verkuil 			break;
229879b0c640SHans Verkuil 		v4l2_device_for_each_subdev(sd, vfd->v4l2_dev) {
22993eef2510SHans Verkuil 			if (p->match.addr != idx++)
23003eef2510SHans Verkuil 				continue;
230179b0c640SHans Verkuil 			if (sd->ops->core && sd->ops->core->s_register)
230279b0c640SHans Verkuil 				p->flags |= V4L2_CHIP_FL_WRITABLE;
230379b0c640SHans Verkuil 			if (sd->ops->core && sd->ops->core->g_register)
230479b0c640SHans Verkuil 				p->flags |= V4L2_CHIP_FL_READABLE;
230579b0c640SHans Verkuil 			strlcpy(p->name, sd->name, sizeof(p->name));
230679b0c640SHans Verkuil 			return 0;
230779b0c640SHans Verkuil 		}
230879b0c640SHans Verkuil 		break;
230979b0c640SHans Verkuil 	}
231079b0c640SHans Verkuil 	return -EINVAL;
2311cd634f1bSHans Verkuil #else
2312cd634f1bSHans Verkuil 	return -ENOTTY;
2313cd634f1bSHans Verkuil #endif
231479b0c640SHans Verkuil }
231579b0c640SHans Verkuil 
23165bc3cb74SMauro Carvalho Chehab static int v4l_dqevent(const struct v4l2_ioctl_ops *ops,
23175bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
23185bc3cb74SMauro Carvalho Chehab {
23195bc3cb74SMauro Carvalho Chehab 	return v4l2_event_dequeue(fh, arg, file->f_flags & O_NONBLOCK);
23205bc3cb74SMauro Carvalho Chehab }
23215bc3cb74SMauro Carvalho Chehab 
23225bc3cb74SMauro Carvalho Chehab static int v4l_subscribe_event(const struct v4l2_ioctl_ops *ops,
23235bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
23245bc3cb74SMauro Carvalho Chehab {
23255bc3cb74SMauro Carvalho Chehab 	return ops->vidioc_subscribe_event(fh, arg);
23265bc3cb74SMauro Carvalho Chehab }
23275bc3cb74SMauro Carvalho Chehab 
23285bc3cb74SMauro Carvalho Chehab static int v4l_unsubscribe_event(const struct v4l2_ioctl_ops *ops,
23295bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
23305bc3cb74SMauro Carvalho Chehab {
23315bc3cb74SMauro Carvalho Chehab 	return ops->vidioc_unsubscribe_event(fh, arg);
23325bc3cb74SMauro Carvalho Chehab }
23335bc3cb74SMauro Carvalho Chehab 
23345bc3cb74SMauro Carvalho Chehab static int v4l_g_sliced_vbi_cap(const struct v4l2_ioctl_ops *ops,
23355bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
23365bc3cb74SMauro Carvalho Chehab {
23375bc3cb74SMauro Carvalho Chehab 	struct v4l2_sliced_vbi_cap *p = arg;
23384b20259fSHans Verkuil 	int ret = check_fmt(file, p->type);
23394b20259fSHans Verkuil 
23404b20259fSHans Verkuil 	if (ret)
23414b20259fSHans Verkuil 		return ret;
23425bc3cb74SMauro Carvalho Chehab 
23435bc3cb74SMauro Carvalho Chehab 	/* Clear up to type, everything after type is zeroed already */
23445bc3cb74SMauro Carvalho Chehab 	memset(p, 0, offsetof(struct v4l2_sliced_vbi_cap, type));
23455bc3cb74SMauro Carvalho Chehab 
23465bc3cb74SMauro Carvalho Chehab 	return ops->vidioc_g_sliced_vbi_cap(file, fh, p);
23475bc3cb74SMauro Carvalho Chehab }
23485bc3cb74SMauro Carvalho Chehab 
23495bc3cb74SMauro Carvalho Chehab static int v4l_enum_freq_bands(const struct v4l2_ioctl_ops *ops,
23505bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
23515bc3cb74SMauro Carvalho Chehab {
23525bc3cb74SMauro Carvalho Chehab 	struct video_device *vfd = video_devdata(file);
23535bc3cb74SMauro Carvalho Chehab 	struct v4l2_frequency_band *p = arg;
23545bc3cb74SMauro Carvalho Chehab 	enum v4l2_tuner_type type;
23555bc3cb74SMauro Carvalho Chehab 	int err;
23565bc3cb74SMauro Carvalho Chehab 
235784099a28SAntti Palosaari 	if (vfd->vfl_type == VFL_TYPE_SDR) {
2358f3c3ececSAntti Palosaari 		if (p->type != V4L2_TUNER_SDR && p->type != V4L2_TUNER_RF)
235984099a28SAntti Palosaari 			return -EINVAL;
236084099a28SAntti Palosaari 		type = p->type;
236184099a28SAntti Palosaari 	} else {
23625bc3cb74SMauro Carvalho Chehab 		type = (vfd->vfl_type == VFL_TYPE_RADIO) ?
23635bc3cb74SMauro Carvalho Chehab 				V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV;
23645bc3cb74SMauro Carvalho Chehab 		if (type != p->type)
23655bc3cb74SMauro Carvalho Chehab 			return -EINVAL;
236684099a28SAntti Palosaari 	}
2367a7f404afSHans Verkuil 	if (ops->vidioc_enum_freq_bands) {
2368a7f404afSHans Verkuil 		err = ops->vidioc_enum_freq_bands(file, fh, p);
2369a7f404afSHans Verkuil 		if (err != -ENOTTY)
2370a7f404afSHans Verkuil 			return err;
2371a7f404afSHans Verkuil 	}
237273f35418SHans Verkuil 	if (is_valid_ioctl(vfd, VIDIOC_G_TUNER)) {
23735bc3cb74SMauro Carvalho Chehab 		struct v4l2_tuner t = {
23745bc3cb74SMauro Carvalho Chehab 			.index = p->tuner,
23755bc3cb74SMauro Carvalho Chehab 			.type = type,
23765bc3cb74SMauro Carvalho Chehab 		};
23775bc3cb74SMauro Carvalho Chehab 
237879e8c7beSMauro Carvalho Chehab 		if (p->index)
237979e8c7beSMauro Carvalho Chehab 			return -EINVAL;
23805bc3cb74SMauro Carvalho Chehab 		err = ops->vidioc_g_tuner(file, fh, &t);
23815bc3cb74SMauro Carvalho Chehab 		if (err)
23825bc3cb74SMauro Carvalho Chehab 			return err;
23835bc3cb74SMauro Carvalho Chehab 		p->capability = t.capability | V4L2_TUNER_CAP_FREQ_BANDS;
23845bc3cb74SMauro Carvalho Chehab 		p->rangelow = t.rangelow;
23855bc3cb74SMauro Carvalho Chehab 		p->rangehigh = t.rangehigh;
23865bc3cb74SMauro Carvalho Chehab 		p->modulation = (type == V4L2_TUNER_RADIO) ?
23875bc3cb74SMauro Carvalho Chehab 			V4L2_BAND_MODULATION_FM : V4L2_BAND_MODULATION_VSB;
23885bc3cb74SMauro Carvalho Chehab 		return 0;
23895bc3cb74SMauro Carvalho Chehab 	}
239073f35418SHans Verkuil 	if (is_valid_ioctl(vfd, VIDIOC_G_MODULATOR)) {
23915bc3cb74SMauro Carvalho Chehab 		struct v4l2_modulator m = {
23925bc3cb74SMauro Carvalho Chehab 			.index = p->tuner,
23935bc3cb74SMauro Carvalho Chehab 		};
23945bc3cb74SMauro Carvalho Chehab 
23955bc3cb74SMauro Carvalho Chehab 		if (type != V4L2_TUNER_RADIO)
23965bc3cb74SMauro Carvalho Chehab 			return -EINVAL;
239779e8c7beSMauro Carvalho Chehab 		if (p->index)
239879e8c7beSMauro Carvalho Chehab 			return -EINVAL;
23995bc3cb74SMauro Carvalho Chehab 		err = ops->vidioc_g_modulator(file, fh, &m);
24005bc3cb74SMauro Carvalho Chehab 		if (err)
24015bc3cb74SMauro Carvalho Chehab 			return err;
24025bc3cb74SMauro Carvalho Chehab 		p->capability = m.capability | V4L2_TUNER_CAP_FREQ_BANDS;
24035bc3cb74SMauro Carvalho Chehab 		p->rangelow = m.rangelow;
24045bc3cb74SMauro Carvalho Chehab 		p->rangehigh = m.rangehigh;
24055bc3cb74SMauro Carvalho Chehab 		p->modulation = (type == V4L2_TUNER_RADIO) ?
24065bc3cb74SMauro Carvalho Chehab 			V4L2_BAND_MODULATION_FM : V4L2_BAND_MODULATION_VSB;
24075bc3cb74SMauro Carvalho Chehab 		return 0;
24085bc3cb74SMauro Carvalho Chehab 	}
24095bc3cb74SMauro Carvalho Chehab 	return -ENOTTY;
24105bc3cb74SMauro Carvalho Chehab }
24115bc3cb74SMauro Carvalho Chehab 
24125bc3cb74SMauro Carvalho Chehab struct v4l2_ioctl_info {
24135bc3cb74SMauro Carvalho Chehab 	unsigned int ioctl;
24145bc3cb74SMauro Carvalho Chehab 	u32 flags;
24155bc3cb74SMauro Carvalho Chehab 	const char * const name;
24165bc3cb74SMauro Carvalho Chehab 	union {
24175bc3cb74SMauro Carvalho Chehab 		u32 offset;
24185bc3cb74SMauro Carvalho Chehab 		int (*func)(const struct v4l2_ioctl_ops *ops,
24195bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *p);
24205bc3cb74SMauro Carvalho Chehab 	} u;
24215bc3cb74SMauro Carvalho Chehab 	void (*debug)(const void *arg, bool write_only);
24225bc3cb74SMauro Carvalho Chehab };
24235bc3cb74SMauro Carvalho Chehab 
24245bc3cb74SMauro Carvalho Chehab /* This control needs a priority check */
24255bc3cb74SMauro Carvalho Chehab #define INFO_FL_PRIO	(1 << 0)
24265bc3cb74SMauro Carvalho Chehab /* This control can be valid if the filehandle passes a control handler. */
24275bc3cb74SMauro Carvalho Chehab #define INFO_FL_CTRL	(1 << 1)
24285bc3cb74SMauro Carvalho Chehab /* This is a standard ioctl, no need for special code */
24295bc3cb74SMauro Carvalho Chehab #define INFO_FL_STD	(1 << 2)
24305bc3cb74SMauro Carvalho Chehab /* This is ioctl has its own function */
24315bc3cb74SMauro Carvalho Chehab #define INFO_FL_FUNC	(1 << 3)
24325bc3cb74SMauro Carvalho Chehab /* Queuing ioctl */
24335bc3cb74SMauro Carvalho Chehab #define INFO_FL_QUEUE	(1 << 4)
24345bc3cb74SMauro Carvalho Chehab /* Zero struct from after the field to the end */
24355bc3cb74SMauro Carvalho Chehab #define INFO_FL_CLEAR(v4l2_struct, field)			\
24365bc3cb74SMauro Carvalho Chehab 	((offsetof(struct v4l2_struct, field) +			\
24375bc3cb74SMauro Carvalho Chehab 	  sizeof(((struct v4l2_struct *)0)->field)) << 16)
24385bc3cb74SMauro Carvalho Chehab #define INFO_FL_CLEAR_MASK (_IOC_SIZEMASK << 16)
24395bc3cb74SMauro Carvalho Chehab 
24405bc3cb74SMauro Carvalho Chehab #define IOCTL_INFO_STD(_ioctl, _vidioc, _debug, _flags)			\
24415bc3cb74SMauro Carvalho Chehab 	[_IOC_NR(_ioctl)] = {						\
24425bc3cb74SMauro Carvalho Chehab 		.ioctl = _ioctl,					\
24435bc3cb74SMauro Carvalho Chehab 		.flags = _flags | INFO_FL_STD,				\
24445bc3cb74SMauro Carvalho Chehab 		.name = #_ioctl,					\
24455bc3cb74SMauro Carvalho Chehab 		.u.offset = offsetof(struct v4l2_ioctl_ops, _vidioc),	\
24465bc3cb74SMauro Carvalho Chehab 		.debug = _debug,					\
24475bc3cb74SMauro Carvalho Chehab 	}
24485bc3cb74SMauro Carvalho Chehab 
24495bc3cb74SMauro Carvalho Chehab #define IOCTL_INFO_FNC(_ioctl, _func, _debug, _flags)			\
24505bc3cb74SMauro Carvalho Chehab 	[_IOC_NR(_ioctl)] = {						\
24515bc3cb74SMauro Carvalho Chehab 		.ioctl = _ioctl,					\
24525bc3cb74SMauro Carvalho Chehab 		.flags = _flags | INFO_FL_FUNC,				\
24535bc3cb74SMauro Carvalho Chehab 		.name = #_ioctl,					\
24545bc3cb74SMauro Carvalho Chehab 		.u.func = _func,					\
24555bc3cb74SMauro Carvalho Chehab 		.debug = _debug,					\
24565bc3cb74SMauro Carvalho Chehab 	}
24575bc3cb74SMauro Carvalho Chehab 
24585bc3cb74SMauro Carvalho Chehab static struct v4l2_ioctl_info v4l2_ioctls[] = {
24595bc3cb74SMauro Carvalho Chehab 	IOCTL_INFO_FNC(VIDIOC_QUERYCAP, v4l_querycap, v4l_print_querycap, 0),
24605bc3cb74SMauro Carvalho Chehab 	IOCTL_INFO_FNC(VIDIOC_ENUM_FMT, v4l_enum_fmt, v4l_print_fmtdesc, INFO_FL_CLEAR(v4l2_fmtdesc, type)),
2461e5ce558aSHans Verkuil 	IOCTL_INFO_FNC(VIDIOC_G_FMT, v4l_g_fmt, v4l_print_format, 0),
24625bc3cb74SMauro Carvalho Chehab 	IOCTL_INFO_FNC(VIDIOC_S_FMT, v4l_s_fmt, v4l_print_format, INFO_FL_PRIO),
24635bc3cb74SMauro Carvalho Chehab 	IOCTL_INFO_FNC(VIDIOC_REQBUFS, v4l_reqbufs, v4l_print_requestbuffers, INFO_FL_PRIO | INFO_FL_QUEUE),
24645bc3cb74SMauro Carvalho Chehab 	IOCTL_INFO_FNC(VIDIOC_QUERYBUF, v4l_querybuf, v4l_print_buffer, INFO_FL_QUEUE | INFO_FL_CLEAR(v4l2_buffer, length)),
24655bc3cb74SMauro Carvalho Chehab 	IOCTL_INFO_STD(VIDIOC_G_FBUF, vidioc_g_fbuf, v4l_print_framebuffer, 0),
24665bc3cb74SMauro Carvalho Chehab 	IOCTL_INFO_STD(VIDIOC_S_FBUF, vidioc_s_fbuf, v4l_print_framebuffer, INFO_FL_PRIO),
2467737c097bSHans Verkuil 	IOCTL_INFO_FNC(VIDIOC_OVERLAY, v4l_overlay, v4l_print_u32, INFO_FL_PRIO),
24685bc3cb74SMauro Carvalho Chehab 	IOCTL_INFO_FNC(VIDIOC_QBUF, v4l_qbuf, v4l_print_buffer, INFO_FL_QUEUE),
2469b799d09aSTomasz Stanislawski 	IOCTL_INFO_STD(VIDIOC_EXPBUF, vidioc_expbuf, v4l_print_exportbuffer, INFO_FL_QUEUE | INFO_FL_CLEAR(v4l2_exportbuffer, flags)),
24705bc3cb74SMauro Carvalho Chehab 	IOCTL_INFO_FNC(VIDIOC_DQBUF, v4l_dqbuf, v4l_print_buffer, INFO_FL_QUEUE),
24715bc3cb74SMauro Carvalho Chehab 	IOCTL_INFO_FNC(VIDIOC_STREAMON, v4l_streamon, v4l_print_buftype, INFO_FL_PRIO | INFO_FL_QUEUE),
24725bc3cb74SMauro Carvalho Chehab 	IOCTL_INFO_FNC(VIDIOC_STREAMOFF, v4l_streamoff, v4l_print_buftype, INFO_FL_PRIO | INFO_FL_QUEUE),
24735bc3cb74SMauro Carvalho Chehab 	IOCTL_INFO_FNC(VIDIOC_G_PARM, v4l_g_parm, v4l_print_streamparm, INFO_FL_CLEAR(v4l2_streamparm, type)),
24745bc3cb74SMauro Carvalho Chehab 	IOCTL_INFO_FNC(VIDIOC_S_PARM, v4l_s_parm, v4l_print_streamparm, INFO_FL_PRIO),
2475ca371575SHans Verkuil 	IOCTL_INFO_STD(VIDIOC_G_STD, vidioc_g_std, v4l_print_std, 0),
24765bc3cb74SMauro Carvalho Chehab 	IOCTL_INFO_FNC(VIDIOC_S_STD, v4l_s_std, v4l_print_std, INFO_FL_PRIO),
24775bc3cb74SMauro Carvalho Chehab 	IOCTL_INFO_FNC(VIDIOC_ENUMSTD, v4l_enumstd, v4l_print_standard, INFO_FL_CLEAR(v4l2_standard, index)),
24785bc3cb74SMauro Carvalho Chehab 	IOCTL_INFO_FNC(VIDIOC_ENUMINPUT, v4l_enuminput, v4l_print_enuminput, INFO_FL_CLEAR(v4l2_input, index)),
24795bc3cb74SMauro Carvalho Chehab 	IOCTL_INFO_FNC(VIDIOC_G_CTRL, v4l_g_ctrl, v4l_print_control, INFO_FL_CTRL | INFO_FL_CLEAR(v4l2_control, id)),
24805bc3cb74SMauro Carvalho Chehab 	IOCTL_INFO_FNC(VIDIOC_S_CTRL, v4l_s_ctrl, v4l_print_control, INFO_FL_PRIO | INFO_FL_CTRL),
24815bc3cb74SMauro Carvalho Chehab 	IOCTL_INFO_FNC(VIDIOC_G_TUNER, v4l_g_tuner, v4l_print_tuner, INFO_FL_CLEAR(v4l2_tuner, index)),
24825bc3cb74SMauro Carvalho Chehab 	IOCTL_INFO_FNC(VIDIOC_S_TUNER, v4l_s_tuner, v4l_print_tuner, INFO_FL_PRIO),
24835bc3cb74SMauro Carvalho Chehab 	IOCTL_INFO_STD(VIDIOC_G_AUDIO, vidioc_g_audio, v4l_print_audio, 0),
24845bc3cb74SMauro Carvalho Chehab 	IOCTL_INFO_STD(VIDIOC_S_AUDIO, vidioc_s_audio, v4l_print_audio, INFO_FL_PRIO),
24855bc3cb74SMauro Carvalho Chehab 	IOCTL_INFO_FNC(VIDIOC_QUERYCTRL, v4l_queryctrl, v4l_print_queryctrl, INFO_FL_CTRL | INFO_FL_CLEAR(v4l2_queryctrl, id)),
24865bc3cb74SMauro Carvalho Chehab 	IOCTL_INFO_FNC(VIDIOC_QUERYMENU, v4l_querymenu, v4l_print_querymenu, INFO_FL_CTRL | INFO_FL_CLEAR(v4l2_querymenu, index)),
24875bc3cb74SMauro Carvalho Chehab 	IOCTL_INFO_STD(VIDIOC_G_INPUT, vidioc_g_input, v4l_print_u32, 0),
24885bc3cb74SMauro Carvalho Chehab 	IOCTL_INFO_FNC(VIDIOC_S_INPUT, v4l_s_input, v4l_print_u32, INFO_FL_PRIO),
2489f9402a94SHans Verkuil 	IOCTL_INFO_STD(VIDIOC_G_EDID, vidioc_g_edid, v4l_print_edid, 0),
2490f9402a94SHans Verkuil 	IOCTL_INFO_STD(VIDIOC_S_EDID, vidioc_s_edid, v4l_print_edid, INFO_FL_PRIO),
24915bc3cb74SMauro Carvalho Chehab 	IOCTL_INFO_STD(VIDIOC_G_OUTPUT, vidioc_g_output, v4l_print_u32, 0),
24925bc3cb74SMauro Carvalho Chehab 	IOCTL_INFO_FNC(VIDIOC_S_OUTPUT, v4l_s_output, v4l_print_u32, INFO_FL_PRIO),
24935bc3cb74SMauro Carvalho Chehab 	IOCTL_INFO_FNC(VIDIOC_ENUMOUTPUT, v4l_enumoutput, v4l_print_enumoutput, INFO_FL_CLEAR(v4l2_output, index)),
24945bc3cb74SMauro Carvalho Chehab 	IOCTL_INFO_STD(VIDIOC_G_AUDOUT, vidioc_g_audout, v4l_print_audioout, 0),
24955bc3cb74SMauro Carvalho Chehab 	IOCTL_INFO_STD(VIDIOC_S_AUDOUT, vidioc_s_audout, v4l_print_audioout, INFO_FL_PRIO),
24965bc3cb74SMauro Carvalho Chehab 	IOCTL_INFO_FNC(VIDIOC_G_MODULATOR, v4l_g_modulator, v4l_print_modulator, INFO_FL_CLEAR(v4l2_modulator, index)),
24974124a3c4SAntti Palosaari 	IOCTL_INFO_FNC(VIDIOC_S_MODULATOR, v4l_s_modulator, v4l_print_modulator, INFO_FL_PRIO),
24985bc3cb74SMauro Carvalho Chehab 	IOCTL_INFO_FNC(VIDIOC_G_FREQUENCY, v4l_g_frequency, v4l_print_frequency, INFO_FL_CLEAR(v4l2_frequency, tuner)),
24995bc3cb74SMauro Carvalho Chehab 	IOCTL_INFO_FNC(VIDIOC_S_FREQUENCY, v4l_s_frequency, v4l_print_frequency, INFO_FL_PRIO),
25005bc3cb74SMauro Carvalho Chehab 	IOCTL_INFO_FNC(VIDIOC_CROPCAP, v4l_cropcap, v4l_print_cropcap, INFO_FL_CLEAR(v4l2_cropcap, type)),
25015bc3cb74SMauro Carvalho Chehab 	IOCTL_INFO_FNC(VIDIOC_G_CROP, v4l_g_crop, v4l_print_crop, INFO_FL_CLEAR(v4l2_crop, type)),
25025bc3cb74SMauro Carvalho Chehab 	IOCTL_INFO_FNC(VIDIOC_S_CROP, v4l_s_crop, v4l_print_crop, INFO_FL_PRIO),
2503865c4642SHans Verkuil 	IOCTL_INFO_STD(VIDIOC_G_SELECTION, vidioc_g_selection, v4l_print_selection, INFO_FL_CLEAR(v4l2_selection, r)),
2504865c4642SHans Verkuil 	IOCTL_INFO_STD(VIDIOC_S_SELECTION, vidioc_s_selection, v4l_print_selection, INFO_FL_PRIO | INFO_FL_CLEAR(v4l2_selection, r)),
25055bc3cb74SMauro Carvalho Chehab 	IOCTL_INFO_STD(VIDIOC_G_JPEGCOMP, vidioc_g_jpegcomp, v4l_print_jpegcompression, 0),
25065bc3cb74SMauro Carvalho Chehab 	IOCTL_INFO_STD(VIDIOC_S_JPEGCOMP, vidioc_s_jpegcomp, v4l_print_jpegcompression, INFO_FL_PRIO),
25075bc3cb74SMauro Carvalho Chehab 	IOCTL_INFO_FNC(VIDIOC_QUERYSTD, v4l_querystd, v4l_print_std, 0),
25085bc3cb74SMauro Carvalho Chehab 	IOCTL_INFO_FNC(VIDIOC_TRY_FMT, v4l_try_fmt, v4l_print_format, 0),
25095bc3cb74SMauro Carvalho Chehab 	IOCTL_INFO_STD(VIDIOC_ENUMAUDIO, vidioc_enumaudio, v4l_print_audio, INFO_FL_CLEAR(v4l2_audio, index)),
25105bc3cb74SMauro Carvalho Chehab 	IOCTL_INFO_STD(VIDIOC_ENUMAUDOUT, vidioc_enumaudout, v4l_print_audioout, INFO_FL_CLEAR(v4l2_audioout, index)),
25115bc3cb74SMauro Carvalho Chehab 	IOCTL_INFO_FNC(VIDIOC_G_PRIORITY, v4l_g_priority, v4l_print_u32, 0),
25125bc3cb74SMauro Carvalho Chehab 	IOCTL_INFO_FNC(VIDIOC_S_PRIORITY, v4l_s_priority, v4l_print_u32, INFO_FL_PRIO),
25135bc3cb74SMauro Carvalho Chehab 	IOCTL_INFO_FNC(VIDIOC_G_SLICED_VBI_CAP, v4l_g_sliced_vbi_cap, v4l_print_sliced_vbi_cap, INFO_FL_CLEAR(v4l2_sliced_vbi_cap, type)),
25145bc3cb74SMauro Carvalho Chehab 	IOCTL_INFO_FNC(VIDIOC_LOG_STATUS, v4l_log_status, v4l_print_newline, 0),
25155bc3cb74SMauro Carvalho Chehab 	IOCTL_INFO_FNC(VIDIOC_G_EXT_CTRLS, v4l_g_ext_ctrls, v4l_print_ext_controls, INFO_FL_CTRL),
25165bc3cb74SMauro Carvalho Chehab 	IOCTL_INFO_FNC(VIDIOC_S_EXT_CTRLS, v4l_s_ext_ctrls, v4l_print_ext_controls, INFO_FL_PRIO | INFO_FL_CTRL),
25175bc3cb74SMauro Carvalho Chehab 	IOCTL_INFO_FNC(VIDIOC_TRY_EXT_CTRLS, v4l_try_ext_ctrls, v4l_print_ext_controls, INFO_FL_CTRL),
25185bc3cb74SMauro Carvalho Chehab 	IOCTL_INFO_STD(VIDIOC_ENUM_FRAMESIZES, vidioc_enum_framesizes, v4l_print_frmsizeenum, INFO_FL_CLEAR(v4l2_frmsizeenum, pixel_format)),
25195bc3cb74SMauro Carvalho Chehab 	IOCTL_INFO_STD(VIDIOC_ENUM_FRAMEINTERVALS, vidioc_enum_frameintervals, v4l_print_frmivalenum, INFO_FL_CLEAR(v4l2_frmivalenum, height)),
25205bc3cb74SMauro Carvalho Chehab 	IOCTL_INFO_STD(VIDIOC_G_ENC_INDEX, vidioc_g_enc_index, v4l_print_enc_idx, 0),
25215bc3cb74SMauro Carvalho Chehab 	IOCTL_INFO_STD(VIDIOC_ENCODER_CMD, vidioc_encoder_cmd, v4l_print_encoder_cmd, INFO_FL_PRIO | INFO_FL_CLEAR(v4l2_encoder_cmd, flags)),
25225bc3cb74SMauro Carvalho Chehab 	IOCTL_INFO_STD(VIDIOC_TRY_ENCODER_CMD, vidioc_try_encoder_cmd, v4l_print_encoder_cmd, INFO_FL_CLEAR(v4l2_encoder_cmd, flags)),
25235bc3cb74SMauro Carvalho Chehab 	IOCTL_INFO_STD(VIDIOC_DECODER_CMD, vidioc_decoder_cmd, v4l_print_decoder_cmd, INFO_FL_PRIO),
25245bc3cb74SMauro Carvalho Chehab 	IOCTL_INFO_STD(VIDIOC_TRY_DECODER_CMD, vidioc_try_decoder_cmd, v4l_print_decoder_cmd, 0),
25255bc3cb74SMauro Carvalho Chehab 	IOCTL_INFO_FNC(VIDIOC_DBG_S_REGISTER, v4l_dbg_s_register, v4l_print_dbg_register, 0),
25265bc3cb74SMauro Carvalho Chehab 	IOCTL_INFO_FNC(VIDIOC_DBG_G_REGISTER, v4l_dbg_g_register, v4l_print_dbg_register, 0),
25275bc3cb74SMauro Carvalho Chehab 	IOCTL_INFO_FNC(VIDIOC_S_HW_FREQ_SEEK, v4l_s_hw_freq_seek, v4l_print_hw_freq_seek, INFO_FL_PRIO),
25285bc3cb74SMauro Carvalho Chehab 	IOCTL_INFO_STD(VIDIOC_S_DV_TIMINGS, vidioc_s_dv_timings, v4l_print_dv_timings, INFO_FL_PRIO),
25295bc3cb74SMauro Carvalho Chehab 	IOCTL_INFO_STD(VIDIOC_G_DV_TIMINGS, vidioc_g_dv_timings, v4l_print_dv_timings, 0),
25305bc3cb74SMauro Carvalho Chehab 	IOCTL_INFO_FNC(VIDIOC_DQEVENT, v4l_dqevent, v4l_print_event, 0),
25315bc3cb74SMauro Carvalho Chehab 	IOCTL_INFO_FNC(VIDIOC_SUBSCRIBE_EVENT, v4l_subscribe_event, v4l_print_event_subscription, 0),
25325bc3cb74SMauro Carvalho Chehab 	IOCTL_INFO_FNC(VIDIOC_UNSUBSCRIBE_EVENT, v4l_unsubscribe_event, v4l_print_event_subscription, 0),
25335bc3cb74SMauro Carvalho Chehab 	IOCTL_INFO_FNC(VIDIOC_CREATE_BUFS, v4l_create_bufs, v4l_print_create_buffers, INFO_FL_PRIO | INFO_FL_QUEUE),
25345bc3cb74SMauro Carvalho Chehab 	IOCTL_INFO_FNC(VIDIOC_PREPARE_BUF, v4l_prepare_buf, v4l_print_buffer, INFO_FL_QUEUE),
25355bc3cb74SMauro Carvalho Chehab 	IOCTL_INFO_STD(VIDIOC_ENUM_DV_TIMINGS, vidioc_enum_dv_timings, v4l_print_enum_dv_timings, 0),
25365bc3cb74SMauro Carvalho Chehab 	IOCTL_INFO_STD(VIDIOC_QUERY_DV_TIMINGS, vidioc_query_dv_timings, v4l_print_dv_timings, 0),
25375bc3cb74SMauro Carvalho Chehab 	IOCTL_INFO_STD(VIDIOC_DV_TIMINGS_CAP, vidioc_dv_timings_cap, v4l_print_dv_timings_cap, INFO_FL_CLEAR(v4l2_dv_timings_cap, type)),
25385bc3cb74SMauro Carvalho Chehab 	IOCTL_INFO_FNC(VIDIOC_ENUM_FREQ_BANDS, v4l_enum_freq_bands, v4l_print_freq_band, 0),
253996b03d2aSHans Verkuil 	IOCTL_INFO_FNC(VIDIOC_DBG_G_CHIP_INFO, v4l_dbg_g_chip_info, v4l_print_dbg_chip_info, INFO_FL_CLEAR(v4l2_dbg_chip_info, match)),
2540e6bee368SHans Verkuil 	IOCTL_INFO_FNC(VIDIOC_QUERY_EXT_CTRL, v4l_query_ext_ctrl, v4l_print_query_ext_ctrl, INFO_FL_CTRL | INFO_FL_CLEAR(v4l2_query_ext_ctrl, id)),
25415bc3cb74SMauro Carvalho Chehab };
25425bc3cb74SMauro Carvalho Chehab #define V4L2_IOCTLS ARRAY_SIZE(v4l2_ioctls)
25435bc3cb74SMauro Carvalho Chehab 
25445bc3cb74SMauro Carvalho Chehab bool v4l2_is_known_ioctl(unsigned int cmd)
25455bc3cb74SMauro Carvalho Chehab {
25465bc3cb74SMauro Carvalho Chehab 	if (_IOC_NR(cmd) >= V4L2_IOCTLS)
25475bc3cb74SMauro Carvalho Chehab 		return false;
25485bc3cb74SMauro Carvalho Chehab 	return v4l2_ioctls[_IOC_NR(cmd)].ioctl == cmd;
25495bc3cb74SMauro Carvalho Chehab }
25505bc3cb74SMauro Carvalho Chehab 
25515bc3cb74SMauro Carvalho Chehab struct mutex *v4l2_ioctl_get_lock(struct video_device *vdev, unsigned cmd)
25525bc3cb74SMauro Carvalho Chehab {
25535bc3cb74SMauro Carvalho Chehab 	if (_IOC_NR(cmd) >= V4L2_IOCTLS)
25545bc3cb74SMauro Carvalho Chehab 		return vdev->lock;
25555bc3cb74SMauro Carvalho Chehab 	if (test_bit(_IOC_NR(cmd), vdev->disable_locking))
25565bc3cb74SMauro Carvalho Chehab 		return NULL;
25575bc3cb74SMauro Carvalho Chehab 	if (vdev->queue && vdev->queue->lock &&
25585bc3cb74SMauro Carvalho Chehab 			(v4l2_ioctls[_IOC_NR(cmd)].flags & INFO_FL_QUEUE))
25595bc3cb74SMauro Carvalho Chehab 		return vdev->queue->lock;
25605bc3cb74SMauro Carvalho Chehab 	return vdev->lock;
25615bc3cb74SMauro Carvalho Chehab }
25625bc3cb74SMauro Carvalho Chehab 
25635bc3cb74SMauro Carvalho Chehab /* Common ioctl debug function. This function can be used by
25645bc3cb74SMauro Carvalho Chehab    external ioctl messages as well as internal V4L ioctl */
25655bc3cb74SMauro Carvalho Chehab void v4l_printk_ioctl(const char *prefix, unsigned int cmd)
25665bc3cb74SMauro Carvalho Chehab {
25675bc3cb74SMauro Carvalho Chehab 	const char *dir, *type;
25685bc3cb74SMauro Carvalho Chehab 
25695bc3cb74SMauro Carvalho Chehab 	if (prefix)
25705bc3cb74SMauro Carvalho Chehab 		printk(KERN_DEBUG "%s: ", prefix);
25715bc3cb74SMauro Carvalho Chehab 
25725bc3cb74SMauro Carvalho Chehab 	switch (_IOC_TYPE(cmd)) {
25735bc3cb74SMauro Carvalho Chehab 	case 'd':
25745bc3cb74SMauro Carvalho Chehab 		type = "v4l2_int";
25755bc3cb74SMauro Carvalho Chehab 		break;
25765bc3cb74SMauro Carvalho Chehab 	case 'V':
25775bc3cb74SMauro Carvalho Chehab 		if (_IOC_NR(cmd) >= V4L2_IOCTLS) {
25785bc3cb74SMauro Carvalho Chehab 			type = "v4l2";
25795bc3cb74SMauro Carvalho Chehab 			break;
25805bc3cb74SMauro Carvalho Chehab 		}
25815bc3cb74SMauro Carvalho Chehab 		pr_cont("%s", v4l2_ioctls[_IOC_NR(cmd)].name);
25825bc3cb74SMauro Carvalho Chehab 		return;
25835bc3cb74SMauro Carvalho Chehab 	default:
25845bc3cb74SMauro Carvalho Chehab 		type = "unknown";
25855bc3cb74SMauro Carvalho Chehab 		break;
25865bc3cb74SMauro Carvalho Chehab 	}
25875bc3cb74SMauro Carvalho Chehab 
25885bc3cb74SMauro Carvalho Chehab 	switch (_IOC_DIR(cmd)) {
25895bc3cb74SMauro Carvalho Chehab 	case _IOC_NONE:              dir = "--"; break;
25905bc3cb74SMauro Carvalho Chehab 	case _IOC_READ:              dir = "r-"; break;
25915bc3cb74SMauro Carvalho Chehab 	case _IOC_WRITE:             dir = "-w"; break;
25925bc3cb74SMauro Carvalho Chehab 	case _IOC_READ | _IOC_WRITE: dir = "rw"; break;
25935bc3cb74SMauro Carvalho Chehab 	default:                     dir = "*ERR*"; break;
25945bc3cb74SMauro Carvalho Chehab 	}
25955bc3cb74SMauro Carvalho Chehab 	pr_cont("%s ioctl '%c', dir=%s, #%d (0x%08x)",
25965bc3cb74SMauro Carvalho Chehab 		type, _IOC_TYPE(cmd), dir, _IOC_NR(cmd), cmd);
25975bc3cb74SMauro Carvalho Chehab }
25985bc3cb74SMauro Carvalho Chehab EXPORT_SYMBOL(v4l_printk_ioctl);
25995bc3cb74SMauro Carvalho Chehab 
26005bc3cb74SMauro Carvalho Chehab static long __video_do_ioctl(struct file *file,
26015bc3cb74SMauro Carvalho Chehab 		unsigned int cmd, void *arg)
26025bc3cb74SMauro Carvalho Chehab {
26035bc3cb74SMauro Carvalho Chehab 	struct video_device *vfd = video_devdata(file);
26045bc3cb74SMauro Carvalho Chehab 	const struct v4l2_ioctl_ops *ops = vfd->ioctl_ops;
26055bc3cb74SMauro Carvalho Chehab 	bool write_only = false;
26065bc3cb74SMauro Carvalho Chehab 	struct v4l2_ioctl_info default_info;
26075bc3cb74SMauro Carvalho Chehab 	const struct v4l2_ioctl_info *info;
26085bc3cb74SMauro Carvalho Chehab 	void *fh = file->private_data;
26095bc3cb74SMauro Carvalho Chehab 	struct v4l2_fh *vfh = NULL;
261017028cdbSHans Verkuil 	int dev_debug = vfd->dev_debug;
26115bc3cb74SMauro Carvalho Chehab 	long ret = -ENOTTY;
26125bc3cb74SMauro Carvalho Chehab 
26135bc3cb74SMauro Carvalho Chehab 	if (ops == NULL) {
26145bc3cb74SMauro Carvalho Chehab 		pr_warn("%s: has no ioctl_ops.\n",
26155bc3cb74SMauro Carvalho Chehab 				video_device_node_name(vfd));
26165bc3cb74SMauro Carvalho Chehab 		return ret;
26175bc3cb74SMauro Carvalho Chehab 	}
26185bc3cb74SMauro Carvalho Chehab 
2619b7284bb0SRamakrishnan Muthukrishnan 	if (test_bit(V4L2_FL_USES_V4L2_FH, &vfd->flags))
26205bc3cb74SMauro Carvalho Chehab 		vfh = file->private_data;
26215bc3cb74SMauro Carvalho Chehab 
26225bc3cb74SMauro Carvalho Chehab 	if (v4l2_is_known_ioctl(cmd)) {
26235bc3cb74SMauro Carvalho Chehab 		info = &v4l2_ioctls[_IOC_NR(cmd)];
26245bc3cb74SMauro Carvalho Chehab 
26255bc3cb74SMauro Carvalho Chehab 		if (!test_bit(_IOC_NR(cmd), vfd->valid_ioctls) &&
26265bc3cb74SMauro Carvalho Chehab 		    !((info->flags & INFO_FL_CTRL) && vfh && vfh->ctrl_handler))
26275bc3cb74SMauro Carvalho Chehab 			goto done;
26285bc3cb74SMauro Carvalho Chehab 
2629b7284bb0SRamakrishnan Muthukrishnan 		if (vfh && (info->flags & INFO_FL_PRIO)) {
26305bc3cb74SMauro Carvalho Chehab 			ret = v4l2_prio_check(vfd->prio, vfh->prio);
26315bc3cb74SMauro Carvalho Chehab 			if (ret)
26325bc3cb74SMauro Carvalho Chehab 				goto done;
26335bc3cb74SMauro Carvalho Chehab 		}
26345bc3cb74SMauro Carvalho Chehab 	} else {
26355bc3cb74SMauro Carvalho Chehab 		default_info.ioctl = cmd;
26365bc3cb74SMauro Carvalho Chehab 		default_info.flags = 0;
26375bc3cb74SMauro Carvalho Chehab 		default_info.debug = v4l_print_default;
26385bc3cb74SMauro Carvalho Chehab 		info = &default_info;
26395bc3cb74SMauro Carvalho Chehab 	}
26405bc3cb74SMauro Carvalho Chehab 
26415bc3cb74SMauro Carvalho Chehab 	write_only = _IOC_DIR(cmd) == _IOC_WRITE;
26425bc3cb74SMauro Carvalho Chehab 	if (info->flags & INFO_FL_STD) {
26435bc3cb74SMauro Carvalho Chehab 		typedef int (*vidioc_op)(struct file *file, void *fh, void *p);
26445bc3cb74SMauro Carvalho Chehab 		const void *p = vfd->ioctl_ops;
26455bc3cb74SMauro Carvalho Chehab 		const vidioc_op *vidioc = p + info->u.offset;
26465bc3cb74SMauro Carvalho Chehab 
26475bc3cb74SMauro Carvalho Chehab 		ret = (*vidioc)(file, fh, arg);
26485bc3cb74SMauro Carvalho Chehab 	} else if (info->flags & INFO_FL_FUNC) {
26495bc3cb74SMauro Carvalho Chehab 		ret = info->u.func(ops, file, fh, arg);
26505bc3cb74SMauro Carvalho Chehab 	} else if (!ops->vidioc_default) {
26515bc3cb74SMauro Carvalho Chehab 		ret = -ENOTTY;
26525bc3cb74SMauro Carvalho Chehab 	} else {
26535bc3cb74SMauro Carvalho Chehab 		ret = ops->vidioc_default(file, fh,
2654b7284bb0SRamakrishnan Muthukrishnan 			vfh ? v4l2_prio_check(vfd->prio, vfh->prio) >= 0 : 0,
26555bc3cb74SMauro Carvalho Chehab 			cmd, arg);
26565bc3cb74SMauro Carvalho Chehab 	}
26575bc3cb74SMauro Carvalho Chehab 
26585bc3cb74SMauro Carvalho Chehab done:
265917028cdbSHans Verkuil 	if (dev_debug & (V4L2_DEV_DEBUG_IOCTL | V4L2_DEV_DEBUG_IOCTL_ARG)) {
266017028cdbSHans Verkuil 		if (!(dev_debug & V4L2_DEV_DEBUG_STREAMING) &&
266117028cdbSHans Verkuil 		    (cmd == VIDIOC_QBUF || cmd == VIDIOC_DQBUF))
266217028cdbSHans Verkuil 			return ret;
266317028cdbSHans Verkuil 
26645bc3cb74SMauro Carvalho Chehab 		v4l_printk_ioctl(video_device_node_name(vfd), cmd);
26655bc3cb74SMauro Carvalho Chehab 		if (ret < 0)
2666505d04bdSHans Verkuil 			pr_cont(": error %ld", ret);
266717028cdbSHans Verkuil 		if (!(dev_debug & V4L2_DEV_DEBUG_IOCTL_ARG))
26685bc3cb74SMauro Carvalho Chehab 			pr_cont("\n");
26695bc3cb74SMauro Carvalho Chehab 		else if (_IOC_DIR(cmd) == _IOC_NONE)
26705bc3cb74SMauro Carvalho Chehab 			info->debug(arg, write_only);
26715bc3cb74SMauro Carvalho Chehab 		else {
26725bc3cb74SMauro Carvalho Chehab 			pr_cont(": ");
26735bc3cb74SMauro Carvalho Chehab 			info->debug(arg, write_only);
26745bc3cb74SMauro Carvalho Chehab 		}
26755bc3cb74SMauro Carvalho Chehab 	}
26765bc3cb74SMauro Carvalho Chehab 
26775bc3cb74SMauro Carvalho Chehab 	return ret;
26785bc3cb74SMauro Carvalho Chehab }
26795bc3cb74SMauro Carvalho Chehab 
26805bc3cb74SMauro Carvalho Chehab static int check_array_args(unsigned int cmd, void *parg, size_t *array_size,
2681ba2d35c1SHans Verkuil 			    void __user **user_ptr, void ***kernel_ptr)
26825bc3cb74SMauro Carvalho Chehab {
26835bc3cb74SMauro Carvalho Chehab 	int ret = 0;
26845bc3cb74SMauro Carvalho Chehab 
26855bc3cb74SMauro Carvalho Chehab 	switch (cmd) {
268696b1a702SHans Verkuil 	case VIDIOC_PREPARE_BUF:
26875bc3cb74SMauro Carvalho Chehab 	case VIDIOC_QUERYBUF:
26885bc3cb74SMauro Carvalho Chehab 	case VIDIOC_QBUF:
26895bc3cb74SMauro Carvalho Chehab 	case VIDIOC_DQBUF: {
26905bc3cb74SMauro Carvalho Chehab 		struct v4l2_buffer *buf = parg;
26915bc3cb74SMauro Carvalho Chehab 
26925bc3cb74SMauro Carvalho Chehab 		if (V4L2_TYPE_IS_MULTIPLANAR(buf->type) && buf->length > 0) {
26935bc3cb74SMauro Carvalho Chehab 			if (buf->length > VIDEO_MAX_PLANES) {
26945bc3cb74SMauro Carvalho Chehab 				ret = -EINVAL;
26955bc3cb74SMauro Carvalho Chehab 				break;
26965bc3cb74SMauro Carvalho Chehab 			}
26975bc3cb74SMauro Carvalho Chehab 			*user_ptr = (void __user *)buf->m.planes;
2698ba2d35c1SHans Verkuil 			*kernel_ptr = (void **)&buf->m.planes;
26995bc3cb74SMauro Carvalho Chehab 			*array_size = sizeof(struct v4l2_plane) * buf->length;
27005bc3cb74SMauro Carvalho Chehab 			ret = 1;
27015bc3cb74SMauro Carvalho Chehab 		}
27025bc3cb74SMauro Carvalho Chehab 		break;
27035bc3cb74SMauro Carvalho Chehab 	}
27045bc3cb74SMauro Carvalho Chehab 
2705dd519bb3SHans Verkuil 	case VIDIOC_G_EDID:
2706dd519bb3SHans Verkuil 	case VIDIOC_S_EDID: {
2707dd519bb3SHans Verkuil 		struct v4l2_edid *edid = parg;
2708ed45ce2cSHans Verkuil 
2709ed45ce2cSHans Verkuil 		if (edid->blocks) {
27101b8b10ccSHans Verkuil 			if (edid->blocks > 256) {
27111b8b10ccSHans Verkuil 				ret = -EINVAL;
27121b8b10ccSHans Verkuil 				break;
27131b8b10ccSHans Verkuil 			}
2714ed45ce2cSHans Verkuil 			*user_ptr = (void __user *)edid->edid;
2715ba2d35c1SHans Verkuil 			*kernel_ptr = (void **)&edid->edid;
2716ed45ce2cSHans Verkuil 			*array_size = edid->blocks * 128;
2717ed45ce2cSHans Verkuil 			ret = 1;
2718ed45ce2cSHans Verkuil 		}
2719ed45ce2cSHans Verkuil 		break;
2720ed45ce2cSHans Verkuil 	}
2721ed45ce2cSHans Verkuil 
27225bc3cb74SMauro Carvalho Chehab 	case VIDIOC_S_EXT_CTRLS:
27235bc3cb74SMauro Carvalho Chehab 	case VIDIOC_G_EXT_CTRLS:
27245bc3cb74SMauro Carvalho Chehab 	case VIDIOC_TRY_EXT_CTRLS: {
27255bc3cb74SMauro Carvalho Chehab 		struct v4l2_ext_controls *ctrls = parg;
27265bc3cb74SMauro Carvalho Chehab 
27275bc3cb74SMauro Carvalho Chehab 		if (ctrls->count != 0) {
27285bc3cb74SMauro Carvalho Chehab 			if (ctrls->count > V4L2_CID_MAX_CTRLS) {
27295bc3cb74SMauro Carvalho Chehab 				ret = -EINVAL;
27305bc3cb74SMauro Carvalho Chehab 				break;
27315bc3cb74SMauro Carvalho Chehab 			}
27325bc3cb74SMauro Carvalho Chehab 			*user_ptr = (void __user *)ctrls->controls;
2733ba2d35c1SHans Verkuil 			*kernel_ptr = (void **)&ctrls->controls;
27345bc3cb74SMauro Carvalho Chehab 			*array_size = sizeof(struct v4l2_ext_control)
27355bc3cb74SMauro Carvalho Chehab 				    * ctrls->count;
27365bc3cb74SMauro Carvalho Chehab 			ret = 1;
27375bc3cb74SMauro Carvalho Chehab 		}
27385bc3cb74SMauro Carvalho Chehab 		break;
27395bc3cb74SMauro Carvalho Chehab 	}
27405bc3cb74SMauro Carvalho Chehab 	}
27415bc3cb74SMauro Carvalho Chehab 
27425bc3cb74SMauro Carvalho Chehab 	return ret;
27435bc3cb74SMauro Carvalho Chehab }
27445bc3cb74SMauro Carvalho Chehab 
27455bc3cb74SMauro Carvalho Chehab long
27465bc3cb74SMauro Carvalho Chehab video_usercopy(struct file *file, unsigned int cmd, unsigned long arg,
27475bc3cb74SMauro Carvalho Chehab 	       v4l2_kioctl func)
27485bc3cb74SMauro Carvalho Chehab {
27495bc3cb74SMauro Carvalho Chehab 	char	sbuf[128];
27505bc3cb74SMauro Carvalho Chehab 	void    *mbuf = NULL;
27515bc3cb74SMauro Carvalho Chehab 	void	*parg = (void *)arg;
27525bc3cb74SMauro Carvalho Chehab 	long	err  = -EINVAL;
27535bc3cb74SMauro Carvalho Chehab 	bool	has_array_args;
27545bc3cb74SMauro Carvalho Chehab 	size_t  array_size = 0;
27555bc3cb74SMauro Carvalho Chehab 	void __user *user_ptr = NULL;
27565bc3cb74SMauro Carvalho Chehab 	void	**kernel_ptr = NULL;
27575bc3cb74SMauro Carvalho Chehab 
27585bc3cb74SMauro Carvalho Chehab 	/*  Copy arguments into temp kernel buffer  */
27595bc3cb74SMauro Carvalho Chehab 	if (_IOC_DIR(cmd) != _IOC_NONE) {
27605bc3cb74SMauro Carvalho Chehab 		if (_IOC_SIZE(cmd) <= sizeof(sbuf)) {
27615bc3cb74SMauro Carvalho Chehab 			parg = sbuf;
27625bc3cb74SMauro Carvalho Chehab 		} else {
27635bc3cb74SMauro Carvalho Chehab 			/* too big to allocate from stack */
27645bc3cb74SMauro Carvalho Chehab 			mbuf = kmalloc(_IOC_SIZE(cmd), GFP_KERNEL);
27655bc3cb74SMauro Carvalho Chehab 			if (NULL == mbuf)
27665bc3cb74SMauro Carvalho Chehab 				return -ENOMEM;
27675bc3cb74SMauro Carvalho Chehab 			parg = mbuf;
27685bc3cb74SMauro Carvalho Chehab 		}
27695bc3cb74SMauro Carvalho Chehab 
27705bc3cb74SMauro Carvalho Chehab 		err = -EFAULT;
27715bc3cb74SMauro Carvalho Chehab 		if (_IOC_DIR(cmd) & _IOC_WRITE) {
27725bc3cb74SMauro Carvalho Chehab 			unsigned int n = _IOC_SIZE(cmd);
27735bc3cb74SMauro Carvalho Chehab 
27745bc3cb74SMauro Carvalho Chehab 			/*
27755bc3cb74SMauro Carvalho Chehab 			 * In some cases, only a few fields are used as input,
27765bc3cb74SMauro Carvalho Chehab 			 * i.e. when the app sets "index" and then the driver
27775bc3cb74SMauro Carvalho Chehab 			 * fills in the rest of the structure for the thing
27785bc3cb74SMauro Carvalho Chehab 			 * with that index.  We only need to copy up the first
27795bc3cb74SMauro Carvalho Chehab 			 * non-input field.
27805bc3cb74SMauro Carvalho Chehab 			 */
27815bc3cb74SMauro Carvalho Chehab 			if (v4l2_is_known_ioctl(cmd)) {
27825bc3cb74SMauro Carvalho Chehab 				u32 flags = v4l2_ioctls[_IOC_NR(cmd)].flags;
27835bc3cb74SMauro Carvalho Chehab 				if (flags & INFO_FL_CLEAR_MASK)
27845bc3cb74SMauro Carvalho Chehab 					n = (flags & INFO_FL_CLEAR_MASK) >> 16;
27855bc3cb74SMauro Carvalho Chehab 			}
27865bc3cb74SMauro Carvalho Chehab 
27875bc3cb74SMauro Carvalho Chehab 			if (copy_from_user(parg, (void __user *)arg, n))
27885bc3cb74SMauro Carvalho Chehab 				goto out;
27895bc3cb74SMauro Carvalho Chehab 
27905bc3cb74SMauro Carvalho Chehab 			/* zero out anything we don't copy from userspace */
27915bc3cb74SMauro Carvalho Chehab 			if (n < _IOC_SIZE(cmd))
27925bc3cb74SMauro Carvalho Chehab 				memset((u8 *)parg + n, 0, _IOC_SIZE(cmd) - n);
27935bc3cb74SMauro Carvalho Chehab 		} else {
27945bc3cb74SMauro Carvalho Chehab 			/* read-only ioctl */
27955bc3cb74SMauro Carvalho Chehab 			memset(parg, 0, _IOC_SIZE(cmd));
27965bc3cb74SMauro Carvalho Chehab 		}
27975bc3cb74SMauro Carvalho Chehab 	}
27985bc3cb74SMauro Carvalho Chehab 
27995bc3cb74SMauro Carvalho Chehab 	err = check_array_args(cmd, parg, &array_size, &user_ptr, &kernel_ptr);
28005bc3cb74SMauro Carvalho Chehab 	if (err < 0)
28015bc3cb74SMauro Carvalho Chehab 		goto out;
28025bc3cb74SMauro Carvalho Chehab 	has_array_args = err;
28035bc3cb74SMauro Carvalho Chehab 
28045bc3cb74SMauro Carvalho Chehab 	if (has_array_args) {
28055bc3cb74SMauro Carvalho Chehab 		/*
28065bc3cb74SMauro Carvalho Chehab 		 * When adding new types of array args, make sure that the
28075bc3cb74SMauro Carvalho Chehab 		 * parent argument to ioctl (which contains the pointer to the
28085bc3cb74SMauro Carvalho Chehab 		 * array) fits into sbuf (so that mbuf will still remain
28095bc3cb74SMauro Carvalho Chehab 		 * unused up to here).
28105bc3cb74SMauro Carvalho Chehab 		 */
28115bc3cb74SMauro Carvalho Chehab 		mbuf = kmalloc(array_size, GFP_KERNEL);
28125bc3cb74SMauro Carvalho Chehab 		err = -ENOMEM;
28135bc3cb74SMauro Carvalho Chehab 		if (NULL == mbuf)
28145bc3cb74SMauro Carvalho Chehab 			goto out_array_args;
28155bc3cb74SMauro Carvalho Chehab 		err = -EFAULT;
28165bc3cb74SMauro Carvalho Chehab 		if (copy_from_user(mbuf, user_ptr, array_size))
28175bc3cb74SMauro Carvalho Chehab 			goto out_array_args;
28185bc3cb74SMauro Carvalho Chehab 		*kernel_ptr = mbuf;
28195bc3cb74SMauro Carvalho Chehab 	}
28205bc3cb74SMauro Carvalho Chehab 
28215bc3cb74SMauro Carvalho Chehab 	/* Handles IOCTL */
28225bc3cb74SMauro Carvalho Chehab 	err = func(file, cmd, parg);
28235bc3cb74SMauro Carvalho Chehab 	if (err == -ENOIOCTLCMD)
28245bc3cb74SMauro Carvalho Chehab 		err = -ENOTTY;
2825aa32f4c0SHans Verkuil 	if (err == 0) {
2826aa32f4c0SHans Verkuil 		if (cmd == VIDIOC_DQBUF)
2827aa32f4c0SHans Verkuil 			trace_v4l2_dqbuf(video_devdata(file)->minor, parg);
2828aa32f4c0SHans Verkuil 		else if (cmd == VIDIOC_QBUF)
2829aa32f4c0SHans Verkuil 			trace_v4l2_qbuf(video_devdata(file)->minor, parg);
2830aa32f4c0SHans Verkuil 	}
28315bc3cb74SMauro Carvalho Chehab 
28325bc3cb74SMauro Carvalho Chehab 	if (has_array_args) {
2833ba2d35c1SHans Verkuil 		*kernel_ptr = (void __force *)user_ptr;
28345bc3cb74SMauro Carvalho Chehab 		if (copy_to_user(user_ptr, mbuf, array_size))
28355bc3cb74SMauro Carvalho Chehab 			err = -EFAULT;
28365bc3cb74SMauro Carvalho Chehab 		goto out_array_args;
28375bc3cb74SMauro Carvalho Chehab 	}
28385bc3cb74SMauro Carvalho Chehab 	/* VIDIOC_QUERY_DV_TIMINGS can return an error, but still have valid
28395bc3cb74SMauro Carvalho Chehab 	   results that must be returned. */
28405bc3cb74SMauro Carvalho Chehab 	if (err < 0 && cmd != VIDIOC_QUERY_DV_TIMINGS)
28415bc3cb74SMauro Carvalho Chehab 		goto out;
28425bc3cb74SMauro Carvalho Chehab 
28435bc3cb74SMauro Carvalho Chehab out_array_args:
28445bc3cb74SMauro Carvalho Chehab 	/*  Copy results into user buffer  */
28455bc3cb74SMauro Carvalho Chehab 	switch (_IOC_DIR(cmd)) {
28465bc3cb74SMauro Carvalho Chehab 	case _IOC_READ:
28475bc3cb74SMauro Carvalho Chehab 	case (_IOC_WRITE | _IOC_READ):
28485bc3cb74SMauro Carvalho Chehab 		if (copy_to_user((void __user *)arg, parg, _IOC_SIZE(cmd)))
28495bc3cb74SMauro Carvalho Chehab 			err = -EFAULT;
28505bc3cb74SMauro Carvalho Chehab 		break;
28515bc3cb74SMauro Carvalho Chehab 	}
28525bc3cb74SMauro Carvalho Chehab 
28535bc3cb74SMauro Carvalho Chehab out:
28545bc3cb74SMauro Carvalho Chehab 	kfree(mbuf);
28555bc3cb74SMauro Carvalho Chehab 	return err;
28565bc3cb74SMauro Carvalho Chehab }
28575bc3cb74SMauro Carvalho Chehab EXPORT_SYMBOL(video_usercopy);
28585bc3cb74SMauro Carvalho Chehab 
28595bc3cb74SMauro Carvalho Chehab long video_ioctl2(struct file *file,
28605bc3cb74SMauro Carvalho Chehab 	       unsigned int cmd, unsigned long arg)
28615bc3cb74SMauro Carvalho Chehab {
28625bc3cb74SMauro Carvalho Chehab 	return video_usercopy(file, cmd, arg, __video_do_ioctl);
28635bc3cb74SMauro Carvalho Chehab }
28645bc3cb74SMauro Carvalho Chehab EXPORT_SYMBOL(video_ioctl2);
2865