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 
1778720427cSMauro Carvalho Chehab 	pr_cont("driver=%.*s, card=%.*s, bus=%.*s, version=0x%08x, capabilities=0x%08x, device_caps=0x%08x\n",
17827d5a87cSHans Verkuil 		(int)sizeof(p->driver), p->driver,
17927d5a87cSHans Verkuil 		(int)sizeof(p->card), p->card,
18027d5a87cSHans Verkuil 		(int)sizeof(p->bus_info), p->bus_info,
1815bc3cb74SMauro Carvalho Chehab 		p->version, p->capabilities, p->device_caps);
1825bc3cb74SMauro Carvalho Chehab }
1835bc3cb74SMauro Carvalho Chehab 
1845bc3cb74SMauro Carvalho Chehab static void v4l_print_enuminput(const void *arg, bool write_only)
1855bc3cb74SMauro Carvalho Chehab {
1865bc3cb74SMauro Carvalho Chehab 	const struct v4l2_input *p = arg;
1875bc3cb74SMauro Carvalho Chehab 
1888720427cSMauro Carvalho Chehab 	pr_cont("index=%u, name=%.*s, type=%u, audioset=0x%x, tuner=%u, std=0x%08Lx, status=0x%x, capabilities=0x%x\n",
18927d5a87cSHans Verkuil 		p->index, (int)sizeof(p->name), p->name, p->type, p->audioset,
19027d5a87cSHans Verkuil 		p->tuner, (unsigned long long)p->std, p->status,
19127d5a87cSHans Verkuil 		p->capabilities);
1925bc3cb74SMauro Carvalho Chehab }
1935bc3cb74SMauro Carvalho Chehab 
1945bc3cb74SMauro Carvalho Chehab static void v4l_print_enumoutput(const void *arg, bool write_only)
1955bc3cb74SMauro Carvalho Chehab {
1965bc3cb74SMauro Carvalho Chehab 	const struct v4l2_output *p = arg;
1975bc3cb74SMauro Carvalho Chehab 
1988720427cSMauro Carvalho Chehab 	pr_cont("index=%u, name=%.*s, type=%u, audioset=0x%x, modulator=%u, std=0x%08Lx, capabilities=0x%x\n",
19927d5a87cSHans Verkuil 		p->index, (int)sizeof(p->name), p->name, p->type, p->audioset,
20027d5a87cSHans Verkuil 		p->modulator, (unsigned long long)p->std, p->capabilities);
2015bc3cb74SMauro Carvalho Chehab }
2025bc3cb74SMauro Carvalho Chehab 
2035bc3cb74SMauro Carvalho Chehab static void v4l_print_audio(const void *arg, bool write_only)
2045bc3cb74SMauro Carvalho Chehab {
2055bc3cb74SMauro Carvalho Chehab 	const struct v4l2_audio *p = arg;
2065bc3cb74SMauro Carvalho Chehab 
2075bc3cb74SMauro Carvalho Chehab 	if (write_only)
2085bc3cb74SMauro Carvalho Chehab 		pr_cont("index=%u, mode=0x%x\n", p->index, p->mode);
2095bc3cb74SMauro Carvalho Chehab 	else
21027d5a87cSHans Verkuil 		pr_cont("index=%u, name=%.*s, capability=0x%x, mode=0x%x\n",
21127d5a87cSHans Verkuil 			p->index, (int)sizeof(p->name), p->name,
21227d5a87cSHans Verkuil 			p->capability, p->mode);
2135bc3cb74SMauro Carvalho Chehab }
2145bc3cb74SMauro Carvalho Chehab 
2155bc3cb74SMauro Carvalho Chehab static void v4l_print_audioout(const void *arg, bool write_only)
2165bc3cb74SMauro Carvalho Chehab {
2175bc3cb74SMauro Carvalho Chehab 	const struct v4l2_audioout *p = arg;
2185bc3cb74SMauro Carvalho Chehab 
2195bc3cb74SMauro Carvalho Chehab 	if (write_only)
2205bc3cb74SMauro Carvalho Chehab 		pr_cont("index=%u\n", p->index);
2215bc3cb74SMauro Carvalho Chehab 	else
22227d5a87cSHans Verkuil 		pr_cont("index=%u, name=%.*s, capability=0x%x, mode=0x%x\n",
22327d5a87cSHans Verkuil 			p->index, (int)sizeof(p->name), p->name,
22427d5a87cSHans Verkuil 			p->capability, p->mode);
2255bc3cb74SMauro Carvalho Chehab }
2265bc3cb74SMauro Carvalho Chehab 
2275bc3cb74SMauro Carvalho Chehab static void v4l_print_fmtdesc(const void *arg, bool write_only)
2285bc3cb74SMauro Carvalho Chehab {
2295bc3cb74SMauro Carvalho Chehab 	const struct v4l2_fmtdesc *p = arg;
2305bc3cb74SMauro Carvalho Chehab 
23127d5a87cSHans Verkuil 	pr_cont("index=%u, type=%s, flags=0x%x, pixelformat=%c%c%c%c, description='%.*s'\n",
2325bc3cb74SMauro Carvalho Chehab 		p->index, prt_names(p->type, v4l2_type_names),
2335bc3cb74SMauro Carvalho Chehab 		p->flags, (p->pixelformat & 0xff),
2345bc3cb74SMauro Carvalho Chehab 		(p->pixelformat >>  8) & 0xff,
2355bc3cb74SMauro Carvalho Chehab 		(p->pixelformat >> 16) & 0xff,
2365bc3cb74SMauro Carvalho Chehab 		(p->pixelformat >> 24) & 0xff,
23727d5a87cSHans Verkuil 		(int)sizeof(p->description), p->description);
2385bc3cb74SMauro Carvalho Chehab }
2395bc3cb74SMauro Carvalho Chehab 
2405bc3cb74SMauro Carvalho Chehab static void v4l_print_format(const void *arg, bool write_only)
2415bc3cb74SMauro Carvalho Chehab {
2425bc3cb74SMauro Carvalho Chehab 	const struct v4l2_format *p = arg;
2435bc3cb74SMauro Carvalho Chehab 	const struct v4l2_pix_format *pix;
2445bc3cb74SMauro Carvalho Chehab 	const struct v4l2_pix_format_mplane *mp;
2455bc3cb74SMauro Carvalho Chehab 	const struct v4l2_vbi_format *vbi;
2465bc3cb74SMauro Carvalho Chehab 	const struct v4l2_sliced_vbi_format *sliced;
2475bc3cb74SMauro Carvalho Chehab 	const struct v4l2_window *win;
24887185c95SAntti Palosaari 	const struct v4l2_sdr_format *sdr;
2495bc3cb74SMauro Carvalho Chehab 	unsigned i;
2505bc3cb74SMauro Carvalho Chehab 
2515bc3cb74SMauro Carvalho Chehab 	pr_cont("type=%s", prt_names(p->type, v4l2_type_names));
2525bc3cb74SMauro Carvalho Chehab 	switch (p->type) {
2535bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_CAPTURE:
2545bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_OUTPUT:
2555bc3cb74SMauro Carvalho Chehab 		pix = &p->fmt.pix;
2568720427cSMauro Carvalho Chehab 		pr_cont(", width=%u, height=%u, pixelformat=%c%c%c%c, field=%s, bytesperline=%u, sizeimage=%u, colorspace=%d, flags=0x%x, ycbcr_enc=%u, quantization=%u, xfer_func=%u\n",
2575bc3cb74SMauro Carvalho Chehab 			pix->width, pix->height,
2585bc3cb74SMauro Carvalho Chehab 			(pix->pixelformat & 0xff),
2595bc3cb74SMauro Carvalho Chehab 			(pix->pixelformat >>  8) & 0xff,
2605bc3cb74SMauro Carvalho Chehab 			(pix->pixelformat >> 16) & 0xff,
2615bc3cb74SMauro Carvalho Chehab 			(pix->pixelformat >> 24) & 0xff,
2625bc3cb74SMauro Carvalho Chehab 			prt_names(pix->field, v4l2_field_names),
2635bc3cb74SMauro Carvalho Chehab 			pix->bytesperline, pix->sizeimage,
264736d96b5SHans Verkuil 			pix->colorspace, pix->flags, pix->ycbcr_enc,
26574fdcb2eSHans Verkuil 			pix->quantization, pix->xfer_func);
2665bc3cb74SMauro Carvalho Chehab 		break;
2675bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
2685bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
2695bc3cb74SMauro Carvalho Chehab 		mp = &p->fmt.pix_mp;
2708720427cSMauro Carvalho Chehab 		pr_cont(", width=%u, height=%u, format=%c%c%c%c, field=%s, colorspace=%d, num_planes=%u, flags=0x%x, ycbcr_enc=%u, quantization=%u, xfer_func=%u\n",
2715bc3cb74SMauro Carvalho Chehab 			mp->width, mp->height,
2725bc3cb74SMauro Carvalho Chehab 			(mp->pixelformat & 0xff),
2735bc3cb74SMauro Carvalho Chehab 			(mp->pixelformat >>  8) & 0xff,
2745bc3cb74SMauro Carvalho Chehab 			(mp->pixelformat >> 16) & 0xff,
2755bc3cb74SMauro Carvalho Chehab 			(mp->pixelformat >> 24) & 0xff,
2765bc3cb74SMauro Carvalho Chehab 			prt_names(mp->field, v4l2_field_names),
277736d96b5SHans Verkuil 			mp->colorspace, mp->num_planes, mp->flags,
27874fdcb2eSHans Verkuil 			mp->ycbcr_enc, mp->quantization, mp->xfer_func);
2795bc3cb74SMauro Carvalho Chehab 		for (i = 0; i < mp->num_planes; i++)
2805bc3cb74SMauro Carvalho Chehab 			printk(KERN_DEBUG "plane %u: bytesperline=%u sizeimage=%u\n", i,
2815bc3cb74SMauro Carvalho Chehab 					mp->plane_fmt[i].bytesperline,
2825bc3cb74SMauro Carvalho Chehab 					mp->plane_fmt[i].sizeimage);
2835bc3cb74SMauro Carvalho Chehab 		break;
2845bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_OVERLAY:
2855bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
2865bc3cb74SMauro Carvalho Chehab 		win = &p->fmt.win;
287560dde24SHans Verkuil 		/* Note: we can't print the clip list here since the clips
288560dde24SHans Verkuil 		 * pointer is a userspace pointer, not a kernelspace
289560dde24SHans Verkuil 		 * pointer. */
290560dde24SHans 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",
291560dde24SHans Verkuil 			win->w.width, win->w.height, win->w.left, win->w.top,
2925bc3cb74SMauro Carvalho Chehab 			prt_names(win->field, v4l2_field_names),
293560dde24SHans Verkuil 			win->chromakey, win->clipcount, win->clips,
294560dde24SHans Verkuil 			win->bitmap, win->global_alpha);
2955bc3cb74SMauro Carvalho Chehab 		break;
2965bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VBI_CAPTURE:
2975bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VBI_OUTPUT:
2985bc3cb74SMauro Carvalho Chehab 		vbi = &p->fmt.vbi;
2998720427cSMauro Carvalho Chehab 		pr_cont(", sampling_rate=%u, offset=%u, samples_per_line=%u, sample_format=%c%c%c%c, start=%u,%u, count=%u,%u\n",
3005bc3cb74SMauro Carvalho Chehab 			vbi->sampling_rate, vbi->offset,
3015bc3cb74SMauro Carvalho Chehab 			vbi->samples_per_line,
3025bc3cb74SMauro Carvalho Chehab 			(vbi->sample_format & 0xff),
3035bc3cb74SMauro Carvalho Chehab 			(vbi->sample_format >>  8) & 0xff,
3045bc3cb74SMauro Carvalho Chehab 			(vbi->sample_format >> 16) & 0xff,
3055bc3cb74SMauro Carvalho Chehab 			(vbi->sample_format >> 24) & 0xff,
3065bc3cb74SMauro Carvalho Chehab 			vbi->start[0], vbi->start[1],
3075bc3cb74SMauro Carvalho Chehab 			vbi->count[0], vbi->count[1]);
3085bc3cb74SMauro Carvalho Chehab 		break;
3095bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
3105bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
3115bc3cb74SMauro Carvalho Chehab 		sliced = &p->fmt.sliced;
3125bc3cb74SMauro Carvalho Chehab 		pr_cont(", service_set=0x%08x, io_size=%d\n",
3135bc3cb74SMauro Carvalho Chehab 				sliced->service_set, sliced->io_size);
3145bc3cb74SMauro Carvalho Chehab 		for (i = 0; i < 24; i++)
3155bc3cb74SMauro Carvalho Chehab 			printk(KERN_DEBUG "line[%02u]=0x%04x, 0x%04x\n", i,
3165bc3cb74SMauro Carvalho Chehab 				sliced->service_lines[0][i],
3175bc3cb74SMauro Carvalho Chehab 				sliced->service_lines[1][i]);
3185bc3cb74SMauro Carvalho Chehab 		break;
319582c52cbSAntti Palosaari 	case V4L2_BUF_TYPE_SDR_CAPTURE:
3209effc72fSAntti Palosaari 	case V4L2_BUF_TYPE_SDR_OUTPUT:
321582c52cbSAntti Palosaari 		sdr = &p->fmt.sdr;
322582c52cbSAntti Palosaari 		pr_cont(", pixelformat=%c%c%c%c\n",
323582c52cbSAntti Palosaari 			(sdr->pixelformat >>  0) & 0xff,
324582c52cbSAntti Palosaari 			(sdr->pixelformat >>  8) & 0xff,
325582c52cbSAntti Palosaari 			(sdr->pixelformat >> 16) & 0xff,
326582c52cbSAntti Palosaari 			(sdr->pixelformat >> 24) & 0xff);
327582c52cbSAntti Palosaari 		break;
3285bc3cb74SMauro Carvalho Chehab 	}
3295bc3cb74SMauro Carvalho Chehab }
3305bc3cb74SMauro Carvalho Chehab 
3315bc3cb74SMauro Carvalho Chehab static void v4l_print_framebuffer(const void *arg, bool write_only)
3325bc3cb74SMauro Carvalho Chehab {
3335bc3cb74SMauro Carvalho Chehab 	const struct v4l2_framebuffer *p = arg;
3345bc3cb74SMauro Carvalho Chehab 
3358720427cSMauro Carvalho Chehab 	pr_cont("capability=0x%x, flags=0x%x, base=0x%p, width=%u, height=%u, pixelformat=%c%c%c%c, bytesperline=%u, sizeimage=%u, colorspace=%d\n",
3365bc3cb74SMauro Carvalho Chehab 			p->capability, p->flags, p->base,
3375bc3cb74SMauro Carvalho Chehab 			p->fmt.width, p->fmt.height,
3385bc3cb74SMauro Carvalho Chehab 			(p->fmt.pixelformat & 0xff),
3395bc3cb74SMauro Carvalho Chehab 			(p->fmt.pixelformat >>  8) & 0xff,
3405bc3cb74SMauro Carvalho Chehab 			(p->fmt.pixelformat >> 16) & 0xff,
3415bc3cb74SMauro Carvalho Chehab 			(p->fmt.pixelformat >> 24) & 0xff,
3425bc3cb74SMauro Carvalho Chehab 			p->fmt.bytesperline, p->fmt.sizeimage,
3435bc3cb74SMauro Carvalho Chehab 			p->fmt.colorspace);
3445bc3cb74SMauro Carvalho Chehab }
3455bc3cb74SMauro Carvalho Chehab 
3465bc3cb74SMauro Carvalho Chehab static void v4l_print_buftype(const void *arg, bool write_only)
3475bc3cb74SMauro Carvalho Chehab {
3485bc3cb74SMauro Carvalho Chehab 	pr_cont("type=%s\n", prt_names(*(u32 *)arg, v4l2_type_names));
3495bc3cb74SMauro Carvalho Chehab }
3505bc3cb74SMauro Carvalho Chehab 
3515bc3cb74SMauro Carvalho Chehab static void v4l_print_modulator(const void *arg, bool write_only)
3525bc3cb74SMauro Carvalho Chehab {
3535bc3cb74SMauro Carvalho Chehab 	const struct v4l2_modulator *p = arg;
3545bc3cb74SMauro Carvalho Chehab 
3555bc3cb74SMauro Carvalho Chehab 	if (write_only)
356560dde24SHans Verkuil 		pr_cont("index=%u, txsubchans=0x%x\n", p->index, p->txsubchans);
3575bc3cb74SMauro Carvalho Chehab 	else
3588720427cSMauro Carvalho Chehab 		pr_cont("index=%u, name=%.*s, capability=0x%x, rangelow=%u, rangehigh=%u, txsubchans=0x%x\n",
35927d5a87cSHans Verkuil 			p->index, (int)sizeof(p->name), p->name, p->capability,
3605bc3cb74SMauro Carvalho Chehab 			p->rangelow, p->rangehigh, p->txsubchans);
3615bc3cb74SMauro Carvalho Chehab }
3625bc3cb74SMauro Carvalho Chehab 
3635bc3cb74SMauro Carvalho Chehab static void v4l_print_tuner(const void *arg, bool write_only)
3645bc3cb74SMauro Carvalho Chehab {
3655bc3cb74SMauro Carvalho Chehab 	const struct v4l2_tuner *p = arg;
3665bc3cb74SMauro Carvalho Chehab 
3675bc3cb74SMauro Carvalho Chehab 	if (write_only)
3685bc3cb74SMauro Carvalho Chehab 		pr_cont("index=%u, audmode=%u\n", p->index, p->audmode);
3695bc3cb74SMauro Carvalho Chehab 	else
3708720427cSMauro Carvalho Chehab 		pr_cont("index=%u, name=%.*s, type=%u, capability=0x%x, rangelow=%u, rangehigh=%u, signal=%u, afc=%d, rxsubchans=0x%x, audmode=%u\n",
37127d5a87cSHans Verkuil 			p->index, (int)sizeof(p->name), p->name, p->type,
3725bc3cb74SMauro Carvalho Chehab 			p->capability, p->rangelow,
3735bc3cb74SMauro Carvalho Chehab 			p->rangehigh, p->signal, p->afc,
3745bc3cb74SMauro Carvalho Chehab 			p->rxsubchans, p->audmode);
3755bc3cb74SMauro Carvalho Chehab }
3765bc3cb74SMauro Carvalho Chehab 
3775bc3cb74SMauro Carvalho Chehab static void v4l_print_frequency(const void *arg, bool write_only)
3785bc3cb74SMauro Carvalho Chehab {
3795bc3cb74SMauro Carvalho Chehab 	const struct v4l2_frequency *p = arg;
3805bc3cb74SMauro Carvalho Chehab 
3815bc3cb74SMauro Carvalho Chehab 	pr_cont("tuner=%u, type=%u, frequency=%u\n",
3825bc3cb74SMauro Carvalho Chehab 				p->tuner, p->type, p->frequency);
3835bc3cb74SMauro Carvalho Chehab }
3845bc3cb74SMauro Carvalho Chehab 
3855bc3cb74SMauro Carvalho Chehab static void v4l_print_standard(const void *arg, bool write_only)
3865bc3cb74SMauro Carvalho Chehab {
3875bc3cb74SMauro Carvalho Chehab 	const struct v4l2_standard *p = arg;
3885bc3cb74SMauro Carvalho Chehab 
3898720427cSMauro Carvalho Chehab 	pr_cont("index=%u, id=0x%Lx, name=%.*s, fps=%u/%u, framelines=%u\n",
3908720427cSMauro Carvalho Chehab 		p->index,
39127d5a87cSHans Verkuil 		(unsigned long long)p->id, (int)sizeof(p->name), p->name,
3925bc3cb74SMauro Carvalho Chehab 		p->frameperiod.numerator,
3935bc3cb74SMauro Carvalho Chehab 		p->frameperiod.denominator,
3945bc3cb74SMauro Carvalho Chehab 		p->framelines);
3955bc3cb74SMauro Carvalho Chehab }
3965bc3cb74SMauro Carvalho Chehab 
3975bc3cb74SMauro Carvalho Chehab static void v4l_print_std(const void *arg, bool write_only)
3985bc3cb74SMauro Carvalho Chehab {
3995bc3cb74SMauro Carvalho Chehab 	pr_cont("std=0x%08Lx\n", *(const long long unsigned *)arg);
4005bc3cb74SMauro Carvalho Chehab }
4015bc3cb74SMauro Carvalho Chehab 
4025bc3cb74SMauro Carvalho Chehab static void v4l_print_hw_freq_seek(const void *arg, bool write_only)
4035bc3cb74SMauro Carvalho Chehab {
4045bc3cb74SMauro Carvalho Chehab 	const struct v4l2_hw_freq_seek *p = arg;
4055bc3cb74SMauro Carvalho Chehab 
4068720427cSMauro Carvalho Chehab 	pr_cont("tuner=%u, type=%u, seek_upward=%u, wrap_around=%u, spacing=%u, rangelow=%u, rangehigh=%u\n",
40779e8c7beSMauro Carvalho Chehab 		p->tuner, p->type, p->seek_upward, p->wrap_around, p->spacing,
40879e8c7beSMauro Carvalho Chehab 		p->rangelow, p->rangehigh);
4095bc3cb74SMauro Carvalho Chehab }
4105bc3cb74SMauro Carvalho Chehab 
4115bc3cb74SMauro Carvalho Chehab static void v4l_print_requestbuffers(const void *arg, bool write_only)
4125bc3cb74SMauro Carvalho Chehab {
4135bc3cb74SMauro Carvalho Chehab 	const struct v4l2_requestbuffers *p = arg;
4145bc3cb74SMauro Carvalho Chehab 
4155bc3cb74SMauro Carvalho Chehab 	pr_cont("count=%d, type=%s, memory=%s\n",
4165bc3cb74SMauro Carvalho Chehab 		p->count,
4175bc3cb74SMauro Carvalho Chehab 		prt_names(p->type, v4l2_type_names),
4185bc3cb74SMauro Carvalho Chehab 		prt_names(p->memory, v4l2_memory_names));
4195bc3cb74SMauro Carvalho Chehab }
4205bc3cb74SMauro Carvalho Chehab 
4215bc3cb74SMauro Carvalho Chehab static void v4l_print_buffer(const void *arg, bool write_only)
4225bc3cb74SMauro Carvalho Chehab {
4235bc3cb74SMauro Carvalho Chehab 	const struct v4l2_buffer *p = arg;
4245bc3cb74SMauro Carvalho Chehab 	const struct v4l2_timecode *tc = &p->timecode;
4255bc3cb74SMauro Carvalho Chehab 	const struct v4l2_plane *plane;
4265bc3cb74SMauro Carvalho Chehab 	int i;
4275bc3cb74SMauro Carvalho Chehab 
4288720427cSMauro Carvalho Chehab 	pr_cont("%02ld:%02d:%02d.%08ld index=%d, type=%s, flags=0x%08x, field=%s, sequence=%d, memory=%s",
4295bc3cb74SMauro Carvalho Chehab 			p->timestamp.tv_sec / 3600,
4305bc3cb74SMauro Carvalho Chehab 			(int)(p->timestamp.tv_sec / 60) % 60,
4315bc3cb74SMauro Carvalho Chehab 			(int)(p->timestamp.tv_sec % 60),
4325bc3cb74SMauro Carvalho Chehab 			(long)p->timestamp.tv_usec,
4335bc3cb74SMauro Carvalho Chehab 			p->index,
4345bc3cb74SMauro Carvalho Chehab 			prt_names(p->type, v4l2_type_names),
4355bc3cb74SMauro Carvalho Chehab 			p->flags, prt_names(p->field, v4l2_field_names),
4365bc3cb74SMauro Carvalho Chehab 			p->sequence, prt_names(p->memory, v4l2_memory_names));
4375bc3cb74SMauro Carvalho Chehab 
4385bc3cb74SMauro Carvalho Chehab 	if (V4L2_TYPE_IS_MULTIPLANAR(p->type) && p->m.planes) {
4395bc3cb74SMauro Carvalho Chehab 		pr_cont("\n");
4405bc3cb74SMauro Carvalho Chehab 		for (i = 0; i < p->length; ++i) {
4415bc3cb74SMauro Carvalho Chehab 			plane = &p->m.planes[i];
4425bc3cb74SMauro Carvalho Chehab 			printk(KERN_DEBUG
4438720427cSMauro Carvalho Chehab 				"plane %d: bytesused=%d, data_offset=0x%08x, offset/userptr=0x%lx, length=%d\n",
4445bc3cb74SMauro Carvalho Chehab 				i, plane->bytesused, plane->data_offset,
4455bc3cb74SMauro Carvalho Chehab 				plane->m.userptr, plane->length);
4465bc3cb74SMauro Carvalho Chehab 		}
4475bc3cb74SMauro Carvalho Chehab 	} else {
448560dde24SHans Verkuil 		pr_cont(", bytesused=%d, offset/userptr=0x%lx, length=%d\n",
4495bc3cb74SMauro Carvalho Chehab 			p->bytesused, p->m.userptr, p->length);
4505bc3cb74SMauro Carvalho Chehab 	}
4515bc3cb74SMauro Carvalho Chehab 
4528720427cSMauro Carvalho Chehab 	printk(KERN_DEBUG "timecode=%02d:%02d:%02d type=%d, flags=0x%08x, frames=%d, userbits=0x%08x\n",
4535bc3cb74SMauro Carvalho Chehab 			tc->hours, tc->minutes, tc->seconds,
4545bc3cb74SMauro Carvalho Chehab 			tc->type, tc->flags, tc->frames, *(__u32 *)tc->userbits);
4555bc3cb74SMauro Carvalho Chehab }
4565bc3cb74SMauro Carvalho Chehab 
457b799d09aSTomasz Stanislawski static void v4l_print_exportbuffer(const void *arg, bool write_only)
458b799d09aSTomasz Stanislawski {
459b799d09aSTomasz Stanislawski 	const struct v4l2_exportbuffer *p = arg;
460b799d09aSTomasz Stanislawski 
461b799d09aSTomasz Stanislawski 	pr_cont("fd=%d, type=%s, index=%u, plane=%u, flags=0x%08x\n",
462b799d09aSTomasz Stanislawski 		p->fd, prt_names(p->type, v4l2_type_names),
463b799d09aSTomasz Stanislawski 		p->index, p->plane, p->flags);
464b799d09aSTomasz Stanislawski }
465b799d09aSTomasz Stanislawski 
4665bc3cb74SMauro Carvalho Chehab static void v4l_print_create_buffers(const void *arg, bool write_only)
4675bc3cb74SMauro Carvalho Chehab {
4685bc3cb74SMauro Carvalho Chehab 	const struct v4l2_create_buffers *p = arg;
4695bc3cb74SMauro Carvalho Chehab 
4705bc3cb74SMauro Carvalho Chehab 	pr_cont("index=%d, count=%d, memory=%s, ",
4715bc3cb74SMauro Carvalho Chehab 			p->index, p->count,
4725bc3cb74SMauro Carvalho Chehab 			prt_names(p->memory, v4l2_memory_names));
4735bc3cb74SMauro Carvalho Chehab 	v4l_print_format(&p->format, write_only);
4745bc3cb74SMauro Carvalho Chehab }
4755bc3cb74SMauro Carvalho Chehab 
4765bc3cb74SMauro Carvalho Chehab static void v4l_print_streamparm(const void *arg, bool write_only)
4775bc3cb74SMauro Carvalho Chehab {
4785bc3cb74SMauro Carvalho Chehab 	const struct v4l2_streamparm *p = arg;
4795bc3cb74SMauro Carvalho Chehab 
4805bc3cb74SMauro Carvalho Chehab 	pr_cont("type=%s", prt_names(p->type, v4l2_type_names));
4815bc3cb74SMauro Carvalho Chehab 
4825bc3cb74SMauro Carvalho Chehab 	if (p->type == V4L2_BUF_TYPE_VIDEO_CAPTURE ||
4835bc3cb74SMauro Carvalho Chehab 	    p->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
4845bc3cb74SMauro Carvalho Chehab 		const struct v4l2_captureparm *c = &p->parm.capture;
4855bc3cb74SMauro Carvalho Chehab 
4868720427cSMauro Carvalho Chehab 		pr_cont(", capability=0x%x, capturemode=0x%x, timeperframe=%d/%d, extendedmode=%d, readbuffers=%d\n",
4875bc3cb74SMauro Carvalho Chehab 			c->capability, c->capturemode,
4885bc3cb74SMauro Carvalho Chehab 			c->timeperframe.numerator, c->timeperframe.denominator,
4895bc3cb74SMauro Carvalho Chehab 			c->extendedmode, c->readbuffers);
4905bc3cb74SMauro Carvalho Chehab 	} else if (p->type == V4L2_BUF_TYPE_VIDEO_OUTPUT ||
4915bc3cb74SMauro Carvalho Chehab 		   p->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
4925bc3cb74SMauro Carvalho Chehab 		const struct v4l2_outputparm *c = &p->parm.output;
4935bc3cb74SMauro Carvalho Chehab 
4948720427cSMauro Carvalho Chehab 		pr_cont(", capability=0x%x, outputmode=0x%x, timeperframe=%d/%d, extendedmode=%d, writebuffers=%d\n",
4955bc3cb74SMauro Carvalho Chehab 			c->capability, c->outputmode,
4965bc3cb74SMauro Carvalho Chehab 			c->timeperframe.numerator, c->timeperframe.denominator,
4975bc3cb74SMauro Carvalho Chehab 			c->extendedmode, c->writebuffers);
498560dde24SHans Verkuil 	} else {
499560dde24SHans Verkuil 		pr_cont("\n");
5005bc3cb74SMauro Carvalho Chehab 	}
5015bc3cb74SMauro Carvalho Chehab }
5025bc3cb74SMauro Carvalho Chehab 
5035bc3cb74SMauro Carvalho Chehab static void v4l_print_queryctrl(const void *arg, bool write_only)
5045bc3cb74SMauro Carvalho Chehab {
5055bc3cb74SMauro Carvalho Chehab 	const struct v4l2_queryctrl *p = arg;
5065bc3cb74SMauro Carvalho Chehab 
5078720427cSMauro Carvalho Chehab 	pr_cont("id=0x%x, type=%d, name=%.*s, min/max=%d/%d, step=%d, default=%d, flags=0x%08x\n",
50827d5a87cSHans Verkuil 			p->id, p->type, (int)sizeof(p->name), p->name,
5095bc3cb74SMauro Carvalho Chehab 			p->minimum, p->maximum,
5105bc3cb74SMauro Carvalho Chehab 			p->step, p->default_value, p->flags);
5115bc3cb74SMauro Carvalho Chehab }
5125bc3cb74SMauro Carvalho Chehab 
513e6bee368SHans Verkuil static void v4l_print_query_ext_ctrl(const void *arg, bool write_only)
514e6bee368SHans Verkuil {
515e6bee368SHans Verkuil 	const struct v4l2_query_ext_ctrl *p = arg;
516e6bee368SHans Verkuil 
5178720427cSMauro Carvalho Chehab 	pr_cont("id=0x%x, type=%d, name=%.*s, min/max=%lld/%lld, step=%lld, default=%lld, flags=0x%08x, elem_size=%u, elems=%u, nr_of_dims=%u, dims=%u,%u,%u,%u\n",
518e6bee368SHans Verkuil 			p->id, p->type, (int)sizeof(p->name), p->name,
519e6bee368SHans Verkuil 			p->minimum, p->maximum,
520e6bee368SHans Verkuil 			p->step, p->default_value, p->flags,
521e6bee368SHans Verkuil 			p->elem_size, p->elems, p->nr_of_dims,
5220176077aSHans Verkuil 			p->dims[0], p->dims[1], p->dims[2], p->dims[3]);
523e6bee368SHans Verkuil }
524e6bee368SHans Verkuil 
5255bc3cb74SMauro Carvalho Chehab static void v4l_print_querymenu(const void *arg, bool write_only)
5265bc3cb74SMauro Carvalho Chehab {
5275bc3cb74SMauro Carvalho Chehab 	const struct v4l2_querymenu *p = arg;
5285bc3cb74SMauro Carvalho Chehab 
5295bc3cb74SMauro Carvalho Chehab 	pr_cont("id=0x%x, index=%d\n", p->id, p->index);
5305bc3cb74SMauro Carvalho Chehab }
5315bc3cb74SMauro Carvalho Chehab 
5325bc3cb74SMauro Carvalho Chehab static void v4l_print_control(const void *arg, bool write_only)
5335bc3cb74SMauro Carvalho Chehab {
5345bc3cb74SMauro Carvalho Chehab 	const struct v4l2_control *p = arg;
5355bc3cb74SMauro Carvalho Chehab 
5365bc3cb74SMauro Carvalho Chehab 	pr_cont("id=0x%x, value=%d\n", p->id, p->value);
5375bc3cb74SMauro Carvalho Chehab }
5385bc3cb74SMauro Carvalho Chehab 
5395bc3cb74SMauro Carvalho Chehab static void v4l_print_ext_controls(const void *arg, bool write_only)
5405bc3cb74SMauro Carvalho Chehab {
5415bc3cb74SMauro Carvalho Chehab 	const struct v4l2_ext_controls *p = arg;
5425bc3cb74SMauro Carvalho Chehab 	int i;
5435bc3cb74SMauro Carvalho Chehab 
5440f8017beSRicardo Ribalda 	pr_cont("which=0x%x, count=%d, error_idx=%d",
5450f8017beSRicardo Ribalda 			p->which, p->count, p->error_idx);
5465bc3cb74SMauro Carvalho Chehab 	for (i = 0; i < p->count; i++) {
547017ab36aSHans Verkuil 		if (!p->controls[i].size)
5485bc3cb74SMauro Carvalho Chehab 			pr_cont(", id/val=0x%x/0x%x",
5495bc3cb74SMauro Carvalho Chehab 				p->controls[i].id, p->controls[i].value);
5505bc3cb74SMauro Carvalho Chehab 		else
5515bc3cb74SMauro Carvalho Chehab 			pr_cont(", id/size=0x%x/%u",
5525bc3cb74SMauro Carvalho Chehab 				p->controls[i].id, p->controls[i].size);
5535bc3cb74SMauro Carvalho Chehab 	}
5545bc3cb74SMauro Carvalho Chehab 	pr_cont("\n");
5555bc3cb74SMauro Carvalho Chehab }
5565bc3cb74SMauro Carvalho Chehab 
5575bc3cb74SMauro Carvalho Chehab static void v4l_print_cropcap(const void *arg, bool write_only)
5585bc3cb74SMauro Carvalho Chehab {
5595bc3cb74SMauro Carvalho Chehab 	const struct v4l2_cropcap *p = arg;
5605bc3cb74SMauro Carvalho Chehab 
5618720427cSMauro Carvalho Chehab 	pr_cont("type=%s, bounds wxh=%dx%d, x,y=%d,%d, defrect wxh=%dx%d, x,y=%d,%d, pixelaspect %d/%d\n",
5625bc3cb74SMauro Carvalho Chehab 		prt_names(p->type, v4l2_type_names),
5635bc3cb74SMauro Carvalho Chehab 		p->bounds.width, p->bounds.height,
5645bc3cb74SMauro Carvalho Chehab 		p->bounds.left, p->bounds.top,
5655bc3cb74SMauro Carvalho Chehab 		p->defrect.width, p->defrect.height,
5665bc3cb74SMauro Carvalho Chehab 		p->defrect.left, p->defrect.top,
5675bc3cb74SMauro Carvalho Chehab 		p->pixelaspect.numerator, p->pixelaspect.denominator);
5685bc3cb74SMauro Carvalho Chehab }
5695bc3cb74SMauro Carvalho Chehab 
5705bc3cb74SMauro Carvalho Chehab static void v4l_print_crop(const void *arg, bool write_only)
5715bc3cb74SMauro Carvalho Chehab {
5725bc3cb74SMauro Carvalho Chehab 	const struct v4l2_crop *p = arg;
5735bc3cb74SMauro Carvalho Chehab 
5745bc3cb74SMauro Carvalho Chehab 	pr_cont("type=%s, wxh=%dx%d, x,y=%d,%d\n",
5755bc3cb74SMauro Carvalho Chehab 		prt_names(p->type, v4l2_type_names),
5765bc3cb74SMauro Carvalho Chehab 		p->c.width, p->c.height,
5775bc3cb74SMauro Carvalho Chehab 		p->c.left, p->c.top);
5785bc3cb74SMauro Carvalho Chehab }
5795bc3cb74SMauro Carvalho Chehab 
5805bc3cb74SMauro Carvalho Chehab static void v4l_print_selection(const void *arg, bool write_only)
5815bc3cb74SMauro Carvalho Chehab {
5825bc3cb74SMauro Carvalho Chehab 	const struct v4l2_selection *p = arg;
5835bc3cb74SMauro Carvalho Chehab 
5845bc3cb74SMauro Carvalho Chehab 	pr_cont("type=%s, target=%d, flags=0x%x, wxh=%dx%d, x,y=%d,%d\n",
5855bc3cb74SMauro Carvalho Chehab 		prt_names(p->type, v4l2_type_names),
5865bc3cb74SMauro Carvalho Chehab 		p->target, p->flags,
5875bc3cb74SMauro Carvalho Chehab 		p->r.width, p->r.height, p->r.left, p->r.top);
5885bc3cb74SMauro Carvalho Chehab }
5895bc3cb74SMauro Carvalho Chehab 
5905bc3cb74SMauro Carvalho Chehab static void v4l_print_jpegcompression(const void *arg, bool write_only)
5915bc3cb74SMauro Carvalho Chehab {
5925bc3cb74SMauro Carvalho Chehab 	const struct v4l2_jpegcompression *p = arg;
5935bc3cb74SMauro Carvalho Chehab 
5948720427cSMauro Carvalho Chehab 	pr_cont("quality=%d, APPn=%d, APP_len=%d, COM_len=%d, jpeg_markers=0x%x\n",
5955bc3cb74SMauro Carvalho Chehab 		p->quality, p->APPn, p->APP_len,
5965bc3cb74SMauro Carvalho Chehab 		p->COM_len, p->jpeg_markers);
5975bc3cb74SMauro Carvalho Chehab }
5985bc3cb74SMauro Carvalho Chehab 
5995bc3cb74SMauro Carvalho Chehab static void v4l_print_enc_idx(const void *arg, bool write_only)
6005bc3cb74SMauro Carvalho Chehab {
6015bc3cb74SMauro Carvalho Chehab 	const struct v4l2_enc_idx *p = arg;
6025bc3cb74SMauro Carvalho Chehab 
6035bc3cb74SMauro Carvalho Chehab 	pr_cont("entries=%d, entries_cap=%d\n",
6045bc3cb74SMauro Carvalho Chehab 			p->entries, p->entries_cap);
6055bc3cb74SMauro Carvalho Chehab }
6065bc3cb74SMauro Carvalho Chehab 
6075bc3cb74SMauro Carvalho Chehab static void v4l_print_encoder_cmd(const void *arg, bool write_only)
6085bc3cb74SMauro Carvalho Chehab {
6095bc3cb74SMauro Carvalho Chehab 	const struct v4l2_encoder_cmd *p = arg;
6105bc3cb74SMauro Carvalho Chehab 
6115bc3cb74SMauro Carvalho Chehab 	pr_cont("cmd=%d, flags=0x%x\n",
6125bc3cb74SMauro Carvalho Chehab 			p->cmd, p->flags);
6135bc3cb74SMauro Carvalho Chehab }
6145bc3cb74SMauro Carvalho Chehab 
6155bc3cb74SMauro Carvalho Chehab static void v4l_print_decoder_cmd(const void *arg, bool write_only)
6165bc3cb74SMauro Carvalho Chehab {
6175bc3cb74SMauro Carvalho Chehab 	const struct v4l2_decoder_cmd *p = arg;
6185bc3cb74SMauro Carvalho Chehab 
6195bc3cb74SMauro Carvalho Chehab 	pr_cont("cmd=%d, flags=0x%x\n", p->cmd, p->flags);
6205bc3cb74SMauro Carvalho Chehab 
6215bc3cb74SMauro Carvalho Chehab 	if (p->cmd == V4L2_DEC_CMD_START)
6225bc3cb74SMauro Carvalho Chehab 		pr_info("speed=%d, format=%u\n",
6235bc3cb74SMauro Carvalho Chehab 				p->start.speed, p->start.format);
6245bc3cb74SMauro Carvalho Chehab 	else if (p->cmd == V4L2_DEC_CMD_STOP)
6255bc3cb74SMauro Carvalho Chehab 		pr_info("pts=%llu\n", p->stop.pts);
6265bc3cb74SMauro Carvalho Chehab }
6275bc3cb74SMauro Carvalho Chehab 
62896b03d2aSHans Verkuil static void v4l_print_dbg_chip_info(const void *arg, bool write_only)
62979b0c640SHans Verkuil {
63096b03d2aSHans Verkuil 	const struct v4l2_dbg_chip_info *p = arg;
63179b0c640SHans Verkuil 
63279b0c640SHans Verkuil 	pr_cont("type=%u, ", p->match.type);
6333eef2510SHans Verkuil 	if (p->match.type == V4L2_CHIP_MATCH_I2C_DRIVER)
63479b0c640SHans Verkuil 		pr_cont("name=%.*s, ",
63579b0c640SHans Verkuil 				(int)sizeof(p->match.name), p->match.name);
63679b0c640SHans Verkuil 	else
63779b0c640SHans Verkuil 		pr_cont("addr=%u, ", p->match.addr);
63879b0c640SHans Verkuil 	pr_cont("name=%.*s\n", (int)sizeof(p->name), p->name);
63979b0c640SHans Verkuil }
64079b0c640SHans Verkuil 
6415bc3cb74SMauro Carvalho Chehab static void v4l_print_dbg_register(const void *arg, bool write_only)
6425bc3cb74SMauro Carvalho Chehab {
6435bc3cb74SMauro Carvalho Chehab 	const struct v4l2_dbg_register *p = arg;
6445bc3cb74SMauro Carvalho Chehab 
6455bc3cb74SMauro Carvalho Chehab 	pr_cont("type=%u, ", p->match.type);
6463eef2510SHans Verkuil 	if (p->match.type == V4L2_CHIP_MATCH_I2C_DRIVER)
64727d5a87cSHans Verkuil 		pr_cont("name=%.*s, ",
64827d5a87cSHans Verkuil 				(int)sizeof(p->match.name), p->match.name);
6495bc3cb74SMauro Carvalho Chehab 	else
6505bc3cb74SMauro Carvalho Chehab 		pr_cont("addr=%u, ", p->match.addr);
6515bc3cb74SMauro Carvalho Chehab 	pr_cont("reg=0x%llx, val=0x%llx\n",
6525bc3cb74SMauro Carvalho Chehab 			p->reg, p->val);
6535bc3cb74SMauro Carvalho Chehab }
6545bc3cb74SMauro Carvalho Chehab 
6555bc3cb74SMauro Carvalho Chehab static void v4l_print_dv_timings(const void *arg, bool write_only)
6565bc3cb74SMauro Carvalho Chehab {
6575bc3cb74SMauro Carvalho Chehab 	const struct v4l2_dv_timings *p = arg;
6585bc3cb74SMauro Carvalho Chehab 
6595bc3cb74SMauro Carvalho Chehab 	switch (p->type) {
6605bc3cb74SMauro Carvalho Chehab 	case V4L2_DV_BT_656_1120:
6618720427cSMauro Carvalho Chehab 		pr_cont("type=bt-656/1120, interlaced=%u, pixelclock=%llu, width=%u, height=%u, polarities=0x%x, hfrontporch=%u, hsync=%u, hbackporch=%u, vfrontporch=%u, vsync=%u, vbackporch=%u, il_vfrontporch=%u, il_vsync=%u, il_vbackporch=%u, standards=0x%x, flags=0x%x\n",
6625bc3cb74SMauro Carvalho Chehab 				p->bt.interlaced, p->bt.pixelclock,
6635bc3cb74SMauro Carvalho Chehab 				p->bt.width, p->bt.height,
6645bc3cb74SMauro Carvalho Chehab 				p->bt.polarities, p->bt.hfrontporch,
6655bc3cb74SMauro Carvalho Chehab 				p->bt.hsync, p->bt.hbackporch,
6665bc3cb74SMauro Carvalho Chehab 				p->bt.vfrontporch, p->bt.vsync,
6675bc3cb74SMauro Carvalho Chehab 				p->bt.vbackporch, p->bt.il_vfrontporch,
6685bc3cb74SMauro Carvalho Chehab 				p->bt.il_vsync, p->bt.il_vbackporch,
6695bc3cb74SMauro Carvalho Chehab 				p->bt.standards, p->bt.flags);
6705bc3cb74SMauro Carvalho Chehab 		break;
6715bc3cb74SMauro Carvalho Chehab 	default:
6725bc3cb74SMauro Carvalho Chehab 		pr_cont("type=%d\n", p->type);
6735bc3cb74SMauro Carvalho Chehab 		break;
6745bc3cb74SMauro Carvalho Chehab 	}
6755bc3cb74SMauro Carvalho Chehab }
6765bc3cb74SMauro Carvalho Chehab 
6775bc3cb74SMauro Carvalho Chehab static void v4l_print_enum_dv_timings(const void *arg, bool write_only)
6785bc3cb74SMauro Carvalho Chehab {
6795bc3cb74SMauro Carvalho Chehab 	const struct v4l2_enum_dv_timings *p = arg;
6805bc3cb74SMauro Carvalho Chehab 
6815bc3cb74SMauro Carvalho Chehab 	pr_cont("index=%u, ", p->index);
6825bc3cb74SMauro Carvalho Chehab 	v4l_print_dv_timings(&p->timings, write_only);
6835bc3cb74SMauro Carvalho Chehab }
6845bc3cb74SMauro Carvalho Chehab 
6855bc3cb74SMauro Carvalho Chehab static void v4l_print_dv_timings_cap(const void *arg, bool write_only)
6865bc3cb74SMauro Carvalho Chehab {
6875bc3cb74SMauro Carvalho Chehab 	const struct v4l2_dv_timings_cap *p = arg;
6885bc3cb74SMauro Carvalho Chehab 
6895bc3cb74SMauro Carvalho Chehab 	switch (p->type) {
6905bc3cb74SMauro Carvalho Chehab 	case V4L2_DV_BT_656_1120:
6918720427cSMauro Carvalho Chehab 		pr_cont("type=bt-656/1120, width=%u-%u, height=%u-%u, pixelclock=%llu-%llu, standards=0x%x, capabilities=0x%x\n",
6925bc3cb74SMauro Carvalho Chehab 			p->bt.min_width, p->bt.max_width,
6935bc3cb74SMauro Carvalho Chehab 			p->bt.min_height, p->bt.max_height,
6945bc3cb74SMauro Carvalho Chehab 			p->bt.min_pixelclock, p->bt.max_pixelclock,
6955bc3cb74SMauro Carvalho Chehab 			p->bt.standards, p->bt.capabilities);
6965bc3cb74SMauro Carvalho Chehab 		break;
6975bc3cb74SMauro Carvalho Chehab 	default:
6985bc3cb74SMauro Carvalho Chehab 		pr_cont("type=%u\n", p->type);
6995bc3cb74SMauro Carvalho Chehab 		break;
7005bc3cb74SMauro Carvalho Chehab 	}
7015bc3cb74SMauro Carvalho Chehab }
7025bc3cb74SMauro Carvalho Chehab 
7035bc3cb74SMauro Carvalho Chehab static void v4l_print_frmsizeenum(const void *arg, bool write_only)
7045bc3cb74SMauro Carvalho Chehab {
7055bc3cb74SMauro Carvalho Chehab 	const struct v4l2_frmsizeenum *p = arg;
7065bc3cb74SMauro Carvalho Chehab 
7075bc3cb74SMauro Carvalho Chehab 	pr_cont("index=%u, pixelformat=%c%c%c%c, type=%u",
7085bc3cb74SMauro Carvalho Chehab 			p->index,
7095bc3cb74SMauro Carvalho Chehab 			(p->pixel_format & 0xff),
7105bc3cb74SMauro Carvalho Chehab 			(p->pixel_format >>  8) & 0xff,
7115bc3cb74SMauro Carvalho Chehab 			(p->pixel_format >> 16) & 0xff,
7125bc3cb74SMauro Carvalho Chehab 			(p->pixel_format >> 24) & 0xff,
7135bc3cb74SMauro Carvalho Chehab 			p->type);
7145bc3cb74SMauro Carvalho Chehab 	switch (p->type) {
7155bc3cb74SMauro Carvalho Chehab 	case V4L2_FRMSIZE_TYPE_DISCRETE:
716560dde24SHans Verkuil 		pr_cont(", wxh=%ux%u\n",
7175bc3cb74SMauro Carvalho Chehab 			p->discrete.width, p->discrete.height);
7185bc3cb74SMauro Carvalho Chehab 		break;
7195bc3cb74SMauro Carvalho Chehab 	case V4L2_FRMSIZE_TYPE_STEPWISE:
720560dde24SHans Verkuil 		pr_cont(", min=%ux%u, max=%ux%u, step=%ux%u\n",
7215bc3cb74SMauro Carvalho Chehab 				p->stepwise.min_width,  p->stepwise.min_height,
7225bc3cb74SMauro Carvalho Chehab 				p->stepwise.step_width, p->stepwise.step_height,
7235bc3cb74SMauro Carvalho Chehab 				p->stepwise.max_width,  p->stepwise.max_height);
7245bc3cb74SMauro Carvalho Chehab 		break;
7255bc3cb74SMauro Carvalho Chehab 	case V4L2_FRMSIZE_TYPE_CONTINUOUS:
7265bc3cb74SMauro Carvalho Chehab 		/* fall through */
7275bc3cb74SMauro Carvalho Chehab 	default:
7285bc3cb74SMauro Carvalho Chehab 		pr_cont("\n");
7295bc3cb74SMauro Carvalho Chehab 		break;
7305bc3cb74SMauro Carvalho Chehab 	}
7315bc3cb74SMauro Carvalho Chehab }
7325bc3cb74SMauro Carvalho Chehab 
7335bc3cb74SMauro Carvalho Chehab static void v4l_print_frmivalenum(const void *arg, bool write_only)
7345bc3cb74SMauro Carvalho Chehab {
7355bc3cb74SMauro Carvalho Chehab 	const struct v4l2_frmivalenum *p = arg;
7365bc3cb74SMauro Carvalho Chehab 
7375bc3cb74SMauro Carvalho Chehab 	pr_cont("index=%u, pixelformat=%c%c%c%c, wxh=%ux%u, type=%u",
7385bc3cb74SMauro Carvalho Chehab 			p->index,
7395bc3cb74SMauro Carvalho Chehab 			(p->pixel_format & 0xff),
7405bc3cb74SMauro Carvalho Chehab 			(p->pixel_format >>  8) & 0xff,
7415bc3cb74SMauro Carvalho Chehab 			(p->pixel_format >> 16) & 0xff,
7425bc3cb74SMauro Carvalho Chehab 			(p->pixel_format >> 24) & 0xff,
7435bc3cb74SMauro Carvalho Chehab 			p->width, p->height, p->type);
7445bc3cb74SMauro Carvalho Chehab 	switch (p->type) {
7455bc3cb74SMauro Carvalho Chehab 	case V4L2_FRMIVAL_TYPE_DISCRETE:
746560dde24SHans Verkuil 		pr_cont(", fps=%d/%d\n",
7475bc3cb74SMauro Carvalho Chehab 				p->discrete.numerator,
7485bc3cb74SMauro Carvalho Chehab 				p->discrete.denominator);
7495bc3cb74SMauro Carvalho Chehab 		break;
7505bc3cb74SMauro Carvalho Chehab 	case V4L2_FRMIVAL_TYPE_STEPWISE:
751560dde24SHans Verkuil 		pr_cont(", min=%d/%d, max=%d/%d, step=%d/%d\n",
7525bc3cb74SMauro Carvalho Chehab 				p->stepwise.min.numerator,
7535bc3cb74SMauro Carvalho Chehab 				p->stepwise.min.denominator,
7545bc3cb74SMauro Carvalho Chehab 				p->stepwise.max.numerator,
7555bc3cb74SMauro Carvalho Chehab 				p->stepwise.max.denominator,
7565bc3cb74SMauro Carvalho Chehab 				p->stepwise.step.numerator,
7575bc3cb74SMauro Carvalho Chehab 				p->stepwise.step.denominator);
7585bc3cb74SMauro Carvalho Chehab 		break;
7595bc3cb74SMauro Carvalho Chehab 	case V4L2_FRMIVAL_TYPE_CONTINUOUS:
7605bc3cb74SMauro Carvalho Chehab 		/* fall through */
7615bc3cb74SMauro Carvalho Chehab 	default:
7625bc3cb74SMauro Carvalho Chehab 		pr_cont("\n");
7635bc3cb74SMauro Carvalho Chehab 		break;
7645bc3cb74SMauro Carvalho Chehab 	}
7655bc3cb74SMauro Carvalho Chehab }
7665bc3cb74SMauro Carvalho Chehab 
7675bc3cb74SMauro Carvalho Chehab static void v4l_print_event(const void *arg, bool write_only)
7685bc3cb74SMauro Carvalho Chehab {
7695bc3cb74SMauro Carvalho Chehab 	const struct v4l2_event *p = arg;
7705bc3cb74SMauro Carvalho Chehab 	const struct v4l2_event_ctrl *c;
7715bc3cb74SMauro Carvalho Chehab 
7728720427cSMauro Carvalho Chehab 	pr_cont("type=0x%x, pending=%u, sequence=%u, id=%u, timestamp=%lu.%9.9lu\n",
7735bc3cb74SMauro Carvalho Chehab 			p->type, p->pending, p->sequence, p->id,
7745bc3cb74SMauro Carvalho Chehab 			p->timestamp.tv_sec, p->timestamp.tv_nsec);
7755bc3cb74SMauro Carvalho Chehab 	switch (p->type) {
7765bc3cb74SMauro Carvalho Chehab 	case V4L2_EVENT_VSYNC:
7775bc3cb74SMauro Carvalho Chehab 		printk(KERN_DEBUG "field=%s\n",
7785bc3cb74SMauro Carvalho Chehab 			prt_names(p->u.vsync.field, v4l2_field_names));
7795bc3cb74SMauro Carvalho Chehab 		break;
7805bc3cb74SMauro Carvalho Chehab 	case V4L2_EVENT_CTRL:
7815bc3cb74SMauro Carvalho Chehab 		c = &p->u.ctrl;
7825bc3cb74SMauro Carvalho Chehab 		printk(KERN_DEBUG "changes=0x%x, type=%u, ",
7835bc3cb74SMauro Carvalho Chehab 			c->changes, c->type);
7845bc3cb74SMauro Carvalho Chehab 		if (c->type == V4L2_CTRL_TYPE_INTEGER64)
7855bc3cb74SMauro Carvalho Chehab 			pr_cont("value64=%lld, ", c->value64);
7865bc3cb74SMauro Carvalho Chehab 		else
7875bc3cb74SMauro Carvalho Chehab 			pr_cont("value=%d, ", c->value);
7888720427cSMauro Carvalho Chehab 		pr_cont("flags=0x%x, minimum=%d, maximum=%d, step=%d, default_value=%d\n",
7895bc3cb74SMauro Carvalho Chehab 			c->flags, c->minimum, c->maximum,
7905bc3cb74SMauro Carvalho Chehab 			c->step, c->default_value);
7915bc3cb74SMauro Carvalho Chehab 		break;
7925bc3cb74SMauro Carvalho Chehab 	case V4L2_EVENT_FRAME_SYNC:
7935bc3cb74SMauro Carvalho Chehab 		pr_cont("frame_sequence=%u\n",
7945bc3cb74SMauro Carvalho Chehab 			p->u.frame_sync.frame_sequence);
7955bc3cb74SMauro Carvalho Chehab 		break;
7965bc3cb74SMauro Carvalho Chehab 	}
7975bc3cb74SMauro Carvalho Chehab }
7985bc3cb74SMauro Carvalho Chehab 
7995bc3cb74SMauro Carvalho Chehab static void v4l_print_event_subscription(const void *arg, bool write_only)
8005bc3cb74SMauro Carvalho Chehab {
8015bc3cb74SMauro Carvalho Chehab 	const struct v4l2_event_subscription *p = arg;
8025bc3cb74SMauro Carvalho Chehab 
8035bc3cb74SMauro Carvalho Chehab 	pr_cont("type=0x%x, id=0x%x, flags=0x%x\n",
8045bc3cb74SMauro Carvalho Chehab 			p->type, p->id, p->flags);
8055bc3cb74SMauro Carvalho Chehab }
8065bc3cb74SMauro Carvalho Chehab 
8075bc3cb74SMauro Carvalho Chehab static void v4l_print_sliced_vbi_cap(const void *arg, bool write_only)
8085bc3cb74SMauro Carvalho Chehab {
8095bc3cb74SMauro Carvalho Chehab 	const struct v4l2_sliced_vbi_cap *p = arg;
8105bc3cb74SMauro Carvalho Chehab 	int i;
8115bc3cb74SMauro Carvalho Chehab 
8125bc3cb74SMauro Carvalho Chehab 	pr_cont("type=%s, service_set=0x%08x\n",
8135bc3cb74SMauro Carvalho Chehab 			prt_names(p->type, v4l2_type_names), p->service_set);
8145bc3cb74SMauro Carvalho Chehab 	for (i = 0; i < 24; i++)
8155bc3cb74SMauro Carvalho Chehab 		printk(KERN_DEBUG "line[%02u]=0x%04x, 0x%04x\n", i,
8165bc3cb74SMauro Carvalho Chehab 				p->service_lines[0][i],
8175bc3cb74SMauro Carvalho Chehab 				p->service_lines[1][i]);
8185bc3cb74SMauro Carvalho Chehab }
8195bc3cb74SMauro Carvalho Chehab 
8205bc3cb74SMauro Carvalho Chehab static void v4l_print_freq_band(const void *arg, bool write_only)
8215bc3cb74SMauro Carvalho Chehab {
8225bc3cb74SMauro Carvalho Chehab 	const struct v4l2_frequency_band *p = arg;
8235bc3cb74SMauro Carvalho Chehab 
8248720427cSMauro Carvalho Chehab 	pr_cont("tuner=%u, type=%u, index=%u, capability=0x%x, rangelow=%u, rangehigh=%u, modulation=0x%x\n",
8255bc3cb74SMauro Carvalho Chehab 			p->tuner, p->type, p->index,
8265bc3cb74SMauro Carvalho Chehab 			p->capability, p->rangelow,
8275bc3cb74SMauro Carvalho Chehab 			p->rangehigh, p->modulation);
8285bc3cb74SMauro Carvalho Chehab }
8295bc3cb74SMauro Carvalho Chehab 
830dd519bb3SHans Verkuil static void v4l_print_edid(const void *arg, bool write_only)
831dd519bb3SHans Verkuil {
832dd519bb3SHans Verkuil 	const struct v4l2_edid *p = arg;
833dd519bb3SHans Verkuil 
834dd519bb3SHans Verkuil 	pr_cont("pad=%u, start_block=%u, blocks=%u\n",
835dd519bb3SHans Verkuil 		p->pad, p->start_block, p->blocks);
836dd519bb3SHans Verkuil }
837dd519bb3SHans Verkuil 
8385bc3cb74SMauro Carvalho Chehab static void v4l_print_u32(const void *arg, bool write_only)
8395bc3cb74SMauro Carvalho Chehab {
8405bc3cb74SMauro Carvalho Chehab 	pr_cont("value=%u\n", *(const u32 *)arg);
8415bc3cb74SMauro Carvalho Chehab }
8425bc3cb74SMauro Carvalho Chehab 
8435bc3cb74SMauro Carvalho Chehab static void v4l_print_newline(const void *arg, bool write_only)
8445bc3cb74SMauro Carvalho Chehab {
8455bc3cb74SMauro Carvalho Chehab 	pr_cont("\n");
8465bc3cb74SMauro Carvalho Chehab }
8475bc3cb74SMauro Carvalho Chehab 
8485bc3cb74SMauro Carvalho Chehab static void v4l_print_default(const void *arg, bool write_only)
8495bc3cb74SMauro Carvalho Chehab {
8505bc3cb74SMauro Carvalho Chehab 	pr_cont("driver-specific ioctl\n");
8515bc3cb74SMauro Carvalho Chehab }
8525bc3cb74SMauro Carvalho Chehab 
8535bc3cb74SMauro Carvalho Chehab static int check_ext_ctrls(struct v4l2_ext_controls *c, int allow_priv)
8545bc3cb74SMauro Carvalho Chehab {
8555bc3cb74SMauro Carvalho Chehab 	__u32 i;
8565bc3cb74SMauro Carvalho Chehab 
8575bc3cb74SMauro Carvalho Chehab 	/* zero the reserved fields */
8585bc3cb74SMauro Carvalho Chehab 	c->reserved[0] = c->reserved[1] = 0;
8595bc3cb74SMauro Carvalho Chehab 	for (i = 0; i < c->count; i++)
8605bc3cb74SMauro Carvalho Chehab 		c->controls[i].reserved2[0] = 0;
8615bc3cb74SMauro Carvalho Chehab 
8625bc3cb74SMauro Carvalho Chehab 	/* V4L2_CID_PRIVATE_BASE cannot be used as control class
8635bc3cb74SMauro Carvalho Chehab 	   when using extended controls.
8645bc3cb74SMauro Carvalho Chehab 	   Only when passed in through VIDIOC_G_CTRL and VIDIOC_S_CTRL
8655bc3cb74SMauro Carvalho Chehab 	   is it allowed for backwards compatibility.
8665bc3cb74SMauro Carvalho Chehab 	 */
8670f8017beSRicardo Ribalda 	if (!allow_priv && c->which == V4L2_CID_PRIVATE_BASE)
8685bc3cb74SMauro Carvalho Chehab 		return 0;
8690f8017beSRicardo Ribalda 	if (!c->which)
8709b239b22SHans Verkuil 		return 1;
8715bc3cb74SMauro Carvalho Chehab 	/* Check that all controls are from the same control class. */
8725bc3cb74SMauro Carvalho Chehab 	for (i = 0; i < c->count; i++) {
8730f8017beSRicardo Ribalda 		if (V4L2_CTRL_ID2WHICH(c->controls[i].id) != c->which) {
8745bc3cb74SMauro Carvalho Chehab 			c->error_idx = i;
8755bc3cb74SMauro Carvalho Chehab 			return 0;
8765bc3cb74SMauro Carvalho Chehab 		}
8775bc3cb74SMauro Carvalho Chehab 	}
8785bc3cb74SMauro Carvalho Chehab 	return 1;
8795bc3cb74SMauro Carvalho Chehab }
8805bc3cb74SMauro Carvalho Chehab 
8814b20259fSHans Verkuil static int check_fmt(struct file *file, enum v4l2_buf_type type)
8825bc3cb74SMauro Carvalho Chehab {
8834b20259fSHans Verkuil 	struct video_device *vfd = video_devdata(file);
8844b20259fSHans Verkuil 	const struct v4l2_ioctl_ops *ops = vfd->ioctl_ops;
8854b20259fSHans Verkuil 	bool is_vid = vfd->vfl_type == VFL_TYPE_GRABBER;
8864b20259fSHans Verkuil 	bool is_vbi = vfd->vfl_type == VFL_TYPE_VBI;
887582c52cbSAntti Palosaari 	bool is_sdr = vfd->vfl_type == VFL_TYPE_SDR;
888b2fe22d0SNick Dyer 	bool is_tch = vfd->vfl_type == VFL_TYPE_TOUCH;
8894b20259fSHans Verkuil 	bool is_rx = vfd->vfl_dir != VFL_DIR_TX;
8904b20259fSHans Verkuil 	bool is_tx = vfd->vfl_dir != VFL_DIR_RX;
8914b20259fSHans Verkuil 
8925bc3cb74SMauro Carvalho Chehab 	if (ops == NULL)
8935bc3cb74SMauro Carvalho Chehab 		return -EINVAL;
8945bc3cb74SMauro Carvalho Chehab 
8955bc3cb74SMauro Carvalho Chehab 	switch (type) {
8965bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_CAPTURE:
897b2fe22d0SNick Dyer 		if ((is_vid || is_tch) && is_rx &&
8984b20259fSHans Verkuil 		    (ops->vidioc_g_fmt_vid_cap || ops->vidioc_g_fmt_vid_cap_mplane))
8995bc3cb74SMauro Carvalho Chehab 			return 0;
9005bc3cb74SMauro Carvalho Chehab 		break;
9015bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
9024b20259fSHans Verkuil 		if (is_vid && is_rx && ops->vidioc_g_fmt_vid_cap_mplane)
9035bc3cb74SMauro Carvalho Chehab 			return 0;
9045bc3cb74SMauro Carvalho Chehab 		break;
9055bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_OVERLAY:
9064b20259fSHans Verkuil 		if (is_vid && is_rx && ops->vidioc_g_fmt_vid_overlay)
9075bc3cb74SMauro Carvalho Chehab 			return 0;
9085bc3cb74SMauro Carvalho Chehab 		break;
9095bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_OUTPUT:
9104b20259fSHans Verkuil 		if (is_vid && is_tx &&
9114b20259fSHans Verkuil 		    (ops->vidioc_g_fmt_vid_out || ops->vidioc_g_fmt_vid_out_mplane))
9125bc3cb74SMauro Carvalho Chehab 			return 0;
9135bc3cb74SMauro Carvalho Chehab 		break;
9145bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
9154b20259fSHans Verkuil 		if (is_vid && is_tx && ops->vidioc_g_fmt_vid_out_mplane)
9165bc3cb74SMauro Carvalho Chehab 			return 0;
9175bc3cb74SMauro Carvalho Chehab 		break;
9185bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
9194b20259fSHans Verkuil 		if (is_vid && is_tx && ops->vidioc_g_fmt_vid_out_overlay)
9205bc3cb74SMauro Carvalho Chehab 			return 0;
9215bc3cb74SMauro Carvalho Chehab 		break;
9225bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VBI_CAPTURE:
9234b20259fSHans Verkuil 		if (is_vbi && is_rx && ops->vidioc_g_fmt_vbi_cap)
9245bc3cb74SMauro Carvalho Chehab 			return 0;
9255bc3cb74SMauro Carvalho Chehab 		break;
9265bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VBI_OUTPUT:
9274b20259fSHans Verkuil 		if (is_vbi && is_tx && ops->vidioc_g_fmt_vbi_out)
9285bc3cb74SMauro Carvalho Chehab 			return 0;
9295bc3cb74SMauro Carvalho Chehab 		break;
9305bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
9314b20259fSHans Verkuil 		if (is_vbi && is_rx && ops->vidioc_g_fmt_sliced_vbi_cap)
9325bc3cb74SMauro Carvalho Chehab 			return 0;
9335bc3cb74SMauro Carvalho Chehab 		break;
9345bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
9354b20259fSHans Verkuil 		if (is_vbi && is_tx && ops->vidioc_g_fmt_sliced_vbi_out)
9365bc3cb74SMauro Carvalho Chehab 			return 0;
9375bc3cb74SMauro Carvalho Chehab 		break;
938582c52cbSAntti Palosaari 	case V4L2_BUF_TYPE_SDR_CAPTURE:
939582c52cbSAntti Palosaari 		if (is_sdr && is_rx && ops->vidioc_g_fmt_sdr_cap)
940582c52cbSAntti Palosaari 			return 0;
941582c52cbSAntti Palosaari 		break;
9429effc72fSAntti Palosaari 	case V4L2_BUF_TYPE_SDR_OUTPUT:
9439effc72fSAntti Palosaari 		if (is_sdr && is_tx && ops->vidioc_g_fmt_sdr_out)
9449effc72fSAntti Palosaari 			return 0;
9459effc72fSAntti Palosaari 		break;
946633c98e5SHans Verkuil 	default:
9475bc3cb74SMauro Carvalho Chehab 		break;
9485bc3cb74SMauro Carvalho Chehab 	}
9495bc3cb74SMauro Carvalho Chehab 	return -EINVAL;
9505bc3cb74SMauro Carvalho Chehab }
9515bc3cb74SMauro Carvalho Chehab 
952d52e2381SLaurent Pinchart static void v4l_sanitize_format(struct v4l2_format *fmt)
953d52e2381SLaurent Pinchart {
954d52e2381SLaurent Pinchart 	unsigned int offset;
955d52e2381SLaurent Pinchart 
956d52e2381SLaurent Pinchart 	/*
957d52e2381SLaurent Pinchart 	 * The v4l2_pix_format structure has been extended with fields that were
958d52e2381SLaurent Pinchart 	 * not previously required to be set to zero by applications. The priv
959d52e2381SLaurent Pinchart 	 * field, when set to a magic value, indicates the the extended fields
960d52e2381SLaurent Pinchart 	 * are valid. Otherwise they will contain undefined values. To simplify
961d52e2381SLaurent Pinchart 	 * the API towards drivers zero the extended fields and set the priv
962d52e2381SLaurent Pinchart 	 * field to the magic value when the extended pixel format structure
963d52e2381SLaurent Pinchart 	 * isn't used by applications.
964d52e2381SLaurent Pinchart 	 */
965d52e2381SLaurent Pinchart 
966d52e2381SLaurent Pinchart 	if (fmt->type != V4L2_BUF_TYPE_VIDEO_CAPTURE &&
967d52e2381SLaurent Pinchart 	    fmt->type != V4L2_BUF_TYPE_VIDEO_OUTPUT)
968d52e2381SLaurent Pinchart 		return;
969d52e2381SLaurent Pinchart 
970d52e2381SLaurent Pinchart 	if (fmt->fmt.pix.priv == V4L2_PIX_FMT_PRIV_MAGIC)
971d52e2381SLaurent Pinchart 		return;
972d52e2381SLaurent Pinchart 
973d52e2381SLaurent Pinchart 	fmt->fmt.pix.priv = V4L2_PIX_FMT_PRIV_MAGIC;
974d52e2381SLaurent Pinchart 
975d52e2381SLaurent Pinchart 	offset = offsetof(struct v4l2_pix_format, priv)
976d52e2381SLaurent Pinchart 	       + sizeof(fmt->fmt.pix.priv);
977d52e2381SLaurent Pinchart 	memset(((void *)&fmt->fmt.pix) + offset, 0,
978d52e2381SLaurent Pinchart 	       sizeof(fmt->fmt.pix) - offset);
979d52e2381SLaurent Pinchart }
980d52e2381SLaurent Pinchart 
9815bc3cb74SMauro Carvalho Chehab static int v4l_querycap(const struct v4l2_ioctl_ops *ops,
9825bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
9835bc3cb74SMauro Carvalho Chehab {
9845bc3cb74SMauro Carvalho Chehab 	struct v4l2_capability *cap = (struct v4l2_capability *)arg;
9857bbe7813SHans Verkuil 	struct video_device *vfd = video_devdata(file);
986d52e2381SLaurent Pinchart 	int ret;
9875bc3cb74SMauro Carvalho Chehab 
9885bc3cb74SMauro Carvalho Chehab 	cap->version = LINUX_VERSION_CODE;
9897bbe7813SHans Verkuil 	cap->device_caps = vfd->device_caps;
9907bbe7813SHans Verkuil 	cap->capabilities = vfd->device_caps | V4L2_CAP_DEVICE_CAPS;
991d52e2381SLaurent Pinchart 
992d52e2381SLaurent Pinchart 	ret = ops->vidioc_querycap(file, fh, cap);
993d52e2381SLaurent Pinchart 
994d52e2381SLaurent Pinchart 	cap->capabilities |= V4L2_CAP_EXT_PIX_FORMAT;
995454a4e72SHans Verkuil 	/*
996454a4e72SHans Verkuil 	 * Drivers MUST fill in device_caps, so check for this and
997454a4e72SHans Verkuil 	 * warn if it was forgotten.
998454a4e72SHans Verkuil 	 */
9996d7570c4SLaura Abbott 	WARN(!(cap->capabilities & V4L2_CAP_DEVICE_CAPS) ||
10006d7570c4SLaura Abbott 		!cap->device_caps, "Bad caps for driver %s, %x %x",
10016d7570c4SLaura Abbott 		cap->driver, cap->capabilities, cap->device_caps);
1002796a2bd2SHans Verkuil 	cap->device_caps |= V4L2_CAP_EXT_PIX_FORMAT;
1003d52e2381SLaurent Pinchart 
1004d52e2381SLaurent Pinchart 	return ret;
10055bc3cb74SMauro Carvalho Chehab }
10065bc3cb74SMauro Carvalho Chehab 
10075bc3cb74SMauro Carvalho Chehab static int v4l_s_input(const struct v4l2_ioctl_ops *ops,
10085bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
10095bc3cb74SMauro Carvalho Chehab {
101077fa4e07SShuah Khan 	struct video_device *vfd = video_devdata(file);
101177fa4e07SShuah Khan 	int ret;
101277fa4e07SShuah Khan 
101377fa4e07SShuah Khan 	ret = v4l_enable_media_source(vfd);
101477fa4e07SShuah Khan 	if (ret)
101577fa4e07SShuah Khan 		return ret;
10165bc3cb74SMauro Carvalho Chehab 	return ops->vidioc_s_input(file, fh, *(unsigned int *)arg);
10175bc3cb74SMauro Carvalho Chehab }
10185bc3cb74SMauro Carvalho Chehab 
10195bc3cb74SMauro Carvalho Chehab static int v4l_s_output(const struct v4l2_ioctl_ops *ops,
10205bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
10215bc3cb74SMauro Carvalho Chehab {
10225bc3cb74SMauro Carvalho Chehab 	return ops->vidioc_s_output(file, fh, *(unsigned int *)arg);
10235bc3cb74SMauro Carvalho Chehab }
10245bc3cb74SMauro Carvalho Chehab 
10255bc3cb74SMauro Carvalho Chehab static int v4l_g_priority(const struct v4l2_ioctl_ops *ops,
10265bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
10275bc3cb74SMauro Carvalho Chehab {
10285bc3cb74SMauro Carvalho Chehab 	struct video_device *vfd;
10295bc3cb74SMauro Carvalho Chehab 	u32 *p = arg;
10305bc3cb74SMauro Carvalho Chehab 
10315bc3cb74SMauro Carvalho Chehab 	vfd = video_devdata(file);
103259b702eaSLaurent Pinchart 	*p = v4l2_prio_max(vfd->prio);
10335bc3cb74SMauro Carvalho Chehab 	return 0;
10345bc3cb74SMauro Carvalho Chehab }
10355bc3cb74SMauro Carvalho Chehab 
10365bc3cb74SMauro Carvalho Chehab static int v4l_s_priority(const struct v4l2_ioctl_ops *ops,
10375bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
10385bc3cb74SMauro Carvalho Chehab {
10395bc3cb74SMauro Carvalho Chehab 	struct video_device *vfd;
10405bc3cb74SMauro Carvalho Chehab 	struct v4l2_fh *vfh;
10415bc3cb74SMauro Carvalho Chehab 	u32 *p = arg;
10425bc3cb74SMauro Carvalho Chehab 
10435bc3cb74SMauro Carvalho Chehab 	vfd = video_devdata(file);
10442438e78aSHans Verkuil 	if (!test_bit(V4L2_FL_USES_V4L2_FH, &vfd->flags))
10452438e78aSHans Verkuil 		return -ENOTTY;
10465bc3cb74SMauro Carvalho Chehab 	vfh = file->private_data;
104759b702eaSLaurent Pinchart 	return v4l2_prio_change(vfd->prio, &vfh->prio, *p);
10485bc3cb74SMauro Carvalho Chehab }
10495bc3cb74SMauro Carvalho Chehab 
10505bc3cb74SMauro Carvalho Chehab static int v4l_enuminput(const struct v4l2_ioctl_ops *ops,
10515bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
10525bc3cb74SMauro Carvalho Chehab {
105373f35418SHans Verkuil 	struct video_device *vfd = video_devdata(file);
10545bc3cb74SMauro Carvalho Chehab 	struct v4l2_input *p = arg;
10555bc3cb74SMauro Carvalho Chehab 
10565bc3cb74SMauro Carvalho Chehab 	/*
105702fa6282SHans Verkuil 	 * We set the flags for CAP_DV_TIMINGS &
10585bc3cb74SMauro Carvalho Chehab 	 * CAP_STD here based on ioctl handler provided by the
10595bc3cb74SMauro Carvalho Chehab 	 * driver. If the driver doesn't support these
10605bc3cb74SMauro Carvalho Chehab 	 * for a specific input, it must override these flags.
10615bc3cb74SMauro Carvalho Chehab 	 */
106273f35418SHans Verkuil 	if (is_valid_ioctl(vfd, VIDIOC_S_STD))
10635bc3cb74SMauro Carvalho Chehab 		p->capabilities |= V4L2_IN_CAP_STD;
10645bc3cb74SMauro Carvalho Chehab 
10655bc3cb74SMauro Carvalho Chehab 	return ops->vidioc_enum_input(file, fh, p);
10665bc3cb74SMauro Carvalho Chehab }
10675bc3cb74SMauro Carvalho Chehab 
10685bc3cb74SMauro Carvalho Chehab static int v4l_enumoutput(const struct v4l2_ioctl_ops *ops,
10695bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
10705bc3cb74SMauro Carvalho Chehab {
107173f35418SHans Verkuil 	struct video_device *vfd = video_devdata(file);
10725bc3cb74SMauro Carvalho Chehab 	struct v4l2_output *p = arg;
10735bc3cb74SMauro Carvalho Chehab 
10745bc3cb74SMauro Carvalho Chehab 	/*
107502fa6282SHans Verkuil 	 * We set the flags for CAP_DV_TIMINGS &
10765bc3cb74SMauro Carvalho Chehab 	 * CAP_STD here based on ioctl handler provided by the
10775bc3cb74SMauro Carvalho Chehab 	 * driver. If the driver doesn't support these
10785bc3cb74SMauro Carvalho Chehab 	 * for a specific output, it must override these flags.
10795bc3cb74SMauro Carvalho Chehab 	 */
108073f35418SHans Verkuil 	if (is_valid_ioctl(vfd, VIDIOC_S_STD))
10815bc3cb74SMauro Carvalho Chehab 		p->capabilities |= V4L2_OUT_CAP_STD;
10825bc3cb74SMauro Carvalho Chehab 
10835bc3cb74SMauro Carvalho Chehab 	return ops->vidioc_enum_output(file, fh, p);
10845bc3cb74SMauro Carvalho Chehab }
10855bc3cb74SMauro Carvalho Chehab 
1086ba300204SHans Verkuil static void v4l_fill_fmtdesc(struct v4l2_fmtdesc *fmt)
1087ba300204SHans Verkuil {
1088ba300204SHans Verkuil 	const unsigned sz = sizeof(fmt->description);
1089ba300204SHans Verkuil 	const char *descr = NULL;
1090ba300204SHans Verkuil 	u32 flags = 0;
1091ba300204SHans Verkuil 
1092ba300204SHans Verkuil 	/*
1093ba300204SHans Verkuil 	 * We depart from the normal coding style here since the descriptions
1094ba300204SHans Verkuil 	 * should be aligned so it is easy to see which descriptions will be
1095ba300204SHans Verkuil 	 * longer than 31 characters (the max length for a description).
1096ba300204SHans Verkuil 	 * And frankly, this is easier to read anyway.
1097ba300204SHans Verkuil 	 *
1098ba300204SHans Verkuil 	 * Note that gcc will use O(log N) comparisons to find the right case.
1099ba300204SHans Verkuil 	 */
1100ba300204SHans Verkuil 	switch (fmt->pixelformat) {
1101ba300204SHans Verkuil 	/* Max description length mask:	descr = "0123456789012345678901234567890" */
1102ba300204SHans Verkuil 	case V4L2_PIX_FMT_RGB332:	descr = "8-bit RGB 3-3-2"; break;
1103ba300204SHans Verkuil 	case V4L2_PIX_FMT_RGB444:	descr = "16-bit A/XRGB 4-4-4-4"; break;
1104ba300204SHans Verkuil 	case V4L2_PIX_FMT_ARGB444:	descr = "16-bit ARGB 4-4-4-4"; break;
1105ba300204SHans Verkuil 	case V4L2_PIX_FMT_XRGB444:	descr = "16-bit XRGB 4-4-4-4"; break;
1106ba300204SHans Verkuil 	case V4L2_PIX_FMT_RGB555:	descr = "16-bit A/XRGB 1-5-5-5"; break;
1107ba300204SHans Verkuil 	case V4L2_PIX_FMT_ARGB555:	descr = "16-bit ARGB 1-5-5-5"; break;
1108ba300204SHans Verkuil 	case V4L2_PIX_FMT_XRGB555:	descr = "16-bit XRGB 1-5-5-5"; break;
1109ba300204SHans Verkuil 	case V4L2_PIX_FMT_RGB565:	descr = "16-bit RGB 5-6-5"; break;
1110ba300204SHans Verkuil 	case V4L2_PIX_FMT_RGB555X:	descr = "16-bit A/XRGB 1-5-5-5 BE"; break;
1111ba300204SHans Verkuil 	case V4L2_PIX_FMT_ARGB555X:	descr = "16-bit ARGB 1-5-5-5 BE"; break;
1112ba300204SHans Verkuil 	case V4L2_PIX_FMT_XRGB555X:	descr = "16-bit XRGB 1-5-5-5 BE"; break;
1113ba300204SHans Verkuil 	case V4L2_PIX_FMT_RGB565X:	descr = "16-bit RGB 5-6-5 BE"; break;
1114ba300204SHans Verkuil 	case V4L2_PIX_FMT_BGR666:	descr = "18-bit BGRX 6-6-6-14"; break;
1115ba300204SHans Verkuil 	case V4L2_PIX_FMT_BGR24:	descr = "24-bit BGR 8-8-8"; break;
1116ba300204SHans Verkuil 	case V4L2_PIX_FMT_RGB24:	descr = "24-bit RGB 8-8-8"; break;
1117ba300204SHans Verkuil 	case V4L2_PIX_FMT_BGR32:	descr = "32-bit BGRA/X 8-8-8-8"; break;
1118ba300204SHans Verkuil 	case V4L2_PIX_FMT_ABGR32:	descr = "32-bit BGRA 8-8-8-8"; break;
1119ba300204SHans Verkuil 	case V4L2_PIX_FMT_XBGR32:	descr = "32-bit BGRX 8-8-8-8"; break;
1120ba300204SHans Verkuil 	case V4L2_PIX_FMT_RGB32:	descr = "32-bit A/XRGB 8-8-8-8"; break;
1121ba300204SHans Verkuil 	case V4L2_PIX_FMT_ARGB32:	descr = "32-bit ARGB 8-8-8-8"; break;
1122ba300204SHans Verkuil 	case V4L2_PIX_FMT_XRGB32:	descr = "32-bit XRGB 8-8-8-8"; break;
1123ba300204SHans Verkuil 	case V4L2_PIX_FMT_GREY:		descr = "8-bit Greyscale"; break;
1124ba300204SHans Verkuil 	case V4L2_PIX_FMT_Y4:		descr = "4-bit Greyscale"; break;
1125ba300204SHans Verkuil 	case V4L2_PIX_FMT_Y6:		descr = "6-bit Greyscale"; break;
1126ba300204SHans Verkuil 	case V4L2_PIX_FMT_Y10:		descr = "10-bit Greyscale"; break;
1127ba300204SHans Verkuil 	case V4L2_PIX_FMT_Y12:		descr = "12-bit Greyscale"; break;
1128ba300204SHans Verkuil 	case V4L2_PIX_FMT_Y16:		descr = "16-bit Greyscale"; break;
11292e5e435fSRicardo Ribalda 	case V4L2_PIX_FMT_Y16_BE:	descr = "16-bit Greyscale BE"; break;
1130ba300204SHans Verkuil 	case V4L2_PIX_FMT_Y10BPACK:	descr = "10-bit Greyscale (Packed)"; break;
1131ba300204SHans Verkuil 	case V4L2_PIX_FMT_PAL8:		descr = "8-bit Palette"; break;
1132ba300204SHans Verkuil 	case V4L2_PIX_FMT_UV8:		descr = "8-bit Chrominance UV 4-4"; break;
1133ba300204SHans Verkuil 	case V4L2_PIX_FMT_YVU410:	descr = "Planar YVU 4:1:0"; break;
1134ba300204SHans Verkuil 	case V4L2_PIX_FMT_YVU420:	descr = "Planar YVU 4:2:0"; break;
1135ba300204SHans Verkuil 	case V4L2_PIX_FMT_YUYV:		descr = "YUYV 4:2:2"; break;
1136ba300204SHans Verkuil 	case V4L2_PIX_FMT_YYUV:		descr = "YYUV 4:2:2"; break;
1137ba300204SHans Verkuil 	case V4L2_PIX_FMT_YVYU:		descr = "YVYU 4:2:2"; break;
1138ba300204SHans Verkuil 	case V4L2_PIX_FMT_UYVY:		descr = "UYVY 4:2:2"; break;
1139ba300204SHans Verkuil 	case V4L2_PIX_FMT_VYUY:		descr = "VYUY 4:2:2"; break;
1140fcbafafbSPhilipp Zabel 	case V4L2_PIX_FMT_YUV422P:	descr = "Planar YUV 4:2:2"; break;
1141ba300204SHans Verkuil 	case V4L2_PIX_FMT_YUV411P:	descr = "Planar YUV 4:1:1"; break;
1142ba300204SHans Verkuil 	case V4L2_PIX_FMT_Y41P:		descr = "YUV 4:1:1 (Packed)"; break;
1143ba300204SHans Verkuil 	case V4L2_PIX_FMT_YUV444:	descr = "16-bit A/XYUV 4-4-4-4"; break;
1144ba300204SHans Verkuil 	case V4L2_PIX_FMT_YUV555:	descr = "16-bit A/XYUV 1-5-5-5"; break;
1145ba300204SHans Verkuil 	case V4L2_PIX_FMT_YUV565:	descr = "16-bit YUV 5-6-5"; break;
1146ba300204SHans Verkuil 	case V4L2_PIX_FMT_YUV32:	descr = "32-bit A/XYUV 8-8-8-8"; break;
1147ba300204SHans Verkuil 	case V4L2_PIX_FMT_YUV410:	descr = "Planar YUV 4:1:0"; break;
1148ba300204SHans Verkuil 	case V4L2_PIX_FMT_YUV420:	descr = "Planar YUV 4:2:0"; break;
1149ba300204SHans Verkuil 	case V4L2_PIX_FMT_HI240:	descr = "8-bit Dithered RGB (BTTV)"; break;
1150ba300204SHans Verkuil 	case V4L2_PIX_FMT_HM12:		descr = "YUV 4:2:0 (16x16 Macroblocks)"; break;
1151ba300204SHans Verkuil 	case V4L2_PIX_FMT_M420:		descr = "YUV 4:2:0 (M420)"; break;
1152ba300204SHans Verkuil 	case V4L2_PIX_FMT_NV12:		descr = "Y/CbCr 4:2:0"; break;
1153ba300204SHans Verkuil 	case V4L2_PIX_FMT_NV21:		descr = "Y/CrCb 4:2:0"; break;
1154ba300204SHans Verkuil 	case V4L2_PIX_FMT_NV16:		descr = "Y/CbCr 4:2:2"; break;
1155ba300204SHans Verkuil 	case V4L2_PIX_FMT_NV61:		descr = "Y/CrCb 4:2:2"; break;
1156ba300204SHans Verkuil 	case V4L2_PIX_FMT_NV24:		descr = "Y/CbCr 4:4:4"; break;
1157ba300204SHans Verkuil 	case V4L2_PIX_FMT_NV42:		descr = "Y/CrCb 4:4:4"; break;
1158ba300204SHans Verkuil 	case V4L2_PIX_FMT_NV12M:	descr = "Y/CbCr 4:2:0 (N-C)"; break;
1159ba300204SHans Verkuil 	case V4L2_PIX_FMT_NV21M:	descr = "Y/CrCb 4:2:0 (N-C)"; break;
1160ba300204SHans Verkuil 	case V4L2_PIX_FMT_NV16M:	descr = "Y/CbCr 4:2:2 (N-C)"; break;
1161ba300204SHans Verkuil 	case V4L2_PIX_FMT_NV61M:	descr = "Y/CrCb 4:2:2 (N-C)"; break;
1162ba300204SHans Verkuil 	case V4L2_PIX_FMT_NV12MT:	descr = "Y/CbCr 4:2:0 (64x32 MB, N-C)"; break;
1163ba300204SHans Verkuil 	case V4L2_PIX_FMT_NV12MT_16X16:	descr = "Y/CbCr 4:2:0 (16x16 MB, N-C)"; break;
1164ba300204SHans Verkuil 	case V4L2_PIX_FMT_YUV420M:	descr = "Planar YUV 4:2:0 (N-C)"; break;
1165ba300204SHans Verkuil 	case V4L2_PIX_FMT_YVU420M:	descr = "Planar YVU 4:2:0 (N-C)"; break;
1166d65fae92SLaurent Pinchart 	case V4L2_PIX_FMT_YUV422M:	descr = "Planar YUV 4:2:2 (N-C)"; break;
1167d65fae92SLaurent Pinchart 	case V4L2_PIX_FMT_YVU422M:	descr = "Planar YVU 4:2:2 (N-C)"; break;
1168d65fae92SLaurent Pinchart 	case V4L2_PIX_FMT_YUV444M:	descr = "Planar YUV 4:4:4 (N-C)"; break;
1169d65fae92SLaurent Pinchart 	case V4L2_PIX_FMT_YVU444M:	descr = "Planar YVU 4:4:4 (N-C)"; break;
1170ba300204SHans Verkuil 	case V4L2_PIX_FMT_SBGGR8:	descr = "8-bit Bayer BGBG/GRGR"; break;
1171ba300204SHans Verkuil 	case V4L2_PIX_FMT_SGBRG8:	descr = "8-bit Bayer GBGB/RGRG"; break;
1172ba300204SHans Verkuil 	case V4L2_PIX_FMT_SGRBG8:	descr = "8-bit Bayer GRGR/BGBG"; break;
1173ba300204SHans Verkuil 	case V4L2_PIX_FMT_SRGGB8:	descr = "8-bit Bayer RGRG/GBGB"; break;
1174ba300204SHans Verkuil 	case V4L2_PIX_FMT_SBGGR10:	descr = "10-bit Bayer BGBG/GRGR"; break;
1175ba300204SHans Verkuil 	case V4L2_PIX_FMT_SGBRG10:	descr = "10-bit Bayer GBGB/RGRG"; break;
1176ba300204SHans Verkuil 	case V4L2_PIX_FMT_SGRBG10:	descr = "10-bit Bayer GRGR/BGBG"; break;
1177ba300204SHans Verkuil 	case V4L2_PIX_FMT_SRGGB10:	descr = "10-bit Bayer RGRG/GBGB"; break;
1178ba300204SHans Verkuil 	case V4L2_PIX_FMT_SBGGR12:	descr = "12-bit Bayer BGBG/GRGR"; break;
1179ba300204SHans Verkuil 	case V4L2_PIX_FMT_SGBRG12:	descr = "12-bit Bayer GBGB/RGRG"; break;
1180ba300204SHans Verkuil 	case V4L2_PIX_FMT_SGRBG12:	descr = "12-bit Bayer GRGR/BGBG"; break;
1181ba300204SHans Verkuil 	case V4L2_PIX_FMT_SRGGB12:	descr = "12-bit Bayer RGRG/GBGB"; break;
1182ba300204SHans Verkuil 	case V4L2_PIX_FMT_SBGGR10P:	descr = "10-bit Bayer BGBG/GRGR Packed"; break;
1183ba300204SHans Verkuil 	case V4L2_PIX_FMT_SGBRG10P:	descr = "10-bit Bayer GBGB/RGRG Packed"; break;
1184ba300204SHans Verkuil 	case V4L2_PIX_FMT_SGRBG10P:	descr = "10-bit Bayer GRGR/BGBG Packed"; break;
1185ba300204SHans Verkuil 	case V4L2_PIX_FMT_SRGGB10P:	descr = "10-bit Bayer RGRG/GBGB Packed"; break;
1186ba300204SHans Verkuil 	case V4L2_PIX_FMT_SBGGR10ALAW8:	descr = "8-bit Bayer BGBG/GRGR (A-law)"; break;
1187ba300204SHans Verkuil 	case V4L2_PIX_FMT_SGBRG10ALAW8:	descr = "8-bit Bayer GBGB/RGRG (A-law)"; break;
1188ba300204SHans Verkuil 	case V4L2_PIX_FMT_SGRBG10ALAW8:	descr = "8-bit Bayer GRGR/BGBG (A-law)"; break;
1189ba300204SHans Verkuil 	case V4L2_PIX_FMT_SRGGB10ALAW8:	descr = "8-bit Bayer RGRG/GBGB (A-law)"; break;
1190ba300204SHans Verkuil 	case V4L2_PIX_FMT_SBGGR10DPCM8:	descr = "8-bit Bayer BGBG/GRGR (DPCM)"; break;
1191ba300204SHans Verkuil 	case V4L2_PIX_FMT_SGBRG10DPCM8:	descr = "8-bit Bayer GBGB/RGRG (DPCM)"; break;
1192ba300204SHans Verkuil 	case V4L2_PIX_FMT_SGRBG10DPCM8:	descr = "8-bit Bayer GRGR/BGBG (DPCM)"; break;
1193ba300204SHans Verkuil 	case V4L2_PIX_FMT_SRGGB10DPCM8:	descr = "8-bit Bayer RGRG/GBGB (DPCM)"; break;
1194ba300204SHans Verkuil 	case V4L2_PIX_FMT_SBGGR16:	descr = "16-bit Bayer BGBG/GRGR (Exp.)"; break;
119599b74277SMauro Carvalho Chehab 	case V4L2_PIX_FMT_SN9C20X_I420:	descr = "GSPCA SN9C20X I420"; break;
1196ba300204SHans Verkuil 	case V4L2_PIX_FMT_SPCA501:	descr = "GSPCA SPCA501"; break;
1197ba300204SHans Verkuil 	case V4L2_PIX_FMT_SPCA505:	descr = "GSPCA SPCA505"; break;
1198ba300204SHans Verkuil 	case V4L2_PIX_FMT_SPCA508:	descr = "GSPCA SPCA508"; break;
1199ba300204SHans Verkuil 	case V4L2_PIX_FMT_STV0680:	descr = "GSPCA STV0680"; break;
1200ba300204SHans Verkuil 	case V4L2_PIX_FMT_TM6000:	descr = "A/V + VBI Mux Packet"; break;
1201ba300204SHans Verkuil 	case V4L2_PIX_FMT_CIT_YYVYUY:	descr = "GSPCA CIT YYVYUY"; break;
1202ba300204SHans Verkuil 	case V4L2_PIX_FMT_KONICA420:	descr = "GSPCA KONICA420"; break;
120348fc10aaSAntti Palosaari 	case V4L2_SDR_FMT_CU8:		descr = "Complex U8"; break;
120448fc10aaSAntti Palosaari 	case V4L2_SDR_FMT_CU16LE:	descr = "Complex U16LE"; break;
1205ba300204SHans Verkuil 	case V4L2_SDR_FMT_CS8:		descr = "Complex S8"; break;
1206ba300204SHans Verkuil 	case V4L2_SDR_FMT_CS14LE:	descr = "Complex S14LE"; break;
1207ba300204SHans Verkuil 	case V4L2_SDR_FMT_RU12LE:	descr = "Real U12LE"; break;
1208b2fe22d0SNick Dyer 	case V4L2_TCH_FMT_DELTA_TD16:	descr = "16-bit signed deltas"; break;
1209b2fe22d0SNick Dyer 	case V4L2_TCH_FMT_DELTA_TD08:	descr = "8-bit signed deltas"; break;
1210b2fe22d0SNick Dyer 	case V4L2_TCH_FMT_TU16:		descr = "16-bit unsigned touch data"; break;
1211b2fe22d0SNick Dyer 	case V4L2_TCH_FMT_TU08:		descr = "8-bit unsigned touch data"; break;
1212ba300204SHans Verkuil 
1213ba300204SHans Verkuil 	default:
1214ba300204SHans Verkuil 		/* Compressed formats */
1215ba300204SHans Verkuil 		flags = V4L2_FMT_FLAG_COMPRESSED;
1216ba300204SHans Verkuil 		switch (fmt->pixelformat) {
1217ba300204SHans Verkuil 		/* Max description length mask:	descr = "0123456789012345678901234567890" */
1218ba300204SHans Verkuil 		case V4L2_PIX_FMT_MJPEG:	descr = "Motion-JPEG"; break;
1219ba300204SHans Verkuil 		case V4L2_PIX_FMT_JPEG:		descr = "JFIF JPEG"; break;
1220ba300204SHans Verkuil 		case V4L2_PIX_FMT_DV:		descr = "1394"; break;
1221ba300204SHans Verkuil 		case V4L2_PIX_FMT_MPEG:		descr = "MPEG-1/2/4"; break;
1222ba300204SHans Verkuil 		case V4L2_PIX_FMT_H264:		descr = "H.264"; break;
1223ba300204SHans Verkuil 		case V4L2_PIX_FMT_H264_NO_SC:	descr = "H.264 (No Start Codes)"; break;
1224ba300204SHans Verkuil 		case V4L2_PIX_FMT_H264_MVC:	descr = "H.264 MVC"; break;
1225ba300204SHans Verkuil 		case V4L2_PIX_FMT_H263:		descr = "H.263"; break;
1226ba300204SHans Verkuil 		case V4L2_PIX_FMT_MPEG1:	descr = "MPEG-1 ES"; break;
1227ba300204SHans Verkuil 		case V4L2_PIX_FMT_MPEG2:	descr = "MPEG-2 ES"; break;
1228ba300204SHans Verkuil 		case V4L2_PIX_FMT_MPEG4:	descr = "MPEG-4 part 2 ES"; break;
1229ba300204SHans Verkuil 		case V4L2_PIX_FMT_XVID:		descr = "Xvid"; break;
1230ba300204SHans Verkuil 		case V4L2_PIX_FMT_VC1_ANNEX_G:	descr = "VC-1 (SMPTE 412M Annex G)"; break;
1231ba300204SHans Verkuil 		case V4L2_PIX_FMT_VC1_ANNEX_L:	descr = "VC-1 (SMPTE 412M Annex L)"; break;
1232ba300204SHans Verkuil 		case V4L2_PIX_FMT_VP8:		descr = "VP8"; break;
1233fa14a564SWu-Cheng Li 		case V4L2_PIX_FMT_VP9:		descr = "VP9"; break;
1234ba300204SHans Verkuil 		case V4L2_PIX_FMT_CPIA1:	descr = "GSPCA CPiA YUV"; break;
1235ba300204SHans Verkuil 		case V4L2_PIX_FMT_WNVA:		descr = "WNVA"; break;
1236ba300204SHans Verkuil 		case V4L2_PIX_FMT_SN9C10X:	descr = "GSPCA SN9C10X"; break;
1237ba300204SHans Verkuil 		case V4L2_PIX_FMT_PWC1:		descr = "Raw Philips Webcam Type (Old)"; break;
1238ba300204SHans Verkuil 		case V4L2_PIX_FMT_PWC2:		descr = "Raw Philips Webcam Type (New)"; break;
1239ba300204SHans Verkuil 		case V4L2_PIX_FMT_ET61X251:	descr = "GSPCA ET61X251"; break;
1240ba300204SHans Verkuil 		case V4L2_PIX_FMT_SPCA561:	descr = "GSPCA SPCA561"; break;
1241ba300204SHans Verkuil 		case V4L2_PIX_FMT_PAC207:	descr = "GSPCA PAC207"; break;
1242ba300204SHans Verkuil 		case V4L2_PIX_FMT_MR97310A:	descr = "GSPCA MR97310A"; break;
1243ba300204SHans Verkuil 		case V4L2_PIX_FMT_JL2005BCD:	descr = "GSPCA JL2005BCD"; break;
1244ba300204SHans Verkuil 		case V4L2_PIX_FMT_SN9C2028:	descr = "GSPCA SN9C2028"; break;
1245ba300204SHans Verkuil 		case V4L2_PIX_FMT_SQ905C:	descr = "GSPCA SQ905C"; break;
1246ba300204SHans Verkuil 		case V4L2_PIX_FMT_PJPG:		descr = "GSPCA PJPG"; break;
1247ba300204SHans Verkuil 		case V4L2_PIX_FMT_OV511:	descr = "GSPCA OV511"; break;
1248ba300204SHans Verkuil 		case V4L2_PIX_FMT_OV518:	descr = "GSPCA OV518"; break;
1249ba300204SHans Verkuil 		case V4L2_PIX_FMT_JPGL:		descr = "JPEG Lite"; break;
1250ba300204SHans Verkuil 		case V4L2_PIX_FMT_SE401:	descr = "GSPCA SE401"; break;
1251ba300204SHans Verkuil 		case V4L2_PIX_FMT_S5C_UYVY_JPG:	descr = "S5C73MX interleaved UYVY/JPEG"; break;
1252d4de6634STiffany Lin 		case V4L2_PIX_FMT_MT21C:	descr = "Mediatek Compressed Format"; break;
1253ba300204SHans Verkuil 		default:
1254ba300204SHans Verkuil 			WARN(1, "Unknown pixelformat 0x%08x\n", fmt->pixelformat);
1255ba300204SHans Verkuil 			if (fmt->description[0])
1256ba300204SHans Verkuil 				return;
1257ba300204SHans Verkuil 			flags = 0;
1258ba300204SHans Verkuil 			snprintf(fmt->description, sz, "%c%c%c%c%s",
1259ba300204SHans Verkuil 					(char)(fmt->pixelformat & 0x7f),
1260ba300204SHans Verkuil 					(char)((fmt->pixelformat >> 8) & 0x7f),
1261ba300204SHans Verkuil 					(char)((fmt->pixelformat >> 16) & 0x7f),
1262ba300204SHans Verkuil 					(char)((fmt->pixelformat >> 24) & 0x7f),
1263ba300204SHans Verkuil 					(fmt->pixelformat & (1 << 31)) ? "-BE" : "");
1264ba300204SHans Verkuil 			break;
1265ba300204SHans Verkuil 		}
1266ba300204SHans Verkuil 	}
1267ba300204SHans Verkuil 
1268ba300204SHans Verkuil 	if (descr)
1269ba300204SHans Verkuil 		WARN_ON(strlcpy(fmt->description, descr, sz) >= sz);
1270ba300204SHans Verkuil 	fmt->flags = flags;
1271ba300204SHans Verkuil }
1272ba300204SHans Verkuil 
12735bc3cb74SMauro Carvalho Chehab static int v4l_enum_fmt(const struct v4l2_ioctl_ops *ops,
12745bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
12755bc3cb74SMauro Carvalho Chehab {
12765bc3cb74SMauro Carvalho Chehab 	struct v4l2_fmtdesc *p = arg;
12774b20259fSHans Verkuil 	struct video_device *vfd = video_devdata(file);
1278ce71bbc9SHans Verkuil 	bool is_vid = vfd->vfl_type == VFL_TYPE_GRABBER;
1279ce71bbc9SHans Verkuil 	bool is_sdr = vfd->vfl_type == VFL_TYPE_SDR;
1280b2fe22d0SNick Dyer 	bool is_tch = vfd->vfl_type == VFL_TYPE_TOUCH;
12814b20259fSHans Verkuil 	bool is_rx = vfd->vfl_dir != VFL_DIR_TX;
12824b20259fSHans Verkuil 	bool is_tx = vfd->vfl_dir != VFL_DIR_RX;
1283ba300204SHans Verkuil 	int ret = -EINVAL;
12845bc3cb74SMauro Carvalho Chehab 
12855bc3cb74SMauro Carvalho Chehab 	switch (p->type) {
12865bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_CAPTURE:
1287b2fe22d0SNick Dyer 		if (unlikely(!is_rx || (!is_vid && !is_tch) || !ops->vidioc_enum_fmt_vid_cap))
12885bc3cb74SMauro Carvalho Chehab 			break;
1289ba300204SHans Verkuil 		ret = ops->vidioc_enum_fmt_vid_cap(file, fh, arg);
1290ba300204SHans Verkuil 		break;
12915bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
1292ce71bbc9SHans Verkuil 		if (unlikely(!is_rx || !is_vid || !ops->vidioc_enum_fmt_vid_cap_mplane))
12935bc3cb74SMauro Carvalho Chehab 			break;
1294ba300204SHans Verkuil 		ret = ops->vidioc_enum_fmt_vid_cap_mplane(file, fh, arg);
1295ba300204SHans Verkuil 		break;
12965bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_OVERLAY:
1297ce71bbc9SHans Verkuil 		if (unlikely(!is_rx || !is_vid || !ops->vidioc_enum_fmt_vid_overlay))
12985bc3cb74SMauro Carvalho Chehab 			break;
1299ba300204SHans Verkuil 		ret = ops->vidioc_enum_fmt_vid_overlay(file, fh, arg);
1300ba300204SHans Verkuil 		break;
13015bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_OUTPUT:
1302ce71bbc9SHans Verkuil 		if (unlikely(!is_tx || !is_vid || !ops->vidioc_enum_fmt_vid_out))
13035bc3cb74SMauro Carvalho Chehab 			break;
1304ba300204SHans Verkuil 		ret = ops->vidioc_enum_fmt_vid_out(file, fh, arg);
1305ba300204SHans Verkuil 		break;
13065bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
1307ce71bbc9SHans Verkuil 		if (unlikely(!is_tx || !is_vid || !ops->vidioc_enum_fmt_vid_out_mplane))
13085bc3cb74SMauro Carvalho Chehab 			break;
1309ba300204SHans Verkuil 		ret = ops->vidioc_enum_fmt_vid_out_mplane(file, fh, arg);
1310ba300204SHans Verkuil 		break;
1311582c52cbSAntti Palosaari 	case V4L2_BUF_TYPE_SDR_CAPTURE:
1312ce71bbc9SHans Verkuil 		if (unlikely(!is_rx || !is_sdr || !ops->vidioc_enum_fmt_sdr_cap))
1313582c52cbSAntti Palosaari 			break;
1314ba300204SHans Verkuil 		ret = ops->vidioc_enum_fmt_sdr_cap(file, fh, arg);
1315ba300204SHans Verkuil 		break;
13169effc72fSAntti Palosaari 	case V4L2_BUF_TYPE_SDR_OUTPUT:
13179effc72fSAntti Palosaari 		if (unlikely(!is_tx || !is_sdr || !ops->vidioc_enum_fmt_sdr_out))
13189effc72fSAntti Palosaari 			break;
13199effc72fSAntti Palosaari 		ret = ops->vidioc_enum_fmt_sdr_out(file, fh, arg);
13209effc72fSAntti Palosaari 		break;
13215bc3cb74SMauro Carvalho Chehab 	}
1322ba300204SHans Verkuil 	if (ret == 0)
1323ba300204SHans Verkuil 		v4l_fill_fmtdesc(p);
1324ba300204SHans Verkuil 	return ret;
13255bc3cb74SMauro Carvalho Chehab }
13265bc3cb74SMauro Carvalho Chehab 
13275bc3cb74SMauro Carvalho Chehab static int v4l_g_fmt(const struct v4l2_ioctl_ops *ops,
13285bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
13295bc3cb74SMauro Carvalho Chehab {
13305bc3cb74SMauro Carvalho Chehab 	struct v4l2_format *p = arg;
13314b20259fSHans Verkuil 	struct video_device *vfd = video_devdata(file);
13324b20259fSHans Verkuil 	bool is_vid = vfd->vfl_type == VFL_TYPE_GRABBER;
1333582c52cbSAntti Palosaari 	bool is_sdr = vfd->vfl_type == VFL_TYPE_SDR;
1334b2fe22d0SNick Dyer 	bool is_tch = vfd->vfl_type == VFL_TYPE_TOUCH;
13354b20259fSHans Verkuil 	bool is_rx = vfd->vfl_dir != VFL_DIR_TX;
13364b20259fSHans Verkuil 	bool is_tx = vfd->vfl_dir != VFL_DIR_RX;
1337d52e2381SLaurent Pinchart 	int ret;
1338d52e2381SLaurent Pinchart 
1339e5ce558aSHans Verkuil 	/*
1340e5ce558aSHans Verkuil 	 * fmt can't be cleared for these overlay types due to the 'clips'
1341e5ce558aSHans Verkuil 	 * 'clipcount' and 'bitmap' pointers in struct v4l2_window.
1342e5ce558aSHans Verkuil 	 * Those are provided by the user. So handle these two overlay types
1343e5ce558aSHans Verkuil 	 * first, and then just do a simple memset for the other types.
1344e5ce558aSHans Verkuil 	 */
1345e5ce558aSHans Verkuil 	switch (p->type) {
1346e5ce558aSHans Verkuil 	case V4L2_BUF_TYPE_VIDEO_OVERLAY:
1347e5ce558aSHans Verkuil 	case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY: {
13484d1afa51SHans Verkuil 		struct v4l2_clip __user *clips = p->fmt.win.clips;
1349e5ce558aSHans Verkuil 		u32 clipcount = p->fmt.win.clipcount;
13504d1afa51SHans Verkuil 		void __user *bitmap = p->fmt.win.bitmap;
1351e5ce558aSHans Verkuil 
1352e5ce558aSHans Verkuil 		memset(&p->fmt, 0, sizeof(p->fmt));
1353e5ce558aSHans Verkuil 		p->fmt.win.clips = clips;
1354e5ce558aSHans Verkuil 		p->fmt.win.clipcount = clipcount;
1355e5ce558aSHans Verkuil 		p->fmt.win.bitmap = bitmap;
1356e5ce558aSHans Verkuil 		break;
1357e5ce558aSHans Verkuil 	}
1358e5ce558aSHans Verkuil 	default:
1359e5ce558aSHans Verkuil 		memset(&p->fmt, 0, sizeof(p->fmt));
1360e5ce558aSHans Verkuil 		break;
1361e5ce558aSHans Verkuil 	}
1362e5ce558aSHans Verkuil 
13635bc3cb74SMauro Carvalho Chehab 	switch (p->type) {
13645bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_CAPTURE:
1365b2fe22d0SNick Dyer 		if (unlikely(!is_rx || (!is_vid && !is_tch) || !ops->vidioc_g_fmt_vid_cap))
13665bc3cb74SMauro Carvalho Chehab 			break;
136748f2650aSHans Verkuil 		p->fmt.pix.priv = V4L2_PIX_FMT_PRIV_MAGIC;
1368d52e2381SLaurent Pinchart 		ret = ops->vidioc_g_fmt_vid_cap(file, fh, arg);
136948f2650aSHans Verkuil 		/* just in case the driver zeroed it again */
1370d52e2381SLaurent Pinchart 		p->fmt.pix.priv = V4L2_PIX_FMT_PRIV_MAGIC;
1371d52e2381SLaurent Pinchart 		return ret;
13725bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
13734b20259fSHans Verkuil 		if (unlikely(!is_rx || !is_vid || !ops->vidioc_g_fmt_vid_cap_mplane))
13745bc3cb74SMauro Carvalho Chehab 			break;
13755bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_g_fmt_vid_cap_mplane(file, fh, arg);
13765bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_OVERLAY:
13774b20259fSHans Verkuil 		if (unlikely(!is_rx || !is_vid || !ops->vidioc_g_fmt_vid_overlay))
13785bc3cb74SMauro Carvalho Chehab 			break;
13795bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_g_fmt_vid_overlay(file, fh, arg);
13804b20259fSHans Verkuil 	case V4L2_BUF_TYPE_VBI_CAPTURE:
13814b20259fSHans Verkuil 		if (unlikely(!is_rx || is_vid || !ops->vidioc_g_fmt_vbi_cap))
13824b20259fSHans Verkuil 			break;
13834b20259fSHans Verkuil 		return ops->vidioc_g_fmt_vbi_cap(file, fh, arg);
13844b20259fSHans Verkuil 	case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
13854b20259fSHans Verkuil 		if (unlikely(!is_rx || is_vid || !ops->vidioc_g_fmt_sliced_vbi_cap))
13864b20259fSHans Verkuil 			break;
13874b20259fSHans Verkuil 		return ops->vidioc_g_fmt_sliced_vbi_cap(file, fh, arg);
13885bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_OUTPUT:
13894b20259fSHans Verkuil 		if (unlikely(!is_tx || !is_vid || !ops->vidioc_g_fmt_vid_out))
13905bc3cb74SMauro Carvalho Chehab 			break;
139148f2650aSHans Verkuil 		p->fmt.pix.priv = V4L2_PIX_FMT_PRIV_MAGIC;
1392d52e2381SLaurent Pinchart 		ret = ops->vidioc_g_fmt_vid_out(file, fh, arg);
139348f2650aSHans Verkuil 		/* just in case the driver zeroed it again */
1394d52e2381SLaurent Pinchart 		p->fmt.pix.priv = V4L2_PIX_FMT_PRIV_MAGIC;
1395d52e2381SLaurent Pinchart 		return ret;
13965bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
13974b20259fSHans Verkuil 		if (unlikely(!is_tx || !is_vid || !ops->vidioc_g_fmt_vid_out_mplane))
13985bc3cb74SMauro Carvalho Chehab 			break;
13995bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_g_fmt_vid_out_mplane(file, fh, arg);
14005bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
14014b20259fSHans Verkuil 		if (unlikely(!is_tx || !is_vid || !ops->vidioc_g_fmt_vid_out_overlay))
14025bc3cb74SMauro Carvalho Chehab 			break;
14035bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_g_fmt_vid_out_overlay(file, fh, arg);
14045bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VBI_OUTPUT:
14054b20259fSHans Verkuil 		if (unlikely(!is_tx || is_vid || !ops->vidioc_g_fmt_vbi_out))
14065bc3cb74SMauro Carvalho Chehab 			break;
14075bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_g_fmt_vbi_out(file, fh, arg);
14085bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
14094b20259fSHans Verkuil 		if (unlikely(!is_tx || is_vid || !ops->vidioc_g_fmt_sliced_vbi_out))
14105bc3cb74SMauro Carvalho Chehab 			break;
14115bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_g_fmt_sliced_vbi_out(file, fh, arg);
1412582c52cbSAntti Palosaari 	case V4L2_BUF_TYPE_SDR_CAPTURE:
1413582c52cbSAntti Palosaari 		if (unlikely(!is_rx || !is_sdr || !ops->vidioc_g_fmt_sdr_cap))
1414582c52cbSAntti Palosaari 			break;
1415582c52cbSAntti Palosaari 		return ops->vidioc_g_fmt_sdr_cap(file, fh, arg);
14169effc72fSAntti Palosaari 	case V4L2_BUF_TYPE_SDR_OUTPUT:
14179effc72fSAntti Palosaari 		if (unlikely(!is_tx || !is_sdr || !ops->vidioc_g_fmt_sdr_out))
14189effc72fSAntti Palosaari 			break;
14199effc72fSAntti Palosaari 		return ops->vidioc_g_fmt_sdr_out(file, fh, arg);
14205bc3cb74SMauro Carvalho Chehab 	}
14215bc3cb74SMauro Carvalho Chehab 	return -EINVAL;
14225bc3cb74SMauro Carvalho Chehab }
14235bc3cb74SMauro Carvalho Chehab 
1424b2fe22d0SNick Dyer static void v4l_pix_format_touch(struct v4l2_pix_format *p)
1425b2fe22d0SNick Dyer {
1426b2fe22d0SNick Dyer 	/*
1427b2fe22d0SNick Dyer 	 * The v4l2_pix_format structure contains fields that make no sense for
1428b2fe22d0SNick Dyer 	 * touch. Set them to default values in this case.
1429b2fe22d0SNick Dyer 	 */
1430b2fe22d0SNick Dyer 
1431b2fe22d0SNick Dyer 	p->field = V4L2_FIELD_NONE;
1432b2fe22d0SNick Dyer 	p->colorspace = V4L2_COLORSPACE_RAW;
1433b2fe22d0SNick Dyer 	p->flags = 0;
1434b2fe22d0SNick Dyer 	p->ycbcr_enc = 0;
1435b2fe22d0SNick Dyer 	p->quantization = 0;
1436b2fe22d0SNick Dyer 	p->xfer_func = 0;
1437b2fe22d0SNick Dyer }
1438b2fe22d0SNick Dyer 
14395bc3cb74SMauro Carvalho Chehab static int v4l_s_fmt(const struct v4l2_ioctl_ops *ops,
14405bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
14415bc3cb74SMauro Carvalho Chehab {
14425bc3cb74SMauro Carvalho Chehab 	struct v4l2_format *p = arg;
14434b20259fSHans Verkuil 	struct video_device *vfd = video_devdata(file);
14444b20259fSHans Verkuil 	bool is_vid = vfd->vfl_type == VFL_TYPE_GRABBER;
1445582c52cbSAntti Palosaari 	bool is_sdr = vfd->vfl_type == VFL_TYPE_SDR;
1446b2fe22d0SNick Dyer 	bool is_tch = vfd->vfl_type == VFL_TYPE_TOUCH;
14474b20259fSHans Verkuil 	bool is_rx = vfd->vfl_dir != VFL_DIR_TX;
14484b20259fSHans Verkuil 	bool is_tx = vfd->vfl_dir != VFL_DIR_RX;
144948f2650aSHans Verkuil 	int ret;
14505bc3cb74SMauro Carvalho Chehab 
145177fa4e07SShuah Khan 	ret = v4l_enable_media_source(vfd);
145277fa4e07SShuah Khan 	if (ret)
145377fa4e07SShuah Khan 		return ret;
1454d52e2381SLaurent Pinchart 	v4l_sanitize_format(p);
1455d52e2381SLaurent Pinchart 
14565bc3cb74SMauro Carvalho Chehab 	switch (p->type) {
14575bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_CAPTURE:
1458b2fe22d0SNick Dyer 		if (unlikely(!is_rx || (!is_vid && !is_tch) || !ops->vidioc_s_fmt_vid_cap))
14595bc3cb74SMauro Carvalho Chehab 			break;
14605bc3cb74SMauro Carvalho Chehab 		CLEAR_AFTER_FIELD(p, fmt.pix);
146148f2650aSHans Verkuil 		ret = ops->vidioc_s_fmt_vid_cap(file, fh, arg);
146248f2650aSHans Verkuil 		/* just in case the driver zeroed it again */
146348f2650aSHans Verkuil 		p->fmt.pix.priv = V4L2_PIX_FMT_PRIV_MAGIC;
1464b2fe22d0SNick Dyer 		if (is_tch)
1465b2fe22d0SNick Dyer 			v4l_pix_format_touch(&p->fmt.pix);
146648f2650aSHans Verkuil 		return ret;
14675bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
14684b20259fSHans Verkuil 		if (unlikely(!is_rx || !is_vid || !ops->vidioc_s_fmt_vid_cap_mplane))
14695bc3cb74SMauro Carvalho Chehab 			break;
1470c49148e8SLaurent Pinchart 		CLEAR_AFTER_FIELD(p, fmt.pix_mp.xfer_func);
14715bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_s_fmt_vid_cap_mplane(file, fh, arg);
14725bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_OVERLAY:
14734b20259fSHans Verkuil 		if (unlikely(!is_rx || !is_vid || !ops->vidioc_s_fmt_vid_overlay))
14745bc3cb74SMauro Carvalho Chehab 			break;
14755bc3cb74SMauro Carvalho Chehab 		CLEAR_AFTER_FIELD(p, fmt.win);
14765bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_s_fmt_vid_overlay(file, fh, arg);
14774b20259fSHans Verkuil 	case V4L2_BUF_TYPE_VBI_CAPTURE:
14784b20259fSHans Verkuil 		if (unlikely(!is_rx || is_vid || !ops->vidioc_s_fmt_vbi_cap))
14794b20259fSHans Verkuil 			break;
14804b20259fSHans Verkuil 		CLEAR_AFTER_FIELD(p, fmt.vbi);
14814b20259fSHans Verkuil 		return ops->vidioc_s_fmt_vbi_cap(file, fh, arg);
14824b20259fSHans Verkuil 	case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
14834b20259fSHans Verkuil 		if (unlikely(!is_rx || is_vid || !ops->vidioc_s_fmt_sliced_vbi_cap))
14844b20259fSHans Verkuil 			break;
14854b20259fSHans Verkuil 		CLEAR_AFTER_FIELD(p, fmt.sliced);
14864b20259fSHans Verkuil 		return ops->vidioc_s_fmt_sliced_vbi_cap(file, fh, arg);
14875bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_OUTPUT:
14884b20259fSHans Verkuil 		if (unlikely(!is_tx || !is_vid || !ops->vidioc_s_fmt_vid_out))
14895bc3cb74SMauro Carvalho Chehab 			break;
14905bc3cb74SMauro Carvalho Chehab 		CLEAR_AFTER_FIELD(p, fmt.pix);
149148f2650aSHans Verkuil 		ret = ops->vidioc_s_fmt_vid_out(file, fh, arg);
149248f2650aSHans Verkuil 		/* just in case the driver zeroed it again */
149348f2650aSHans Verkuil 		p->fmt.pix.priv = V4L2_PIX_FMT_PRIV_MAGIC;
149448f2650aSHans Verkuil 		return ret;
14955bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
14964b20259fSHans Verkuil 		if (unlikely(!is_tx || !is_vid || !ops->vidioc_s_fmt_vid_out_mplane))
14975bc3cb74SMauro Carvalho Chehab 			break;
1498c49148e8SLaurent Pinchart 		CLEAR_AFTER_FIELD(p, fmt.pix_mp.xfer_func);
14995bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_s_fmt_vid_out_mplane(file, fh, arg);
15005bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
15014b20259fSHans Verkuil 		if (unlikely(!is_tx || !is_vid || !ops->vidioc_s_fmt_vid_out_overlay))
15025bc3cb74SMauro Carvalho Chehab 			break;
15035bc3cb74SMauro Carvalho Chehab 		CLEAR_AFTER_FIELD(p, fmt.win);
15045bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_s_fmt_vid_out_overlay(file, fh, arg);
15055bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VBI_OUTPUT:
15064b20259fSHans Verkuil 		if (unlikely(!is_tx || is_vid || !ops->vidioc_s_fmt_vbi_out))
15075bc3cb74SMauro Carvalho Chehab 			break;
15085bc3cb74SMauro Carvalho Chehab 		CLEAR_AFTER_FIELD(p, fmt.vbi);
15095bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_s_fmt_vbi_out(file, fh, arg);
15105bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
15114b20259fSHans Verkuil 		if (unlikely(!is_tx || is_vid || !ops->vidioc_s_fmt_sliced_vbi_out))
15125bc3cb74SMauro Carvalho Chehab 			break;
15135bc3cb74SMauro Carvalho Chehab 		CLEAR_AFTER_FIELD(p, fmt.sliced);
15145bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_s_fmt_sliced_vbi_out(file, fh, arg);
1515582c52cbSAntti Palosaari 	case V4L2_BUF_TYPE_SDR_CAPTURE:
1516582c52cbSAntti Palosaari 		if (unlikely(!is_rx || !is_sdr || !ops->vidioc_s_fmt_sdr_cap))
1517582c52cbSAntti Palosaari 			break;
1518582c52cbSAntti Palosaari 		CLEAR_AFTER_FIELD(p, fmt.sdr);
1519582c52cbSAntti Palosaari 		return ops->vidioc_s_fmt_sdr_cap(file, fh, arg);
15209effc72fSAntti Palosaari 	case V4L2_BUF_TYPE_SDR_OUTPUT:
15219effc72fSAntti Palosaari 		if (unlikely(!is_tx || !is_sdr || !ops->vidioc_s_fmt_sdr_out))
15229effc72fSAntti Palosaari 			break;
15239effc72fSAntti Palosaari 		CLEAR_AFTER_FIELD(p, fmt.sdr);
15249effc72fSAntti Palosaari 		return ops->vidioc_s_fmt_sdr_out(file, fh, arg);
15255bc3cb74SMauro Carvalho Chehab 	}
15265bc3cb74SMauro Carvalho Chehab 	return -EINVAL;
15275bc3cb74SMauro Carvalho Chehab }
15285bc3cb74SMauro Carvalho Chehab 
15295bc3cb74SMauro Carvalho Chehab static int v4l_try_fmt(const struct v4l2_ioctl_ops *ops,
15305bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
15315bc3cb74SMauro Carvalho Chehab {
15325bc3cb74SMauro Carvalho Chehab 	struct v4l2_format *p = arg;
15334b20259fSHans Verkuil 	struct video_device *vfd = video_devdata(file);
15344b20259fSHans Verkuil 	bool is_vid = vfd->vfl_type == VFL_TYPE_GRABBER;
1535582c52cbSAntti Palosaari 	bool is_sdr = vfd->vfl_type == VFL_TYPE_SDR;
1536b2fe22d0SNick Dyer 	bool is_tch = vfd->vfl_type == VFL_TYPE_TOUCH;
15374b20259fSHans Verkuil 	bool is_rx = vfd->vfl_dir != VFL_DIR_TX;
15384b20259fSHans Verkuil 	bool is_tx = vfd->vfl_dir != VFL_DIR_RX;
153948f2650aSHans Verkuil 	int ret;
15405bc3cb74SMauro Carvalho Chehab 
1541d52e2381SLaurent Pinchart 	v4l_sanitize_format(p);
1542d52e2381SLaurent Pinchart 
15435bc3cb74SMauro Carvalho Chehab 	switch (p->type) {
15445bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_CAPTURE:
1545b2fe22d0SNick Dyer 		if (unlikely(!is_rx || (!is_vid && !is_tch) || !ops->vidioc_try_fmt_vid_cap))
15465bc3cb74SMauro Carvalho Chehab 			break;
15475bc3cb74SMauro Carvalho Chehab 		CLEAR_AFTER_FIELD(p, fmt.pix);
154848f2650aSHans Verkuil 		ret = ops->vidioc_try_fmt_vid_cap(file, fh, arg);
154948f2650aSHans Verkuil 		/* just in case the driver zeroed it again */
155048f2650aSHans Verkuil 		p->fmt.pix.priv = V4L2_PIX_FMT_PRIV_MAGIC;
155148f2650aSHans Verkuil 		return ret;
15525bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
15534b20259fSHans Verkuil 		if (unlikely(!is_rx || !is_vid || !ops->vidioc_try_fmt_vid_cap_mplane))
15545bc3cb74SMauro Carvalho Chehab 			break;
1555c49148e8SLaurent Pinchart 		CLEAR_AFTER_FIELD(p, fmt.pix_mp.xfer_func);
15565bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_try_fmt_vid_cap_mplane(file, fh, arg);
15575bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_OVERLAY:
15584b20259fSHans Verkuil 		if (unlikely(!is_rx || !is_vid || !ops->vidioc_try_fmt_vid_overlay))
15595bc3cb74SMauro Carvalho Chehab 			break;
15605bc3cb74SMauro Carvalho Chehab 		CLEAR_AFTER_FIELD(p, fmt.win);
15615bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_try_fmt_vid_overlay(file, fh, arg);
15624b20259fSHans Verkuil 	case V4L2_BUF_TYPE_VBI_CAPTURE:
15634b20259fSHans Verkuil 		if (unlikely(!is_rx || is_vid || !ops->vidioc_try_fmt_vbi_cap))
15644b20259fSHans Verkuil 			break;
15654b20259fSHans Verkuil 		CLEAR_AFTER_FIELD(p, fmt.vbi);
15664b20259fSHans Verkuil 		return ops->vidioc_try_fmt_vbi_cap(file, fh, arg);
15674b20259fSHans Verkuil 	case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
15684b20259fSHans Verkuil 		if (unlikely(!is_rx || is_vid || !ops->vidioc_try_fmt_sliced_vbi_cap))
15694b20259fSHans Verkuil 			break;
15704b20259fSHans Verkuil 		CLEAR_AFTER_FIELD(p, fmt.sliced);
15714b20259fSHans Verkuil 		return ops->vidioc_try_fmt_sliced_vbi_cap(file, fh, arg);
15725bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_OUTPUT:
15734b20259fSHans Verkuil 		if (unlikely(!is_tx || !is_vid || !ops->vidioc_try_fmt_vid_out))
15745bc3cb74SMauro Carvalho Chehab 			break;
15755bc3cb74SMauro Carvalho Chehab 		CLEAR_AFTER_FIELD(p, fmt.pix);
157648f2650aSHans Verkuil 		ret = ops->vidioc_try_fmt_vid_out(file, fh, arg);
157748f2650aSHans Verkuil 		/* just in case the driver zeroed it again */
157848f2650aSHans Verkuil 		p->fmt.pix.priv = V4L2_PIX_FMT_PRIV_MAGIC;
157948f2650aSHans Verkuil 		return ret;
15805bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
15814b20259fSHans Verkuil 		if (unlikely(!is_tx || !is_vid || !ops->vidioc_try_fmt_vid_out_mplane))
15825bc3cb74SMauro Carvalho Chehab 			break;
1583c49148e8SLaurent Pinchart 		CLEAR_AFTER_FIELD(p, fmt.pix_mp.xfer_func);
15845bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_try_fmt_vid_out_mplane(file, fh, arg);
15855bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
15864b20259fSHans Verkuil 		if (unlikely(!is_tx || !is_vid || !ops->vidioc_try_fmt_vid_out_overlay))
15875bc3cb74SMauro Carvalho Chehab 			break;
15885bc3cb74SMauro Carvalho Chehab 		CLEAR_AFTER_FIELD(p, fmt.win);
15895bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_try_fmt_vid_out_overlay(file, fh, arg);
15905bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VBI_OUTPUT:
15914b20259fSHans Verkuil 		if (unlikely(!is_tx || is_vid || !ops->vidioc_try_fmt_vbi_out))
15925bc3cb74SMauro Carvalho Chehab 			break;
15935bc3cb74SMauro Carvalho Chehab 		CLEAR_AFTER_FIELD(p, fmt.vbi);
15945bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_try_fmt_vbi_out(file, fh, arg);
15955bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
15964b20259fSHans Verkuil 		if (unlikely(!is_tx || is_vid || !ops->vidioc_try_fmt_sliced_vbi_out))
15975bc3cb74SMauro Carvalho Chehab 			break;
15985bc3cb74SMauro Carvalho Chehab 		CLEAR_AFTER_FIELD(p, fmt.sliced);
15995bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_try_fmt_sliced_vbi_out(file, fh, arg);
1600582c52cbSAntti Palosaari 	case V4L2_BUF_TYPE_SDR_CAPTURE:
1601582c52cbSAntti Palosaari 		if (unlikely(!is_rx || !is_sdr || !ops->vidioc_try_fmt_sdr_cap))
1602582c52cbSAntti Palosaari 			break;
1603582c52cbSAntti Palosaari 		CLEAR_AFTER_FIELD(p, fmt.sdr);
1604582c52cbSAntti Palosaari 		return ops->vidioc_try_fmt_sdr_cap(file, fh, arg);
16059effc72fSAntti Palosaari 	case V4L2_BUF_TYPE_SDR_OUTPUT:
16069effc72fSAntti Palosaari 		if (unlikely(!is_tx || !is_sdr || !ops->vidioc_try_fmt_sdr_out))
16079effc72fSAntti Palosaari 			break;
16089effc72fSAntti Palosaari 		CLEAR_AFTER_FIELD(p, fmt.sdr);
16099effc72fSAntti Palosaari 		return ops->vidioc_try_fmt_sdr_out(file, fh, arg);
16105bc3cb74SMauro Carvalho Chehab 	}
16115bc3cb74SMauro Carvalho Chehab 	return -EINVAL;
16125bc3cb74SMauro Carvalho Chehab }
16135bc3cb74SMauro Carvalho Chehab 
16145bc3cb74SMauro Carvalho Chehab static int v4l_streamon(const struct v4l2_ioctl_ops *ops,
16155bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
16165bc3cb74SMauro Carvalho Chehab {
16175bc3cb74SMauro Carvalho Chehab 	return ops->vidioc_streamon(file, fh, *(unsigned int *)arg);
16185bc3cb74SMauro Carvalho Chehab }
16195bc3cb74SMauro Carvalho Chehab 
16205bc3cb74SMauro Carvalho Chehab static int v4l_streamoff(const struct v4l2_ioctl_ops *ops,
16215bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
16225bc3cb74SMauro Carvalho Chehab {
16235bc3cb74SMauro Carvalho Chehab 	return ops->vidioc_streamoff(file, fh, *(unsigned int *)arg);
16245bc3cb74SMauro Carvalho Chehab }
16255bc3cb74SMauro Carvalho Chehab 
16265bc3cb74SMauro Carvalho Chehab static int v4l_g_tuner(const struct v4l2_ioctl_ops *ops,
16275bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
16285bc3cb74SMauro Carvalho Chehab {
16295bc3cb74SMauro Carvalho Chehab 	struct video_device *vfd = video_devdata(file);
16305bc3cb74SMauro Carvalho Chehab 	struct v4l2_tuner *p = arg;
16315bc3cb74SMauro Carvalho Chehab 	int err;
16325bc3cb74SMauro Carvalho Chehab 
16335bc3cb74SMauro Carvalho Chehab 	p->type = (vfd->vfl_type == VFL_TYPE_RADIO) ?
16345bc3cb74SMauro Carvalho Chehab 			V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV;
16355bc3cb74SMauro Carvalho Chehab 	err = ops->vidioc_g_tuner(file, fh, p);
16365bc3cb74SMauro Carvalho Chehab 	if (!err)
16375bc3cb74SMauro Carvalho Chehab 		p->capability |= V4L2_TUNER_CAP_FREQ_BANDS;
16385bc3cb74SMauro Carvalho Chehab 	return err;
16395bc3cb74SMauro Carvalho Chehab }
16405bc3cb74SMauro Carvalho Chehab 
16415bc3cb74SMauro Carvalho Chehab static int v4l_s_tuner(const struct v4l2_ioctl_ops *ops,
16425bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
16435bc3cb74SMauro Carvalho Chehab {
16445bc3cb74SMauro Carvalho Chehab 	struct video_device *vfd = video_devdata(file);
16455bc3cb74SMauro Carvalho Chehab 	struct v4l2_tuner *p = arg;
164677fa4e07SShuah Khan 	int ret;
16475bc3cb74SMauro Carvalho Chehab 
164877fa4e07SShuah Khan 	ret = v4l_enable_media_source(vfd);
164977fa4e07SShuah Khan 	if (ret)
165077fa4e07SShuah Khan 		return ret;
16515bc3cb74SMauro Carvalho Chehab 	p->type = (vfd->vfl_type == VFL_TYPE_RADIO) ?
16525bc3cb74SMauro Carvalho Chehab 			V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV;
16535bc3cb74SMauro Carvalho Chehab 	return ops->vidioc_s_tuner(file, fh, p);
16545bc3cb74SMauro Carvalho Chehab }
16555bc3cb74SMauro Carvalho Chehab 
16565bc3cb74SMauro Carvalho Chehab static int v4l_g_modulator(const struct v4l2_ioctl_ops *ops,
16575bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
16585bc3cb74SMauro Carvalho Chehab {
16594124a3c4SAntti Palosaari 	struct video_device *vfd = video_devdata(file);
16605bc3cb74SMauro Carvalho Chehab 	struct v4l2_modulator *p = arg;
16615bc3cb74SMauro Carvalho Chehab 	int err;
16625bc3cb74SMauro Carvalho Chehab 
16634124a3c4SAntti Palosaari 	if (vfd->vfl_type == VFL_TYPE_RADIO)
16644124a3c4SAntti Palosaari 		p->type = V4L2_TUNER_RADIO;
16654124a3c4SAntti Palosaari 
16665bc3cb74SMauro Carvalho Chehab 	err = ops->vidioc_g_modulator(file, fh, p);
16675bc3cb74SMauro Carvalho Chehab 	if (!err)
16685bc3cb74SMauro Carvalho Chehab 		p->capability |= V4L2_TUNER_CAP_FREQ_BANDS;
16695bc3cb74SMauro Carvalho Chehab 	return err;
16705bc3cb74SMauro Carvalho Chehab }
16715bc3cb74SMauro Carvalho Chehab 
16724124a3c4SAntti Palosaari static int v4l_s_modulator(const struct v4l2_ioctl_ops *ops,
16734124a3c4SAntti Palosaari 				struct file *file, void *fh, void *arg)
16744124a3c4SAntti Palosaari {
16754124a3c4SAntti Palosaari 	struct video_device *vfd = video_devdata(file);
16764124a3c4SAntti Palosaari 	struct v4l2_modulator *p = arg;
16774124a3c4SAntti Palosaari 
16784124a3c4SAntti Palosaari 	if (vfd->vfl_type == VFL_TYPE_RADIO)
16794124a3c4SAntti Palosaari 		p->type = V4L2_TUNER_RADIO;
16804124a3c4SAntti Palosaari 
16814124a3c4SAntti Palosaari 	return ops->vidioc_s_modulator(file, fh, p);
16824124a3c4SAntti Palosaari }
16834124a3c4SAntti Palosaari 
16845bc3cb74SMauro Carvalho Chehab static int v4l_g_frequency(const struct v4l2_ioctl_ops *ops,
16855bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
16865bc3cb74SMauro Carvalho Chehab {
16875bc3cb74SMauro Carvalho Chehab 	struct video_device *vfd = video_devdata(file);
16885bc3cb74SMauro Carvalho Chehab 	struct v4l2_frequency *p = arg;
16895bc3cb74SMauro Carvalho Chehab 
169084099a28SAntti Palosaari 	if (vfd->vfl_type == VFL_TYPE_SDR)
1691f3c3ececSAntti Palosaari 		p->type = V4L2_TUNER_SDR;
169284099a28SAntti Palosaari 	else
16935bc3cb74SMauro Carvalho Chehab 		p->type = (vfd->vfl_type == VFL_TYPE_RADIO) ?
16945bc3cb74SMauro Carvalho Chehab 				V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV;
16955bc3cb74SMauro Carvalho Chehab 	return ops->vidioc_g_frequency(file, fh, p);
16965bc3cb74SMauro Carvalho Chehab }
16975bc3cb74SMauro Carvalho Chehab 
16985bc3cb74SMauro Carvalho Chehab static int v4l_s_frequency(const struct v4l2_ioctl_ops *ops,
16995bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
17005bc3cb74SMauro Carvalho Chehab {
17015bc3cb74SMauro Carvalho Chehab 	struct video_device *vfd = video_devdata(file);
1702b530a447SHans Verkuil 	const struct v4l2_frequency *p = arg;
17035bc3cb74SMauro Carvalho Chehab 	enum v4l2_tuner_type type;
170477fa4e07SShuah Khan 	int ret;
17055bc3cb74SMauro Carvalho Chehab 
170677fa4e07SShuah Khan 	ret = v4l_enable_media_source(vfd);
170777fa4e07SShuah Khan 	if (ret)
170877fa4e07SShuah Khan 		return ret;
170984099a28SAntti Palosaari 	if (vfd->vfl_type == VFL_TYPE_SDR) {
1710f3c3ececSAntti Palosaari 		if (p->type != V4L2_TUNER_SDR && p->type != V4L2_TUNER_RF)
171184099a28SAntti Palosaari 			return -EINVAL;
171284099a28SAntti Palosaari 	} else {
17135bc3cb74SMauro Carvalho Chehab 		type = (vfd->vfl_type == VFL_TYPE_RADIO) ?
17145bc3cb74SMauro Carvalho Chehab 				V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV;
171584099a28SAntti Palosaari 		if (type != p->type)
17165bc3cb74SMauro Carvalho Chehab 			return -EINVAL;
171784099a28SAntti Palosaari 	}
17185bc3cb74SMauro Carvalho Chehab 	return ops->vidioc_s_frequency(file, fh, p);
17195bc3cb74SMauro Carvalho Chehab }
17205bc3cb74SMauro Carvalho Chehab 
17215bc3cb74SMauro Carvalho Chehab static int v4l_enumstd(const struct v4l2_ioctl_ops *ops,
17225bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
17235bc3cb74SMauro Carvalho Chehab {
17245bc3cb74SMauro Carvalho Chehab 	struct video_device *vfd = video_devdata(file);
17255bc3cb74SMauro Carvalho Chehab 	struct v4l2_standard *p = arg;
17265bc3cb74SMauro Carvalho Chehab 	v4l2_std_id id = vfd->tvnorms, curr_id = 0;
17275bc3cb74SMauro Carvalho Chehab 	unsigned int index = p->index, i, j = 0;
17285bc3cb74SMauro Carvalho Chehab 	const char *descr = "";
17295bc3cb74SMauro Carvalho Chehab 
1730a5338190SHans Verkuil 	/* Return -ENODATA if the tvnorms for the current input
1731a5338190SHans Verkuil 	   or output is 0, meaning that it doesn't support this API. */
1732a5338190SHans Verkuil 	if (id == 0)
1733a5338190SHans Verkuil 		return -ENODATA;
1734a5338190SHans Verkuil 
17355bc3cb74SMauro Carvalho Chehab 	/* Return norm array in a canonical way */
17365bc3cb74SMauro Carvalho Chehab 	for (i = 0; i <= index && id; i++) {
17375bc3cb74SMauro Carvalho Chehab 		/* last std value in the standards array is 0, so this
17385bc3cb74SMauro Carvalho Chehab 		   while always ends there since (id & 0) == 0. */
17395bc3cb74SMauro Carvalho Chehab 		while ((id & standards[j].std) != standards[j].std)
17405bc3cb74SMauro Carvalho Chehab 			j++;
17415bc3cb74SMauro Carvalho Chehab 		curr_id = standards[j].std;
17425bc3cb74SMauro Carvalho Chehab 		descr = standards[j].descr;
17435bc3cb74SMauro Carvalho Chehab 		j++;
17445bc3cb74SMauro Carvalho Chehab 		if (curr_id == 0)
17455bc3cb74SMauro Carvalho Chehab 			break;
17465bc3cb74SMauro Carvalho Chehab 		if (curr_id != V4L2_STD_PAL &&
17475bc3cb74SMauro Carvalho Chehab 				curr_id != V4L2_STD_SECAM &&
17485bc3cb74SMauro Carvalho Chehab 				curr_id != V4L2_STD_NTSC)
17495bc3cb74SMauro Carvalho Chehab 			id &= ~curr_id;
17505bc3cb74SMauro Carvalho Chehab 	}
17515bc3cb74SMauro Carvalho Chehab 	if (i <= index)
17525bc3cb74SMauro Carvalho Chehab 		return -EINVAL;
17535bc3cb74SMauro Carvalho Chehab 
17545bc3cb74SMauro Carvalho Chehab 	v4l2_video_std_construct(p, curr_id, descr);
17555bc3cb74SMauro Carvalho Chehab 	return 0;
17565bc3cb74SMauro Carvalho Chehab }
17575bc3cb74SMauro Carvalho Chehab 
17585bc3cb74SMauro Carvalho Chehab static int v4l_s_std(const struct v4l2_ioctl_ops *ops,
17595bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
17605bc3cb74SMauro Carvalho Chehab {
17615bc3cb74SMauro Carvalho Chehab 	struct video_device *vfd = video_devdata(file);
1762314527acSHans Verkuil 	v4l2_std_id id = *(v4l2_std_id *)arg, norm;
176377fa4e07SShuah Khan 	int ret;
17645bc3cb74SMauro Carvalho Chehab 
176577fa4e07SShuah Khan 	ret = v4l_enable_media_source(vfd);
176677fa4e07SShuah Khan 	if (ret)
176777fa4e07SShuah Khan 		return ret;
1768314527acSHans Verkuil 	norm = id & vfd->tvnorms;
17695bc3cb74SMauro Carvalho Chehab 	if (vfd->tvnorms && !norm)	/* Check if std is supported */
17705bc3cb74SMauro Carvalho Chehab 		return -EINVAL;
17715bc3cb74SMauro Carvalho Chehab 
17725bc3cb74SMauro Carvalho Chehab 	/* Calls the specific handler */
1773ca371575SHans Verkuil 	return ops->vidioc_s_std(file, fh, norm);
17745bc3cb74SMauro Carvalho Chehab }
17755bc3cb74SMauro Carvalho Chehab 
17765bc3cb74SMauro Carvalho Chehab static int v4l_querystd(const struct v4l2_ioctl_ops *ops,
17775bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
17785bc3cb74SMauro Carvalho Chehab {
17795bc3cb74SMauro Carvalho Chehab 	struct video_device *vfd = video_devdata(file);
17805bc3cb74SMauro Carvalho Chehab 	v4l2_std_id *p = arg;
178177fa4e07SShuah Khan 	int ret;
17825bc3cb74SMauro Carvalho Chehab 
178377fa4e07SShuah Khan 	ret = v4l_enable_media_source(vfd);
178477fa4e07SShuah Khan 	if (ret)
178577fa4e07SShuah Khan 		return ret;
17865bc3cb74SMauro Carvalho Chehab 	/*
17871a2c6866SHans Verkuil 	 * If no signal is detected, then the driver should return
17881a2c6866SHans Verkuil 	 * V4L2_STD_UNKNOWN. Otherwise it should return tvnorms with
17891a2c6866SHans Verkuil 	 * any standards that do not apply removed.
17901a2c6866SHans Verkuil 	 *
17915bc3cb74SMauro Carvalho Chehab 	 * This means that tuners, audio and video decoders can join
17925bc3cb74SMauro Carvalho Chehab 	 * their efforts to improve the standards detection.
17935bc3cb74SMauro Carvalho Chehab 	 */
17945bc3cb74SMauro Carvalho Chehab 	*p = vfd->tvnorms;
17955bc3cb74SMauro Carvalho Chehab 	return ops->vidioc_querystd(file, fh, arg);
17965bc3cb74SMauro Carvalho Chehab }
17975bc3cb74SMauro Carvalho Chehab 
17985bc3cb74SMauro Carvalho Chehab static int v4l_s_hw_freq_seek(const struct v4l2_ioctl_ops *ops,
17995bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
18005bc3cb74SMauro Carvalho Chehab {
18015bc3cb74SMauro Carvalho Chehab 	struct video_device *vfd = video_devdata(file);
18025bc3cb74SMauro Carvalho Chehab 	struct v4l2_hw_freq_seek *p = arg;
18035bc3cb74SMauro Carvalho Chehab 	enum v4l2_tuner_type type;
180477fa4e07SShuah Khan 	int ret;
18055bc3cb74SMauro Carvalho Chehab 
180677fa4e07SShuah Khan 	ret = v4l_enable_media_source(vfd);
180777fa4e07SShuah Khan 	if (ret)
180877fa4e07SShuah Khan 		return ret;
180984099a28SAntti Palosaari 	/* s_hw_freq_seek is not supported for SDR for now */
181084099a28SAntti Palosaari 	if (vfd->vfl_type == VFL_TYPE_SDR)
181184099a28SAntti Palosaari 		return -EINVAL;
181284099a28SAntti Palosaari 
18135bc3cb74SMauro Carvalho Chehab 	type = (vfd->vfl_type == VFL_TYPE_RADIO) ?
18145bc3cb74SMauro Carvalho Chehab 		V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV;
18155bc3cb74SMauro Carvalho Chehab 	if (p->type != type)
18165bc3cb74SMauro Carvalho Chehab 		return -EINVAL;
18175bc3cb74SMauro Carvalho Chehab 	return ops->vidioc_s_hw_freq_seek(file, fh, p);
18185bc3cb74SMauro Carvalho Chehab }
18195bc3cb74SMauro Carvalho Chehab 
1820737c097bSHans Verkuil static int v4l_overlay(const struct v4l2_ioctl_ops *ops,
1821737c097bSHans Verkuil 				struct file *file, void *fh, void *arg)
1822737c097bSHans Verkuil {
1823737c097bSHans Verkuil 	return ops->vidioc_overlay(file, fh, *(unsigned int *)arg);
1824737c097bSHans Verkuil }
1825737c097bSHans Verkuil 
18265bc3cb74SMauro Carvalho Chehab static int v4l_reqbufs(const struct v4l2_ioctl_ops *ops,
18275bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
18285bc3cb74SMauro Carvalho Chehab {
18295bc3cb74SMauro Carvalho Chehab 	struct v4l2_requestbuffers *p = arg;
18304b20259fSHans Verkuil 	int ret = check_fmt(file, p->type);
18315bc3cb74SMauro Carvalho Chehab 
18325bc3cb74SMauro Carvalho Chehab 	if (ret)
18335bc3cb74SMauro Carvalho Chehab 		return ret;
18345bc3cb74SMauro Carvalho Chehab 
18355bc3cb74SMauro Carvalho Chehab 	CLEAR_AFTER_FIELD(p, memory);
18365bc3cb74SMauro Carvalho Chehab 
18375bc3cb74SMauro Carvalho Chehab 	return ops->vidioc_reqbufs(file, fh, p);
18385bc3cb74SMauro Carvalho Chehab }
18395bc3cb74SMauro Carvalho Chehab 
18405bc3cb74SMauro Carvalho Chehab static int v4l_querybuf(const struct v4l2_ioctl_ops *ops,
18415bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
18425bc3cb74SMauro Carvalho Chehab {
18435bc3cb74SMauro Carvalho Chehab 	struct v4l2_buffer *p = arg;
18444b20259fSHans Verkuil 	int ret = check_fmt(file, p->type);
18455bc3cb74SMauro Carvalho Chehab 
18465bc3cb74SMauro Carvalho Chehab 	return ret ? ret : ops->vidioc_querybuf(file, fh, p);
18475bc3cb74SMauro Carvalho Chehab }
18485bc3cb74SMauro Carvalho Chehab 
18495bc3cb74SMauro Carvalho Chehab static int v4l_qbuf(const struct v4l2_ioctl_ops *ops,
18505bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
18515bc3cb74SMauro Carvalho Chehab {
18525bc3cb74SMauro Carvalho Chehab 	struct v4l2_buffer *p = arg;
18534b20259fSHans Verkuil 	int ret = check_fmt(file, p->type);
18545bc3cb74SMauro Carvalho Chehab 
18555bc3cb74SMauro Carvalho Chehab 	return ret ? ret : ops->vidioc_qbuf(file, fh, p);
18565bc3cb74SMauro Carvalho Chehab }
18575bc3cb74SMauro Carvalho Chehab 
18585bc3cb74SMauro Carvalho Chehab static int v4l_dqbuf(const struct v4l2_ioctl_ops *ops,
18595bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
18605bc3cb74SMauro Carvalho Chehab {
18615bc3cb74SMauro Carvalho Chehab 	struct v4l2_buffer *p = arg;
18624b20259fSHans Verkuil 	int ret = check_fmt(file, p->type);
18635bc3cb74SMauro Carvalho Chehab 
18645bc3cb74SMauro Carvalho Chehab 	return ret ? ret : ops->vidioc_dqbuf(file, fh, p);
18655bc3cb74SMauro Carvalho Chehab }
18665bc3cb74SMauro Carvalho Chehab 
18675bc3cb74SMauro Carvalho Chehab static int v4l_create_bufs(const struct v4l2_ioctl_ops *ops,
18685bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
18695bc3cb74SMauro Carvalho Chehab {
18705bc3cb74SMauro Carvalho Chehab 	struct v4l2_create_buffers *create = arg;
18714b20259fSHans Verkuil 	int ret = check_fmt(file, create->format.type);
18725bc3cb74SMauro Carvalho Chehab 
1873d52e2381SLaurent Pinchart 	if (ret)
1874d52e2381SLaurent Pinchart 		return ret;
1875d52e2381SLaurent Pinchart 
18765d351251SHans Verkuil 	CLEAR_AFTER_FIELD(create, format);
18775d351251SHans Verkuil 
1878d52e2381SLaurent Pinchart 	v4l_sanitize_format(&create->format);
1879d52e2381SLaurent Pinchart 
1880d52e2381SLaurent Pinchart 	ret = ops->vidioc_create_bufs(file, fh, create);
1881d52e2381SLaurent Pinchart 
1882d52e2381SLaurent Pinchart 	if (create->format.type == V4L2_BUF_TYPE_VIDEO_CAPTURE ||
1883d52e2381SLaurent Pinchart 	    create->format.type == V4L2_BUF_TYPE_VIDEO_OUTPUT)
1884d52e2381SLaurent Pinchart 		create->format.fmt.pix.priv = V4L2_PIX_FMT_PRIV_MAGIC;
1885d52e2381SLaurent Pinchart 
1886d52e2381SLaurent Pinchart 	return ret;
18875bc3cb74SMauro Carvalho Chehab }
18885bc3cb74SMauro Carvalho Chehab 
18895bc3cb74SMauro Carvalho Chehab static int v4l_prepare_buf(const struct v4l2_ioctl_ops *ops,
18905bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
18915bc3cb74SMauro Carvalho Chehab {
18925bc3cb74SMauro Carvalho Chehab 	struct v4l2_buffer *b = arg;
18934b20259fSHans Verkuil 	int ret = check_fmt(file, b->type);
18945bc3cb74SMauro Carvalho Chehab 
18955bc3cb74SMauro Carvalho Chehab 	return ret ? ret : ops->vidioc_prepare_buf(file, fh, b);
18965bc3cb74SMauro Carvalho Chehab }
18975bc3cb74SMauro Carvalho Chehab 
18985bc3cb74SMauro Carvalho Chehab static int v4l_g_parm(const struct v4l2_ioctl_ops *ops,
18995bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
19005bc3cb74SMauro Carvalho Chehab {
19015bc3cb74SMauro Carvalho Chehab 	struct v4l2_streamparm *p = arg;
19025bc3cb74SMauro Carvalho Chehab 	v4l2_std_id std;
19034b20259fSHans Verkuil 	int ret = check_fmt(file, p->type);
19045bc3cb74SMauro Carvalho Chehab 
19055bc3cb74SMauro Carvalho Chehab 	if (ret)
19065bc3cb74SMauro Carvalho Chehab 		return ret;
19075bc3cb74SMauro Carvalho Chehab 	if (ops->vidioc_g_parm)
19085bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_g_parm(file, fh, p);
19095bc3cb74SMauro Carvalho Chehab 	if (p->type != V4L2_BUF_TYPE_VIDEO_CAPTURE &&
19105bc3cb74SMauro Carvalho Chehab 	    p->type != V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
19115bc3cb74SMauro Carvalho Chehab 		return -EINVAL;
19125bc3cb74SMauro Carvalho Chehab 	p->parm.capture.readbuffers = 2;
19135bc3cb74SMauro Carvalho Chehab 	ret = ops->vidioc_g_std(file, fh, &std);
19145bc3cb74SMauro Carvalho Chehab 	if (ret == 0)
1915ca371575SHans Verkuil 		v4l2_video_std_frame_period(std, &p->parm.capture.timeperframe);
19165bc3cb74SMauro Carvalho Chehab 	return ret;
19175bc3cb74SMauro Carvalho Chehab }
19185bc3cb74SMauro Carvalho Chehab 
19195bc3cb74SMauro Carvalho Chehab static int v4l_s_parm(const struct v4l2_ioctl_ops *ops,
19205bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
19215bc3cb74SMauro Carvalho Chehab {
19225bc3cb74SMauro Carvalho Chehab 	struct v4l2_streamparm *p = arg;
19234b20259fSHans Verkuil 	int ret = check_fmt(file, p->type);
19245bc3cb74SMauro Carvalho Chehab 
19255bc3cb74SMauro Carvalho Chehab 	return ret ? ret : ops->vidioc_s_parm(file, fh, p);
19265bc3cb74SMauro Carvalho Chehab }
19275bc3cb74SMauro Carvalho Chehab 
19285bc3cb74SMauro Carvalho Chehab static int v4l_queryctrl(const struct v4l2_ioctl_ops *ops,
19295bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
19305bc3cb74SMauro Carvalho Chehab {
19315bc3cb74SMauro Carvalho Chehab 	struct video_device *vfd = video_devdata(file);
19325bc3cb74SMauro Carvalho Chehab 	struct v4l2_queryctrl *p = arg;
19335bc3cb74SMauro Carvalho Chehab 	struct v4l2_fh *vfh =
19345bc3cb74SMauro Carvalho Chehab 		test_bit(V4L2_FL_USES_V4L2_FH, &vfd->flags) ? fh : NULL;
19355bc3cb74SMauro Carvalho Chehab 
19365bc3cb74SMauro Carvalho Chehab 	if (vfh && vfh->ctrl_handler)
19375bc3cb74SMauro Carvalho Chehab 		return v4l2_queryctrl(vfh->ctrl_handler, p);
19385bc3cb74SMauro Carvalho Chehab 	if (vfd->ctrl_handler)
19395bc3cb74SMauro Carvalho Chehab 		return v4l2_queryctrl(vfd->ctrl_handler, p);
19405bc3cb74SMauro Carvalho Chehab 	if (ops->vidioc_queryctrl)
19415bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_queryctrl(file, fh, p);
19425bc3cb74SMauro Carvalho Chehab 	return -ENOTTY;
19435bc3cb74SMauro Carvalho Chehab }
19445bc3cb74SMauro Carvalho Chehab 
1945e6bee368SHans Verkuil static int v4l_query_ext_ctrl(const struct v4l2_ioctl_ops *ops,
1946e6bee368SHans Verkuil 				struct file *file, void *fh, void *arg)
1947e6bee368SHans Verkuil {
1948e6bee368SHans Verkuil 	struct video_device *vfd = video_devdata(file);
1949e6bee368SHans Verkuil 	struct v4l2_query_ext_ctrl *p = arg;
1950e6bee368SHans Verkuil 	struct v4l2_fh *vfh =
1951e6bee368SHans Verkuil 		test_bit(V4L2_FL_USES_V4L2_FH, &vfd->flags) ? fh : NULL;
1952e6bee368SHans Verkuil 
1953e6bee368SHans Verkuil 	if (vfh && vfh->ctrl_handler)
1954e6bee368SHans Verkuil 		return v4l2_query_ext_ctrl(vfh->ctrl_handler, p);
1955e6bee368SHans Verkuil 	if (vfd->ctrl_handler)
1956e6bee368SHans Verkuil 		return v4l2_query_ext_ctrl(vfd->ctrl_handler, p);
1957e6bee368SHans Verkuil 	if (ops->vidioc_query_ext_ctrl)
1958e6bee368SHans Verkuil 		return ops->vidioc_query_ext_ctrl(file, fh, p);
1959e6bee368SHans Verkuil 	return -ENOTTY;
1960e6bee368SHans Verkuil }
1961e6bee368SHans Verkuil 
19625bc3cb74SMauro Carvalho Chehab static int v4l_querymenu(const struct v4l2_ioctl_ops *ops,
19635bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
19645bc3cb74SMauro Carvalho Chehab {
19655bc3cb74SMauro Carvalho Chehab 	struct video_device *vfd = video_devdata(file);
19665bc3cb74SMauro Carvalho Chehab 	struct v4l2_querymenu *p = arg;
19675bc3cb74SMauro Carvalho Chehab 	struct v4l2_fh *vfh =
19685bc3cb74SMauro Carvalho Chehab 		test_bit(V4L2_FL_USES_V4L2_FH, &vfd->flags) ? fh : NULL;
19695bc3cb74SMauro Carvalho Chehab 
19705bc3cb74SMauro Carvalho Chehab 	if (vfh && vfh->ctrl_handler)
19715bc3cb74SMauro Carvalho Chehab 		return v4l2_querymenu(vfh->ctrl_handler, p);
19725bc3cb74SMauro Carvalho Chehab 	if (vfd->ctrl_handler)
19735bc3cb74SMauro Carvalho Chehab 		return v4l2_querymenu(vfd->ctrl_handler, p);
19745bc3cb74SMauro Carvalho Chehab 	if (ops->vidioc_querymenu)
19755bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_querymenu(file, fh, p);
19765bc3cb74SMauro Carvalho Chehab 	return -ENOTTY;
19775bc3cb74SMauro Carvalho Chehab }
19785bc3cb74SMauro Carvalho Chehab 
19795bc3cb74SMauro Carvalho Chehab static int v4l_g_ctrl(const struct v4l2_ioctl_ops *ops,
19805bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
19815bc3cb74SMauro Carvalho Chehab {
19825bc3cb74SMauro Carvalho Chehab 	struct video_device *vfd = video_devdata(file);
19835bc3cb74SMauro Carvalho Chehab 	struct v4l2_control *p = arg;
19845bc3cb74SMauro Carvalho Chehab 	struct v4l2_fh *vfh =
19855bc3cb74SMauro Carvalho Chehab 		test_bit(V4L2_FL_USES_V4L2_FH, &vfd->flags) ? fh : NULL;
19865bc3cb74SMauro Carvalho Chehab 	struct v4l2_ext_controls ctrls;
19875bc3cb74SMauro Carvalho Chehab 	struct v4l2_ext_control ctrl;
19885bc3cb74SMauro Carvalho Chehab 
19895bc3cb74SMauro Carvalho Chehab 	if (vfh && vfh->ctrl_handler)
19905bc3cb74SMauro Carvalho Chehab 		return v4l2_g_ctrl(vfh->ctrl_handler, p);
19915bc3cb74SMauro Carvalho Chehab 	if (vfd->ctrl_handler)
19925bc3cb74SMauro Carvalho Chehab 		return v4l2_g_ctrl(vfd->ctrl_handler, p);
19935bc3cb74SMauro Carvalho Chehab 	if (ops->vidioc_g_ctrl)
19945bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_g_ctrl(file, fh, p);
19955bc3cb74SMauro Carvalho Chehab 	if (ops->vidioc_g_ext_ctrls == NULL)
19965bc3cb74SMauro Carvalho Chehab 		return -ENOTTY;
19975bc3cb74SMauro Carvalho Chehab 
19980f8017beSRicardo Ribalda 	ctrls.which = V4L2_CTRL_ID2WHICH(p->id);
19995bc3cb74SMauro Carvalho Chehab 	ctrls.count = 1;
20005bc3cb74SMauro Carvalho Chehab 	ctrls.controls = &ctrl;
20015bc3cb74SMauro Carvalho Chehab 	ctrl.id = p->id;
20025bc3cb74SMauro Carvalho Chehab 	ctrl.value = p->value;
20035bc3cb74SMauro Carvalho Chehab 	if (check_ext_ctrls(&ctrls, 1)) {
20045bc3cb74SMauro Carvalho Chehab 		int ret = ops->vidioc_g_ext_ctrls(file, fh, &ctrls);
20055bc3cb74SMauro Carvalho Chehab 
20065bc3cb74SMauro Carvalho Chehab 		if (ret == 0)
20075bc3cb74SMauro Carvalho Chehab 			p->value = ctrl.value;
20085bc3cb74SMauro Carvalho Chehab 		return ret;
20095bc3cb74SMauro Carvalho Chehab 	}
20105bc3cb74SMauro Carvalho Chehab 	return -EINVAL;
20115bc3cb74SMauro Carvalho Chehab }
20125bc3cb74SMauro Carvalho Chehab 
20135bc3cb74SMauro Carvalho Chehab static int v4l_s_ctrl(const struct v4l2_ioctl_ops *ops,
20145bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
20155bc3cb74SMauro Carvalho Chehab {
20165bc3cb74SMauro Carvalho Chehab 	struct video_device *vfd = video_devdata(file);
20175bc3cb74SMauro Carvalho Chehab 	struct v4l2_control *p = arg;
20185bc3cb74SMauro Carvalho Chehab 	struct v4l2_fh *vfh =
20195bc3cb74SMauro Carvalho Chehab 		test_bit(V4L2_FL_USES_V4L2_FH, &vfd->flags) ? fh : NULL;
20205bc3cb74SMauro Carvalho Chehab 	struct v4l2_ext_controls ctrls;
20215bc3cb74SMauro Carvalho Chehab 	struct v4l2_ext_control ctrl;
20225bc3cb74SMauro Carvalho Chehab 
20235bc3cb74SMauro Carvalho Chehab 	if (vfh && vfh->ctrl_handler)
20245bc3cb74SMauro Carvalho Chehab 		return v4l2_s_ctrl(vfh, vfh->ctrl_handler, p);
20255bc3cb74SMauro Carvalho Chehab 	if (vfd->ctrl_handler)
20265bc3cb74SMauro Carvalho Chehab 		return v4l2_s_ctrl(NULL, vfd->ctrl_handler, p);
20275bc3cb74SMauro Carvalho Chehab 	if (ops->vidioc_s_ctrl)
20285bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_s_ctrl(file, fh, p);
20295bc3cb74SMauro Carvalho Chehab 	if (ops->vidioc_s_ext_ctrls == NULL)
20305bc3cb74SMauro Carvalho Chehab 		return -ENOTTY;
20315bc3cb74SMauro Carvalho Chehab 
20320f8017beSRicardo Ribalda 	ctrls.which = V4L2_CTRL_ID2WHICH(p->id);
20335bc3cb74SMauro Carvalho Chehab 	ctrls.count = 1;
20345bc3cb74SMauro Carvalho Chehab 	ctrls.controls = &ctrl;
20355bc3cb74SMauro Carvalho Chehab 	ctrl.id = p->id;
20365bc3cb74SMauro Carvalho Chehab 	ctrl.value = p->value;
20375bc3cb74SMauro Carvalho Chehab 	if (check_ext_ctrls(&ctrls, 1))
20385bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_s_ext_ctrls(file, fh, &ctrls);
20395bc3cb74SMauro Carvalho Chehab 	return -EINVAL;
20405bc3cb74SMauro Carvalho Chehab }
20415bc3cb74SMauro Carvalho Chehab 
20425bc3cb74SMauro Carvalho Chehab static int v4l_g_ext_ctrls(const struct v4l2_ioctl_ops *ops,
20435bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
20445bc3cb74SMauro Carvalho Chehab {
20455bc3cb74SMauro Carvalho Chehab 	struct video_device *vfd = video_devdata(file);
20465bc3cb74SMauro Carvalho Chehab 	struct v4l2_ext_controls *p = arg;
20475bc3cb74SMauro Carvalho Chehab 	struct v4l2_fh *vfh =
20485bc3cb74SMauro Carvalho Chehab 		test_bit(V4L2_FL_USES_V4L2_FH, &vfd->flags) ? fh : NULL;
20495bc3cb74SMauro Carvalho Chehab 
20505bc3cb74SMauro Carvalho Chehab 	p->error_idx = p->count;
20515bc3cb74SMauro Carvalho Chehab 	if (vfh && vfh->ctrl_handler)
20525bc3cb74SMauro Carvalho Chehab 		return v4l2_g_ext_ctrls(vfh->ctrl_handler, p);
20535bc3cb74SMauro Carvalho Chehab 	if (vfd->ctrl_handler)
20545bc3cb74SMauro Carvalho Chehab 		return v4l2_g_ext_ctrls(vfd->ctrl_handler, p);
20555bc3cb74SMauro Carvalho Chehab 	if (ops->vidioc_g_ext_ctrls == NULL)
20565bc3cb74SMauro Carvalho Chehab 		return -ENOTTY;
20575bc3cb74SMauro Carvalho Chehab 	return check_ext_ctrls(p, 0) ? ops->vidioc_g_ext_ctrls(file, fh, p) :
20585bc3cb74SMauro Carvalho Chehab 					-EINVAL;
20595bc3cb74SMauro Carvalho Chehab }
20605bc3cb74SMauro Carvalho Chehab 
20615bc3cb74SMauro Carvalho Chehab static int v4l_s_ext_ctrls(const struct v4l2_ioctl_ops *ops,
20625bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
20635bc3cb74SMauro Carvalho Chehab {
20645bc3cb74SMauro Carvalho Chehab 	struct video_device *vfd = video_devdata(file);
20655bc3cb74SMauro Carvalho Chehab 	struct v4l2_ext_controls *p = arg;
20665bc3cb74SMauro Carvalho Chehab 	struct v4l2_fh *vfh =
20675bc3cb74SMauro Carvalho Chehab 		test_bit(V4L2_FL_USES_V4L2_FH, &vfd->flags) ? fh : NULL;
20685bc3cb74SMauro Carvalho Chehab 
20695bc3cb74SMauro Carvalho Chehab 	p->error_idx = p->count;
20705bc3cb74SMauro Carvalho Chehab 	if (vfh && vfh->ctrl_handler)
20715bc3cb74SMauro Carvalho Chehab 		return v4l2_s_ext_ctrls(vfh, vfh->ctrl_handler, p);
20725bc3cb74SMauro Carvalho Chehab 	if (vfd->ctrl_handler)
20735bc3cb74SMauro Carvalho Chehab 		return v4l2_s_ext_ctrls(NULL, vfd->ctrl_handler, p);
20745bc3cb74SMauro Carvalho Chehab 	if (ops->vidioc_s_ext_ctrls == NULL)
20755bc3cb74SMauro Carvalho Chehab 		return -ENOTTY;
20765bc3cb74SMauro Carvalho Chehab 	return check_ext_ctrls(p, 0) ? ops->vidioc_s_ext_ctrls(file, fh, p) :
20775bc3cb74SMauro Carvalho Chehab 					-EINVAL;
20785bc3cb74SMauro Carvalho Chehab }
20795bc3cb74SMauro Carvalho Chehab 
20805bc3cb74SMauro Carvalho Chehab static int v4l_try_ext_ctrls(const struct v4l2_ioctl_ops *ops,
20815bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
20825bc3cb74SMauro Carvalho Chehab {
20835bc3cb74SMauro Carvalho Chehab 	struct video_device *vfd = video_devdata(file);
20845bc3cb74SMauro Carvalho Chehab 	struct v4l2_ext_controls *p = arg;
20855bc3cb74SMauro Carvalho Chehab 	struct v4l2_fh *vfh =
20865bc3cb74SMauro Carvalho Chehab 		test_bit(V4L2_FL_USES_V4L2_FH, &vfd->flags) ? fh : NULL;
20875bc3cb74SMauro Carvalho Chehab 
20885bc3cb74SMauro Carvalho Chehab 	p->error_idx = p->count;
20895bc3cb74SMauro Carvalho Chehab 	if (vfh && vfh->ctrl_handler)
20905bc3cb74SMauro Carvalho Chehab 		return v4l2_try_ext_ctrls(vfh->ctrl_handler, p);
20915bc3cb74SMauro Carvalho Chehab 	if (vfd->ctrl_handler)
20925bc3cb74SMauro Carvalho Chehab 		return v4l2_try_ext_ctrls(vfd->ctrl_handler, p);
20935bc3cb74SMauro Carvalho Chehab 	if (ops->vidioc_try_ext_ctrls == NULL)
20945bc3cb74SMauro Carvalho Chehab 		return -ENOTTY;
20955bc3cb74SMauro Carvalho Chehab 	return check_ext_ctrls(p, 0) ? ops->vidioc_try_ext_ctrls(file, fh, p) :
20965bc3cb74SMauro Carvalho Chehab 					-EINVAL;
20975bc3cb74SMauro Carvalho Chehab }
20985bc3cb74SMauro Carvalho Chehab 
20995bc3cb74SMauro Carvalho Chehab static int v4l_g_crop(const struct v4l2_ioctl_ops *ops,
21005bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
21015bc3cb74SMauro Carvalho Chehab {
21025bc3cb74SMauro Carvalho Chehab 	struct v4l2_crop *p = arg;
21035bc3cb74SMauro Carvalho Chehab 	struct v4l2_selection s = {
21045bc3cb74SMauro Carvalho Chehab 		.type = p->type,
21055bc3cb74SMauro Carvalho Chehab 	};
21065bc3cb74SMauro Carvalho Chehab 	int ret;
21075bc3cb74SMauro Carvalho Chehab 
21085bc3cb74SMauro Carvalho Chehab 	if (ops->vidioc_g_crop)
21095bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_g_crop(file, fh, p);
21105bc3cb74SMauro Carvalho Chehab 	/* simulate capture crop using selection api */
21115bc3cb74SMauro Carvalho Chehab 
21125bc3cb74SMauro Carvalho Chehab 	/* crop means compose for output devices */
21135bc3cb74SMauro Carvalho Chehab 	if (V4L2_TYPE_IS_OUTPUT(p->type))
21145bc3cb74SMauro Carvalho Chehab 		s.target = V4L2_SEL_TGT_COMPOSE_ACTIVE;
21155bc3cb74SMauro Carvalho Chehab 	else
21165bc3cb74SMauro Carvalho Chehab 		s.target = V4L2_SEL_TGT_CROP_ACTIVE;
21175bc3cb74SMauro Carvalho Chehab 
21185bc3cb74SMauro Carvalho Chehab 	ret = ops->vidioc_g_selection(file, fh, &s);
21195bc3cb74SMauro Carvalho Chehab 
21205bc3cb74SMauro Carvalho Chehab 	/* copying results to old structure on success */
21215bc3cb74SMauro Carvalho Chehab 	if (!ret)
21225bc3cb74SMauro Carvalho Chehab 		p->c = s.r;
21235bc3cb74SMauro Carvalho Chehab 	return ret;
21245bc3cb74SMauro Carvalho Chehab }
21255bc3cb74SMauro Carvalho Chehab 
21265bc3cb74SMauro Carvalho Chehab static int v4l_s_crop(const struct v4l2_ioctl_ops *ops,
21275bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
21285bc3cb74SMauro Carvalho Chehab {
21295bc3cb74SMauro Carvalho Chehab 	struct v4l2_crop *p = arg;
21305bc3cb74SMauro Carvalho Chehab 	struct v4l2_selection s = {
21315bc3cb74SMauro Carvalho Chehab 		.type = p->type,
21325bc3cb74SMauro Carvalho Chehab 		.r = p->c,
21335bc3cb74SMauro Carvalho Chehab 	};
21345bc3cb74SMauro Carvalho Chehab 
21355bc3cb74SMauro Carvalho Chehab 	if (ops->vidioc_s_crop)
21365bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_s_crop(file, fh, p);
21375bc3cb74SMauro Carvalho Chehab 	/* simulate capture crop using selection api */
21385bc3cb74SMauro Carvalho Chehab 
21395bc3cb74SMauro Carvalho Chehab 	/* crop means compose for output devices */
21405bc3cb74SMauro Carvalho Chehab 	if (V4L2_TYPE_IS_OUTPUT(p->type))
21415bc3cb74SMauro Carvalho Chehab 		s.target = V4L2_SEL_TGT_COMPOSE_ACTIVE;
21425bc3cb74SMauro Carvalho Chehab 	else
21435bc3cb74SMauro Carvalho Chehab 		s.target = V4L2_SEL_TGT_CROP_ACTIVE;
21445bc3cb74SMauro Carvalho Chehab 
21455bc3cb74SMauro Carvalho Chehab 	return ops->vidioc_s_selection(file, fh, &s);
21465bc3cb74SMauro Carvalho Chehab }
21475bc3cb74SMauro Carvalho Chehab 
21485bc3cb74SMauro Carvalho Chehab static int v4l_cropcap(const struct v4l2_ioctl_ops *ops,
21495bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
21505bc3cb74SMauro Carvalho Chehab {
21515bc3cb74SMauro Carvalho Chehab 	struct v4l2_cropcap *p = arg;
21525bc3cb74SMauro Carvalho Chehab 	struct v4l2_selection s = { .type = p->type };
215395dd7b7eSHans Verkuil 	int ret = 0;
215495dd7b7eSHans Verkuil 
215595dd7b7eSHans Verkuil 	/* setting trivial pixelaspect */
215695dd7b7eSHans Verkuil 	p->pixelaspect.numerator = 1;
215795dd7b7eSHans Verkuil 	p->pixelaspect.denominator = 1;
215895dd7b7eSHans Verkuil 
215995dd7b7eSHans Verkuil 	/*
216095dd7b7eSHans Verkuil 	 * The determine_valid_ioctls() call already should ensure
216195dd7b7eSHans Verkuil 	 * that this can never happen, but just in case...
216295dd7b7eSHans Verkuil 	 */
21631ca830b1SHans Verkuil 	if (WARN_ON(!ops->vidioc_cropcap && !ops->vidioc_g_selection))
216495dd7b7eSHans Verkuil 		return -ENOTTY;
216595dd7b7eSHans Verkuil 
216695dd7b7eSHans Verkuil 	if (ops->vidioc_cropcap)
216795dd7b7eSHans Verkuil 		ret = ops->vidioc_cropcap(file, fh, p);
216895dd7b7eSHans Verkuil 
216995dd7b7eSHans Verkuil 	if (!ops->vidioc_g_selection)
217095dd7b7eSHans Verkuil 		return ret;
217195dd7b7eSHans Verkuil 
217295dd7b7eSHans Verkuil 	/*
217395dd7b7eSHans Verkuil 	 * Ignore ENOTTY or ENOIOCTLCMD error returns, just use the
217495dd7b7eSHans Verkuil 	 * square pixel aspect ratio in that case.
217595dd7b7eSHans Verkuil 	 */
217695dd7b7eSHans Verkuil 	if (ret && ret != -ENOTTY && ret != -ENOIOCTLCMD)
217795dd7b7eSHans Verkuil 		return ret;
217895dd7b7eSHans Verkuil 
217995dd7b7eSHans Verkuil 	/* Use g_selection() to fill in the bounds and defrect rectangles */
21805bc3cb74SMauro Carvalho Chehab 
21815bc3cb74SMauro Carvalho Chehab 	/* obtaining bounds */
21825bc3cb74SMauro Carvalho Chehab 	if (V4L2_TYPE_IS_OUTPUT(p->type))
21835bc3cb74SMauro Carvalho Chehab 		s.target = V4L2_SEL_TGT_COMPOSE_BOUNDS;
21845bc3cb74SMauro Carvalho Chehab 	else
21855bc3cb74SMauro Carvalho Chehab 		s.target = V4L2_SEL_TGT_CROP_BOUNDS;
21865bc3cb74SMauro Carvalho Chehab 
21875bc3cb74SMauro Carvalho Chehab 	ret = ops->vidioc_g_selection(file, fh, &s);
21885bc3cb74SMauro Carvalho Chehab 	if (ret)
21895bc3cb74SMauro Carvalho Chehab 		return ret;
21905bc3cb74SMauro Carvalho Chehab 	p->bounds = s.r;
21915bc3cb74SMauro Carvalho Chehab 
21925bc3cb74SMauro Carvalho Chehab 	/* obtaining defrect */
21935bc3cb74SMauro Carvalho Chehab 	if (V4L2_TYPE_IS_OUTPUT(p->type))
21945bc3cb74SMauro Carvalho Chehab 		s.target = V4L2_SEL_TGT_COMPOSE_DEFAULT;
21955bc3cb74SMauro Carvalho Chehab 	else
21965bc3cb74SMauro Carvalho Chehab 		s.target = V4L2_SEL_TGT_CROP_DEFAULT;
21975bc3cb74SMauro Carvalho Chehab 
21985bc3cb74SMauro Carvalho Chehab 	ret = ops->vidioc_g_selection(file, fh, &s);
21995bc3cb74SMauro Carvalho Chehab 	if (ret)
22005bc3cb74SMauro Carvalho Chehab 		return ret;
22015bc3cb74SMauro Carvalho Chehab 	p->defrect = s.r;
22029409945cSHans Verkuil 
22035bc3cb74SMauro Carvalho Chehab 	return 0;
22045bc3cb74SMauro Carvalho Chehab }
22055bc3cb74SMauro Carvalho Chehab 
22065bc3cb74SMauro Carvalho Chehab static int v4l_log_status(const struct v4l2_ioctl_ops *ops,
22075bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
22085bc3cb74SMauro Carvalho Chehab {
22095bc3cb74SMauro Carvalho Chehab 	struct video_device *vfd = video_devdata(file);
22105bc3cb74SMauro Carvalho Chehab 	int ret;
22115bc3cb74SMauro Carvalho Chehab 
22125bc3cb74SMauro Carvalho Chehab 	if (vfd->v4l2_dev)
22135bc3cb74SMauro Carvalho Chehab 		pr_info("%s: =================  START STATUS  =================\n",
22145bc3cb74SMauro Carvalho Chehab 			vfd->v4l2_dev->name);
22155bc3cb74SMauro Carvalho Chehab 	ret = ops->vidioc_log_status(file, fh);
22165bc3cb74SMauro Carvalho Chehab 	if (vfd->v4l2_dev)
22175bc3cb74SMauro Carvalho Chehab 		pr_info("%s: ==================  END STATUS  ==================\n",
22185bc3cb74SMauro Carvalho Chehab 			vfd->v4l2_dev->name);
22195bc3cb74SMauro Carvalho Chehab 	return ret;
22205bc3cb74SMauro Carvalho Chehab }
22215bc3cb74SMauro Carvalho Chehab 
22225bc3cb74SMauro Carvalho Chehab static int v4l_dbg_g_register(const struct v4l2_ioctl_ops *ops,
22235bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
22245bc3cb74SMauro Carvalho Chehab {
22255bc3cb74SMauro Carvalho Chehab #ifdef CONFIG_VIDEO_ADV_DEBUG
22265bc3cb74SMauro Carvalho Chehab 	struct v4l2_dbg_register *p = arg;
222779b0c640SHans Verkuil 	struct video_device *vfd = video_devdata(file);
222879b0c640SHans Verkuil 	struct v4l2_subdev *sd;
222979b0c640SHans Verkuil 	int idx = 0;
22305bc3cb74SMauro Carvalho Chehab 
22315bc3cb74SMauro Carvalho Chehab 	if (!capable(CAP_SYS_ADMIN))
22325bc3cb74SMauro Carvalho Chehab 		return -EPERM;
22333eef2510SHans Verkuil 	if (p->match.type == V4L2_CHIP_MATCH_SUBDEV) {
223479b0c640SHans Verkuil 		if (vfd->v4l2_dev == NULL)
223579b0c640SHans Verkuil 			return -EINVAL;
22363eef2510SHans Verkuil 		v4l2_device_for_each_subdev(sd, vfd->v4l2_dev)
22373eef2510SHans Verkuil 			if (p->match.addr == idx++)
223879b0c640SHans Verkuil 				return v4l2_subdev_call(sd, core, g_register, p);
223979b0c640SHans Verkuil 		return -EINVAL;
224079b0c640SHans Verkuil 	}
2241191b79b0SHans Verkuil 	if (ops->vidioc_g_register && p->match.type == V4L2_CHIP_MATCH_BRIDGE &&
2242191b79b0SHans Verkuil 	    (ops->vidioc_g_chip_info || p->match.addr == 0))
22435bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_g_register(file, fh, p);
224479b0c640SHans Verkuil 	return -EINVAL;
22455bc3cb74SMauro Carvalho Chehab #else
22465bc3cb74SMauro Carvalho Chehab 	return -ENOTTY;
22475bc3cb74SMauro Carvalho Chehab #endif
22485bc3cb74SMauro Carvalho Chehab }
22495bc3cb74SMauro Carvalho Chehab 
22505bc3cb74SMauro Carvalho Chehab static int v4l_dbg_s_register(const struct v4l2_ioctl_ops *ops,
22515bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
22525bc3cb74SMauro Carvalho Chehab {
22535bc3cb74SMauro Carvalho Chehab #ifdef CONFIG_VIDEO_ADV_DEBUG
2254977ba3b1SHans Verkuil 	const struct v4l2_dbg_register *p = arg;
225579b0c640SHans Verkuil 	struct video_device *vfd = video_devdata(file);
225679b0c640SHans Verkuil 	struct v4l2_subdev *sd;
225779b0c640SHans Verkuil 	int idx = 0;
22585bc3cb74SMauro Carvalho Chehab 
22595bc3cb74SMauro Carvalho Chehab 	if (!capable(CAP_SYS_ADMIN))
22605bc3cb74SMauro Carvalho Chehab 		return -EPERM;
22613eef2510SHans Verkuil 	if (p->match.type == V4L2_CHIP_MATCH_SUBDEV) {
226279b0c640SHans Verkuil 		if (vfd->v4l2_dev == NULL)
226379b0c640SHans Verkuil 			return -EINVAL;
22643eef2510SHans Verkuil 		v4l2_device_for_each_subdev(sd, vfd->v4l2_dev)
22653eef2510SHans Verkuil 			if (p->match.addr == idx++)
226679b0c640SHans Verkuil 				return v4l2_subdev_call(sd, core, s_register, p);
226779b0c640SHans Verkuil 		return -EINVAL;
226879b0c640SHans Verkuil 	}
2269191b79b0SHans Verkuil 	if (ops->vidioc_s_register && p->match.type == V4L2_CHIP_MATCH_BRIDGE &&
2270191b79b0SHans Verkuil 	    (ops->vidioc_g_chip_info || p->match.addr == 0))
22715bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_s_register(file, fh, p);
227279b0c640SHans Verkuil 	return -EINVAL;
22735bc3cb74SMauro Carvalho Chehab #else
22745bc3cb74SMauro Carvalho Chehab 	return -ENOTTY;
22755bc3cb74SMauro Carvalho Chehab #endif
22765bc3cb74SMauro Carvalho Chehab }
22775bc3cb74SMauro Carvalho Chehab 
227896b03d2aSHans Verkuil static int v4l_dbg_g_chip_info(const struct v4l2_ioctl_ops *ops,
227979b0c640SHans Verkuil 				struct file *file, void *fh, void *arg)
228079b0c640SHans Verkuil {
2281cd634f1bSHans Verkuil #ifdef CONFIG_VIDEO_ADV_DEBUG
228279b0c640SHans Verkuil 	struct video_device *vfd = video_devdata(file);
228396b03d2aSHans Verkuil 	struct v4l2_dbg_chip_info *p = arg;
228479b0c640SHans Verkuil 	struct v4l2_subdev *sd;
228579b0c640SHans Verkuil 	int idx = 0;
228679b0c640SHans Verkuil 
228779b0c640SHans Verkuil 	switch (p->match.type) {
228879b0c640SHans Verkuil 	case V4L2_CHIP_MATCH_BRIDGE:
228979b0c640SHans Verkuil 		if (ops->vidioc_s_register)
229079b0c640SHans Verkuil 			p->flags |= V4L2_CHIP_FL_WRITABLE;
229179b0c640SHans Verkuil 		if (ops->vidioc_g_register)
229279b0c640SHans Verkuil 			p->flags |= V4L2_CHIP_FL_READABLE;
229379b0c640SHans Verkuil 		strlcpy(p->name, vfd->v4l2_dev->name, sizeof(p->name));
229496b03d2aSHans Verkuil 		if (ops->vidioc_g_chip_info)
229596b03d2aSHans Verkuil 			return ops->vidioc_g_chip_info(file, fh, arg);
22960f0fe4b9SHans Verkuil 		if (p->match.addr)
22970f0fe4b9SHans Verkuil 			return -EINVAL;
229879b0c640SHans Verkuil 		return 0;
229979b0c640SHans Verkuil 
23003eef2510SHans Verkuil 	case V4L2_CHIP_MATCH_SUBDEV:
230179b0c640SHans Verkuil 		if (vfd->v4l2_dev == NULL)
230279b0c640SHans Verkuil 			break;
230379b0c640SHans Verkuil 		v4l2_device_for_each_subdev(sd, vfd->v4l2_dev) {
23043eef2510SHans Verkuil 			if (p->match.addr != idx++)
23053eef2510SHans Verkuil 				continue;
230679b0c640SHans Verkuil 			if (sd->ops->core && sd->ops->core->s_register)
230779b0c640SHans Verkuil 				p->flags |= V4L2_CHIP_FL_WRITABLE;
230879b0c640SHans Verkuil 			if (sd->ops->core && sd->ops->core->g_register)
230979b0c640SHans Verkuil 				p->flags |= V4L2_CHIP_FL_READABLE;
231079b0c640SHans Verkuil 			strlcpy(p->name, sd->name, sizeof(p->name));
231179b0c640SHans Verkuil 			return 0;
231279b0c640SHans Verkuil 		}
231379b0c640SHans Verkuil 		break;
231479b0c640SHans Verkuil 	}
231579b0c640SHans Verkuil 	return -EINVAL;
2316cd634f1bSHans Verkuil #else
2317cd634f1bSHans Verkuil 	return -ENOTTY;
2318cd634f1bSHans Verkuil #endif
231979b0c640SHans Verkuil }
232079b0c640SHans Verkuil 
23215bc3cb74SMauro Carvalho Chehab static int v4l_dqevent(const struct v4l2_ioctl_ops *ops,
23225bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
23235bc3cb74SMauro Carvalho Chehab {
23245bc3cb74SMauro Carvalho Chehab 	return v4l2_event_dequeue(fh, arg, file->f_flags & O_NONBLOCK);
23255bc3cb74SMauro Carvalho Chehab }
23265bc3cb74SMauro Carvalho Chehab 
23275bc3cb74SMauro Carvalho Chehab static int v4l_subscribe_event(const struct v4l2_ioctl_ops *ops,
23285bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
23295bc3cb74SMauro Carvalho Chehab {
23305bc3cb74SMauro Carvalho Chehab 	return ops->vidioc_subscribe_event(fh, arg);
23315bc3cb74SMauro Carvalho Chehab }
23325bc3cb74SMauro Carvalho Chehab 
23335bc3cb74SMauro Carvalho Chehab static int v4l_unsubscribe_event(const struct v4l2_ioctl_ops *ops,
23345bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
23355bc3cb74SMauro Carvalho Chehab {
23365bc3cb74SMauro Carvalho Chehab 	return ops->vidioc_unsubscribe_event(fh, arg);
23375bc3cb74SMauro Carvalho Chehab }
23385bc3cb74SMauro Carvalho Chehab 
23395bc3cb74SMauro Carvalho Chehab static int v4l_g_sliced_vbi_cap(const struct v4l2_ioctl_ops *ops,
23405bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
23415bc3cb74SMauro Carvalho Chehab {
23425bc3cb74SMauro Carvalho Chehab 	struct v4l2_sliced_vbi_cap *p = arg;
23434b20259fSHans Verkuil 	int ret = check_fmt(file, p->type);
23444b20259fSHans Verkuil 
23454b20259fSHans Verkuil 	if (ret)
23464b20259fSHans Verkuil 		return ret;
23475bc3cb74SMauro Carvalho Chehab 
23485bc3cb74SMauro Carvalho Chehab 	/* Clear up to type, everything after type is zeroed already */
23495bc3cb74SMauro Carvalho Chehab 	memset(p, 0, offsetof(struct v4l2_sliced_vbi_cap, type));
23505bc3cb74SMauro Carvalho Chehab 
23515bc3cb74SMauro Carvalho Chehab 	return ops->vidioc_g_sliced_vbi_cap(file, fh, p);
23525bc3cb74SMauro Carvalho Chehab }
23535bc3cb74SMauro Carvalho Chehab 
23545bc3cb74SMauro Carvalho Chehab static int v4l_enum_freq_bands(const struct v4l2_ioctl_ops *ops,
23555bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
23565bc3cb74SMauro Carvalho Chehab {
23575bc3cb74SMauro Carvalho Chehab 	struct video_device *vfd = video_devdata(file);
23585bc3cb74SMauro Carvalho Chehab 	struct v4l2_frequency_band *p = arg;
23595bc3cb74SMauro Carvalho Chehab 	enum v4l2_tuner_type type;
23605bc3cb74SMauro Carvalho Chehab 	int err;
23615bc3cb74SMauro Carvalho Chehab 
236284099a28SAntti Palosaari 	if (vfd->vfl_type == VFL_TYPE_SDR) {
2363f3c3ececSAntti Palosaari 		if (p->type != V4L2_TUNER_SDR && p->type != V4L2_TUNER_RF)
236484099a28SAntti Palosaari 			return -EINVAL;
236584099a28SAntti Palosaari 		type = p->type;
236684099a28SAntti Palosaari 	} else {
23675bc3cb74SMauro Carvalho Chehab 		type = (vfd->vfl_type == VFL_TYPE_RADIO) ?
23685bc3cb74SMauro Carvalho Chehab 				V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV;
23695bc3cb74SMauro Carvalho Chehab 		if (type != p->type)
23705bc3cb74SMauro Carvalho Chehab 			return -EINVAL;
237184099a28SAntti Palosaari 	}
2372a7f404afSHans Verkuil 	if (ops->vidioc_enum_freq_bands) {
2373a7f404afSHans Verkuil 		err = ops->vidioc_enum_freq_bands(file, fh, p);
2374a7f404afSHans Verkuil 		if (err != -ENOTTY)
2375a7f404afSHans Verkuil 			return err;
2376a7f404afSHans Verkuil 	}
237773f35418SHans Verkuil 	if (is_valid_ioctl(vfd, VIDIOC_G_TUNER)) {
23785bc3cb74SMauro Carvalho Chehab 		struct v4l2_tuner t = {
23795bc3cb74SMauro Carvalho Chehab 			.index = p->tuner,
23805bc3cb74SMauro Carvalho Chehab 			.type = type,
23815bc3cb74SMauro Carvalho Chehab 		};
23825bc3cb74SMauro Carvalho Chehab 
238379e8c7beSMauro Carvalho Chehab 		if (p->index)
238479e8c7beSMauro Carvalho Chehab 			return -EINVAL;
23855bc3cb74SMauro Carvalho Chehab 		err = ops->vidioc_g_tuner(file, fh, &t);
23865bc3cb74SMauro Carvalho Chehab 		if (err)
23875bc3cb74SMauro Carvalho Chehab 			return err;
23885bc3cb74SMauro Carvalho Chehab 		p->capability = t.capability | V4L2_TUNER_CAP_FREQ_BANDS;
23895bc3cb74SMauro Carvalho Chehab 		p->rangelow = t.rangelow;
23905bc3cb74SMauro Carvalho Chehab 		p->rangehigh = t.rangehigh;
23915bc3cb74SMauro Carvalho Chehab 		p->modulation = (type == V4L2_TUNER_RADIO) ?
23925bc3cb74SMauro Carvalho Chehab 			V4L2_BAND_MODULATION_FM : V4L2_BAND_MODULATION_VSB;
23935bc3cb74SMauro Carvalho Chehab 		return 0;
23945bc3cb74SMauro Carvalho Chehab 	}
239573f35418SHans Verkuil 	if (is_valid_ioctl(vfd, VIDIOC_G_MODULATOR)) {
23965bc3cb74SMauro Carvalho Chehab 		struct v4l2_modulator m = {
23975bc3cb74SMauro Carvalho Chehab 			.index = p->tuner,
23985bc3cb74SMauro Carvalho Chehab 		};
23995bc3cb74SMauro Carvalho Chehab 
24005bc3cb74SMauro Carvalho Chehab 		if (type != V4L2_TUNER_RADIO)
24015bc3cb74SMauro Carvalho Chehab 			return -EINVAL;
240279e8c7beSMauro Carvalho Chehab 		if (p->index)
240379e8c7beSMauro Carvalho Chehab 			return -EINVAL;
24045bc3cb74SMauro Carvalho Chehab 		err = ops->vidioc_g_modulator(file, fh, &m);
24055bc3cb74SMauro Carvalho Chehab 		if (err)
24065bc3cb74SMauro Carvalho Chehab 			return err;
24075bc3cb74SMauro Carvalho Chehab 		p->capability = m.capability | V4L2_TUNER_CAP_FREQ_BANDS;
24085bc3cb74SMauro Carvalho Chehab 		p->rangelow = m.rangelow;
24095bc3cb74SMauro Carvalho Chehab 		p->rangehigh = m.rangehigh;
24105bc3cb74SMauro Carvalho Chehab 		p->modulation = (type == V4L2_TUNER_RADIO) ?
24115bc3cb74SMauro Carvalho Chehab 			V4L2_BAND_MODULATION_FM : V4L2_BAND_MODULATION_VSB;
24125bc3cb74SMauro Carvalho Chehab 		return 0;
24135bc3cb74SMauro Carvalho Chehab 	}
24145bc3cb74SMauro Carvalho Chehab 	return -ENOTTY;
24155bc3cb74SMauro Carvalho Chehab }
24165bc3cb74SMauro Carvalho Chehab 
24175bc3cb74SMauro Carvalho Chehab struct v4l2_ioctl_info {
24185bc3cb74SMauro Carvalho Chehab 	unsigned int ioctl;
24195bc3cb74SMauro Carvalho Chehab 	u32 flags;
24205bc3cb74SMauro Carvalho Chehab 	const char * const name;
24215bc3cb74SMauro Carvalho Chehab 	union {
24225bc3cb74SMauro Carvalho Chehab 		u32 offset;
24235bc3cb74SMauro Carvalho Chehab 		int (*func)(const struct v4l2_ioctl_ops *ops,
24245bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *p);
24255bc3cb74SMauro Carvalho Chehab 	} u;
24265bc3cb74SMauro Carvalho Chehab 	void (*debug)(const void *arg, bool write_only);
24275bc3cb74SMauro Carvalho Chehab };
24285bc3cb74SMauro Carvalho Chehab 
24295bc3cb74SMauro Carvalho Chehab /* This control needs a priority check */
24305bc3cb74SMauro Carvalho Chehab #define INFO_FL_PRIO	(1 << 0)
24315bc3cb74SMauro Carvalho Chehab /* This control can be valid if the filehandle passes a control handler. */
24325bc3cb74SMauro Carvalho Chehab #define INFO_FL_CTRL	(1 << 1)
24335bc3cb74SMauro Carvalho Chehab /* This is a standard ioctl, no need for special code */
24345bc3cb74SMauro Carvalho Chehab #define INFO_FL_STD	(1 << 2)
24355bc3cb74SMauro Carvalho Chehab /* This is ioctl has its own function */
24365bc3cb74SMauro Carvalho Chehab #define INFO_FL_FUNC	(1 << 3)
24375bc3cb74SMauro Carvalho Chehab /* Queuing ioctl */
24385bc3cb74SMauro Carvalho Chehab #define INFO_FL_QUEUE	(1 << 4)
24395bc3cb74SMauro Carvalho Chehab /* Zero struct from after the field to the end */
24405bc3cb74SMauro Carvalho Chehab #define INFO_FL_CLEAR(v4l2_struct, field)			\
24415bc3cb74SMauro Carvalho Chehab 	((offsetof(struct v4l2_struct, field) +			\
24425bc3cb74SMauro Carvalho Chehab 	  sizeof(((struct v4l2_struct *)0)->field)) << 16)
24435bc3cb74SMauro Carvalho Chehab #define INFO_FL_CLEAR_MASK (_IOC_SIZEMASK << 16)
24445bc3cb74SMauro Carvalho Chehab 
24455bc3cb74SMauro Carvalho Chehab #define IOCTL_INFO_STD(_ioctl, _vidioc, _debug, _flags)			\
24465bc3cb74SMauro Carvalho Chehab 	[_IOC_NR(_ioctl)] = {						\
24475bc3cb74SMauro Carvalho Chehab 		.ioctl = _ioctl,					\
24485bc3cb74SMauro Carvalho Chehab 		.flags = _flags | INFO_FL_STD,				\
24495bc3cb74SMauro Carvalho Chehab 		.name = #_ioctl,					\
24505bc3cb74SMauro Carvalho Chehab 		.u.offset = offsetof(struct v4l2_ioctl_ops, _vidioc),	\
24515bc3cb74SMauro Carvalho Chehab 		.debug = _debug,					\
24525bc3cb74SMauro Carvalho Chehab 	}
24535bc3cb74SMauro Carvalho Chehab 
24545bc3cb74SMauro Carvalho Chehab #define IOCTL_INFO_FNC(_ioctl, _func, _debug, _flags)			\
24555bc3cb74SMauro Carvalho Chehab 	[_IOC_NR(_ioctl)] = {						\
24565bc3cb74SMauro Carvalho Chehab 		.ioctl = _ioctl,					\
24575bc3cb74SMauro Carvalho Chehab 		.flags = _flags | INFO_FL_FUNC,				\
24585bc3cb74SMauro Carvalho Chehab 		.name = #_ioctl,					\
24595bc3cb74SMauro Carvalho Chehab 		.u.func = _func,					\
24605bc3cb74SMauro Carvalho Chehab 		.debug = _debug,					\
24615bc3cb74SMauro Carvalho Chehab 	}
24625bc3cb74SMauro Carvalho Chehab 
24635bc3cb74SMauro Carvalho Chehab static struct v4l2_ioctl_info v4l2_ioctls[] = {
24645bc3cb74SMauro Carvalho Chehab 	IOCTL_INFO_FNC(VIDIOC_QUERYCAP, v4l_querycap, v4l_print_querycap, 0),
24655bc3cb74SMauro Carvalho Chehab 	IOCTL_INFO_FNC(VIDIOC_ENUM_FMT, v4l_enum_fmt, v4l_print_fmtdesc, INFO_FL_CLEAR(v4l2_fmtdesc, type)),
2466e5ce558aSHans Verkuil 	IOCTL_INFO_FNC(VIDIOC_G_FMT, v4l_g_fmt, v4l_print_format, 0),
24675bc3cb74SMauro Carvalho Chehab 	IOCTL_INFO_FNC(VIDIOC_S_FMT, v4l_s_fmt, v4l_print_format, INFO_FL_PRIO),
24685bc3cb74SMauro Carvalho Chehab 	IOCTL_INFO_FNC(VIDIOC_REQBUFS, v4l_reqbufs, v4l_print_requestbuffers, INFO_FL_PRIO | INFO_FL_QUEUE),
24695bc3cb74SMauro Carvalho Chehab 	IOCTL_INFO_FNC(VIDIOC_QUERYBUF, v4l_querybuf, v4l_print_buffer, INFO_FL_QUEUE | INFO_FL_CLEAR(v4l2_buffer, length)),
24705bc3cb74SMauro Carvalho Chehab 	IOCTL_INFO_STD(VIDIOC_G_FBUF, vidioc_g_fbuf, v4l_print_framebuffer, 0),
24715bc3cb74SMauro Carvalho Chehab 	IOCTL_INFO_STD(VIDIOC_S_FBUF, vidioc_s_fbuf, v4l_print_framebuffer, INFO_FL_PRIO),
2472737c097bSHans Verkuil 	IOCTL_INFO_FNC(VIDIOC_OVERLAY, v4l_overlay, v4l_print_u32, INFO_FL_PRIO),
24735bc3cb74SMauro Carvalho Chehab 	IOCTL_INFO_FNC(VIDIOC_QBUF, v4l_qbuf, v4l_print_buffer, INFO_FL_QUEUE),
2474b799d09aSTomasz Stanislawski 	IOCTL_INFO_STD(VIDIOC_EXPBUF, vidioc_expbuf, v4l_print_exportbuffer, INFO_FL_QUEUE | INFO_FL_CLEAR(v4l2_exportbuffer, flags)),
24755bc3cb74SMauro Carvalho Chehab 	IOCTL_INFO_FNC(VIDIOC_DQBUF, v4l_dqbuf, v4l_print_buffer, INFO_FL_QUEUE),
24765bc3cb74SMauro Carvalho Chehab 	IOCTL_INFO_FNC(VIDIOC_STREAMON, v4l_streamon, v4l_print_buftype, INFO_FL_PRIO | INFO_FL_QUEUE),
24775bc3cb74SMauro Carvalho Chehab 	IOCTL_INFO_FNC(VIDIOC_STREAMOFF, v4l_streamoff, v4l_print_buftype, INFO_FL_PRIO | INFO_FL_QUEUE),
24785bc3cb74SMauro Carvalho Chehab 	IOCTL_INFO_FNC(VIDIOC_G_PARM, v4l_g_parm, v4l_print_streamparm, INFO_FL_CLEAR(v4l2_streamparm, type)),
24795bc3cb74SMauro Carvalho Chehab 	IOCTL_INFO_FNC(VIDIOC_S_PARM, v4l_s_parm, v4l_print_streamparm, INFO_FL_PRIO),
2480ca371575SHans Verkuil 	IOCTL_INFO_STD(VIDIOC_G_STD, vidioc_g_std, v4l_print_std, 0),
24815bc3cb74SMauro Carvalho Chehab 	IOCTL_INFO_FNC(VIDIOC_S_STD, v4l_s_std, v4l_print_std, INFO_FL_PRIO),
24825bc3cb74SMauro Carvalho Chehab 	IOCTL_INFO_FNC(VIDIOC_ENUMSTD, v4l_enumstd, v4l_print_standard, INFO_FL_CLEAR(v4l2_standard, index)),
24835bc3cb74SMauro Carvalho Chehab 	IOCTL_INFO_FNC(VIDIOC_ENUMINPUT, v4l_enuminput, v4l_print_enuminput, INFO_FL_CLEAR(v4l2_input, index)),
24845bc3cb74SMauro Carvalho Chehab 	IOCTL_INFO_FNC(VIDIOC_G_CTRL, v4l_g_ctrl, v4l_print_control, INFO_FL_CTRL | INFO_FL_CLEAR(v4l2_control, id)),
24855bc3cb74SMauro Carvalho Chehab 	IOCTL_INFO_FNC(VIDIOC_S_CTRL, v4l_s_ctrl, v4l_print_control, INFO_FL_PRIO | INFO_FL_CTRL),
24865bc3cb74SMauro Carvalho Chehab 	IOCTL_INFO_FNC(VIDIOC_G_TUNER, v4l_g_tuner, v4l_print_tuner, INFO_FL_CLEAR(v4l2_tuner, index)),
24875bc3cb74SMauro Carvalho Chehab 	IOCTL_INFO_FNC(VIDIOC_S_TUNER, v4l_s_tuner, v4l_print_tuner, INFO_FL_PRIO),
24885bc3cb74SMauro Carvalho Chehab 	IOCTL_INFO_STD(VIDIOC_G_AUDIO, vidioc_g_audio, v4l_print_audio, 0),
24895bc3cb74SMauro Carvalho Chehab 	IOCTL_INFO_STD(VIDIOC_S_AUDIO, vidioc_s_audio, v4l_print_audio, INFO_FL_PRIO),
24905bc3cb74SMauro Carvalho Chehab 	IOCTL_INFO_FNC(VIDIOC_QUERYCTRL, v4l_queryctrl, v4l_print_queryctrl, INFO_FL_CTRL | INFO_FL_CLEAR(v4l2_queryctrl, id)),
24915bc3cb74SMauro Carvalho Chehab 	IOCTL_INFO_FNC(VIDIOC_QUERYMENU, v4l_querymenu, v4l_print_querymenu, INFO_FL_CTRL | INFO_FL_CLEAR(v4l2_querymenu, index)),
24925bc3cb74SMauro Carvalho Chehab 	IOCTL_INFO_STD(VIDIOC_G_INPUT, vidioc_g_input, v4l_print_u32, 0),
24935bc3cb74SMauro Carvalho Chehab 	IOCTL_INFO_FNC(VIDIOC_S_INPUT, v4l_s_input, v4l_print_u32, INFO_FL_PRIO),
2494f9402a94SHans Verkuil 	IOCTL_INFO_STD(VIDIOC_G_EDID, vidioc_g_edid, v4l_print_edid, 0),
2495f9402a94SHans Verkuil 	IOCTL_INFO_STD(VIDIOC_S_EDID, vidioc_s_edid, v4l_print_edid, INFO_FL_PRIO),
24965bc3cb74SMauro Carvalho Chehab 	IOCTL_INFO_STD(VIDIOC_G_OUTPUT, vidioc_g_output, v4l_print_u32, 0),
24975bc3cb74SMauro Carvalho Chehab 	IOCTL_INFO_FNC(VIDIOC_S_OUTPUT, v4l_s_output, v4l_print_u32, INFO_FL_PRIO),
24985bc3cb74SMauro Carvalho Chehab 	IOCTL_INFO_FNC(VIDIOC_ENUMOUTPUT, v4l_enumoutput, v4l_print_enumoutput, INFO_FL_CLEAR(v4l2_output, index)),
24995bc3cb74SMauro Carvalho Chehab 	IOCTL_INFO_STD(VIDIOC_G_AUDOUT, vidioc_g_audout, v4l_print_audioout, 0),
25005bc3cb74SMauro Carvalho Chehab 	IOCTL_INFO_STD(VIDIOC_S_AUDOUT, vidioc_s_audout, v4l_print_audioout, INFO_FL_PRIO),
25015bc3cb74SMauro Carvalho Chehab 	IOCTL_INFO_FNC(VIDIOC_G_MODULATOR, v4l_g_modulator, v4l_print_modulator, INFO_FL_CLEAR(v4l2_modulator, index)),
25024124a3c4SAntti Palosaari 	IOCTL_INFO_FNC(VIDIOC_S_MODULATOR, v4l_s_modulator, v4l_print_modulator, INFO_FL_PRIO),
25035bc3cb74SMauro Carvalho Chehab 	IOCTL_INFO_FNC(VIDIOC_G_FREQUENCY, v4l_g_frequency, v4l_print_frequency, INFO_FL_CLEAR(v4l2_frequency, tuner)),
25045bc3cb74SMauro Carvalho Chehab 	IOCTL_INFO_FNC(VIDIOC_S_FREQUENCY, v4l_s_frequency, v4l_print_frequency, INFO_FL_PRIO),
25055bc3cb74SMauro Carvalho Chehab 	IOCTL_INFO_FNC(VIDIOC_CROPCAP, v4l_cropcap, v4l_print_cropcap, INFO_FL_CLEAR(v4l2_cropcap, type)),
25065bc3cb74SMauro Carvalho Chehab 	IOCTL_INFO_FNC(VIDIOC_G_CROP, v4l_g_crop, v4l_print_crop, INFO_FL_CLEAR(v4l2_crop, type)),
25075bc3cb74SMauro Carvalho Chehab 	IOCTL_INFO_FNC(VIDIOC_S_CROP, v4l_s_crop, v4l_print_crop, INFO_FL_PRIO),
2508865c4642SHans Verkuil 	IOCTL_INFO_STD(VIDIOC_G_SELECTION, vidioc_g_selection, v4l_print_selection, INFO_FL_CLEAR(v4l2_selection, r)),
2509865c4642SHans Verkuil 	IOCTL_INFO_STD(VIDIOC_S_SELECTION, vidioc_s_selection, v4l_print_selection, INFO_FL_PRIO | INFO_FL_CLEAR(v4l2_selection, r)),
25105bc3cb74SMauro Carvalho Chehab 	IOCTL_INFO_STD(VIDIOC_G_JPEGCOMP, vidioc_g_jpegcomp, v4l_print_jpegcompression, 0),
25115bc3cb74SMauro Carvalho Chehab 	IOCTL_INFO_STD(VIDIOC_S_JPEGCOMP, vidioc_s_jpegcomp, v4l_print_jpegcompression, INFO_FL_PRIO),
25125bc3cb74SMauro Carvalho Chehab 	IOCTL_INFO_FNC(VIDIOC_QUERYSTD, v4l_querystd, v4l_print_std, 0),
25135bc3cb74SMauro Carvalho Chehab 	IOCTL_INFO_FNC(VIDIOC_TRY_FMT, v4l_try_fmt, v4l_print_format, 0),
25145bc3cb74SMauro Carvalho Chehab 	IOCTL_INFO_STD(VIDIOC_ENUMAUDIO, vidioc_enumaudio, v4l_print_audio, INFO_FL_CLEAR(v4l2_audio, index)),
25155bc3cb74SMauro Carvalho Chehab 	IOCTL_INFO_STD(VIDIOC_ENUMAUDOUT, vidioc_enumaudout, v4l_print_audioout, INFO_FL_CLEAR(v4l2_audioout, index)),
25165bc3cb74SMauro Carvalho Chehab 	IOCTL_INFO_FNC(VIDIOC_G_PRIORITY, v4l_g_priority, v4l_print_u32, 0),
25175bc3cb74SMauro Carvalho Chehab 	IOCTL_INFO_FNC(VIDIOC_S_PRIORITY, v4l_s_priority, v4l_print_u32, INFO_FL_PRIO),
25185bc3cb74SMauro 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)),
25195bc3cb74SMauro Carvalho Chehab 	IOCTL_INFO_FNC(VIDIOC_LOG_STATUS, v4l_log_status, v4l_print_newline, 0),
25205bc3cb74SMauro Carvalho Chehab 	IOCTL_INFO_FNC(VIDIOC_G_EXT_CTRLS, v4l_g_ext_ctrls, v4l_print_ext_controls, INFO_FL_CTRL),
25215bc3cb74SMauro Carvalho Chehab 	IOCTL_INFO_FNC(VIDIOC_S_EXT_CTRLS, v4l_s_ext_ctrls, v4l_print_ext_controls, INFO_FL_PRIO | INFO_FL_CTRL),
25225bc3cb74SMauro Carvalho Chehab 	IOCTL_INFO_FNC(VIDIOC_TRY_EXT_CTRLS, v4l_try_ext_ctrls, v4l_print_ext_controls, INFO_FL_CTRL),
25235bc3cb74SMauro Carvalho Chehab 	IOCTL_INFO_STD(VIDIOC_ENUM_FRAMESIZES, vidioc_enum_framesizes, v4l_print_frmsizeenum, INFO_FL_CLEAR(v4l2_frmsizeenum, pixel_format)),
25245bc3cb74SMauro Carvalho Chehab 	IOCTL_INFO_STD(VIDIOC_ENUM_FRAMEINTERVALS, vidioc_enum_frameintervals, v4l_print_frmivalenum, INFO_FL_CLEAR(v4l2_frmivalenum, height)),
25255bc3cb74SMauro Carvalho Chehab 	IOCTL_INFO_STD(VIDIOC_G_ENC_INDEX, vidioc_g_enc_index, v4l_print_enc_idx, 0),
25265bc3cb74SMauro 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)),
25275bc3cb74SMauro Carvalho Chehab 	IOCTL_INFO_STD(VIDIOC_TRY_ENCODER_CMD, vidioc_try_encoder_cmd, v4l_print_encoder_cmd, INFO_FL_CLEAR(v4l2_encoder_cmd, flags)),
25285bc3cb74SMauro Carvalho Chehab 	IOCTL_INFO_STD(VIDIOC_DECODER_CMD, vidioc_decoder_cmd, v4l_print_decoder_cmd, INFO_FL_PRIO),
25295bc3cb74SMauro Carvalho Chehab 	IOCTL_INFO_STD(VIDIOC_TRY_DECODER_CMD, vidioc_try_decoder_cmd, v4l_print_decoder_cmd, 0),
25305bc3cb74SMauro Carvalho Chehab 	IOCTL_INFO_FNC(VIDIOC_DBG_S_REGISTER, v4l_dbg_s_register, v4l_print_dbg_register, 0),
25315bc3cb74SMauro Carvalho Chehab 	IOCTL_INFO_FNC(VIDIOC_DBG_G_REGISTER, v4l_dbg_g_register, v4l_print_dbg_register, 0),
25325bc3cb74SMauro Carvalho Chehab 	IOCTL_INFO_FNC(VIDIOC_S_HW_FREQ_SEEK, v4l_s_hw_freq_seek, v4l_print_hw_freq_seek, INFO_FL_PRIO),
2533f932af80SHans Verkuil 	IOCTL_INFO_STD(VIDIOC_S_DV_TIMINGS, vidioc_s_dv_timings, v4l_print_dv_timings, INFO_FL_PRIO | INFO_FL_CLEAR(v4l2_dv_timings, bt.flags)),
25345bc3cb74SMauro Carvalho Chehab 	IOCTL_INFO_STD(VIDIOC_G_DV_TIMINGS, vidioc_g_dv_timings, v4l_print_dv_timings, 0),
25355bc3cb74SMauro Carvalho Chehab 	IOCTL_INFO_FNC(VIDIOC_DQEVENT, v4l_dqevent, v4l_print_event, 0),
25365bc3cb74SMauro Carvalho Chehab 	IOCTL_INFO_FNC(VIDIOC_SUBSCRIBE_EVENT, v4l_subscribe_event, v4l_print_event_subscription, 0),
25375bc3cb74SMauro Carvalho Chehab 	IOCTL_INFO_FNC(VIDIOC_UNSUBSCRIBE_EVENT, v4l_unsubscribe_event, v4l_print_event_subscription, 0),
25385bc3cb74SMauro Carvalho Chehab 	IOCTL_INFO_FNC(VIDIOC_CREATE_BUFS, v4l_create_bufs, v4l_print_create_buffers, INFO_FL_PRIO | INFO_FL_QUEUE),
25395bc3cb74SMauro Carvalho Chehab 	IOCTL_INFO_FNC(VIDIOC_PREPARE_BUF, v4l_prepare_buf, v4l_print_buffer, INFO_FL_QUEUE),
2540f932af80SHans Verkuil 	IOCTL_INFO_STD(VIDIOC_ENUM_DV_TIMINGS, vidioc_enum_dv_timings, v4l_print_enum_dv_timings, INFO_FL_CLEAR(v4l2_enum_dv_timings, pad)),
25415bc3cb74SMauro Carvalho Chehab 	IOCTL_INFO_STD(VIDIOC_QUERY_DV_TIMINGS, vidioc_query_dv_timings, v4l_print_dv_timings, 0),
25425bc3cb74SMauro 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)),
25435bc3cb74SMauro Carvalho Chehab 	IOCTL_INFO_FNC(VIDIOC_ENUM_FREQ_BANDS, v4l_enum_freq_bands, v4l_print_freq_band, 0),
254496b03d2aSHans 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)),
2545e6bee368SHans 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)),
25465bc3cb74SMauro Carvalho Chehab };
25475bc3cb74SMauro Carvalho Chehab #define V4L2_IOCTLS ARRAY_SIZE(v4l2_ioctls)
25485bc3cb74SMauro Carvalho Chehab 
25495bc3cb74SMauro Carvalho Chehab bool v4l2_is_known_ioctl(unsigned int cmd)
25505bc3cb74SMauro Carvalho Chehab {
25515bc3cb74SMauro Carvalho Chehab 	if (_IOC_NR(cmd) >= V4L2_IOCTLS)
25525bc3cb74SMauro Carvalho Chehab 		return false;
25535bc3cb74SMauro Carvalho Chehab 	return v4l2_ioctls[_IOC_NR(cmd)].ioctl == cmd;
25545bc3cb74SMauro Carvalho Chehab }
25555bc3cb74SMauro Carvalho Chehab 
25565bc3cb74SMauro Carvalho Chehab struct mutex *v4l2_ioctl_get_lock(struct video_device *vdev, unsigned cmd)
25575bc3cb74SMauro Carvalho Chehab {
25585bc3cb74SMauro Carvalho Chehab 	if (_IOC_NR(cmd) >= V4L2_IOCTLS)
25595bc3cb74SMauro Carvalho Chehab 		return vdev->lock;
25605bc3cb74SMauro Carvalho Chehab 	if (test_bit(_IOC_NR(cmd), vdev->disable_locking))
25615bc3cb74SMauro Carvalho Chehab 		return NULL;
25625bc3cb74SMauro Carvalho Chehab 	if (vdev->queue && vdev->queue->lock &&
25635bc3cb74SMauro Carvalho Chehab 			(v4l2_ioctls[_IOC_NR(cmd)].flags & INFO_FL_QUEUE))
25645bc3cb74SMauro Carvalho Chehab 		return vdev->queue->lock;
25655bc3cb74SMauro Carvalho Chehab 	return vdev->lock;
25665bc3cb74SMauro Carvalho Chehab }
25675bc3cb74SMauro Carvalho Chehab 
25685bc3cb74SMauro Carvalho Chehab /* Common ioctl debug function. This function can be used by
25695bc3cb74SMauro Carvalho Chehab    external ioctl messages as well as internal V4L ioctl */
25705bc3cb74SMauro Carvalho Chehab void v4l_printk_ioctl(const char *prefix, unsigned int cmd)
25715bc3cb74SMauro Carvalho Chehab {
25725bc3cb74SMauro Carvalho Chehab 	const char *dir, *type;
25735bc3cb74SMauro Carvalho Chehab 
25745bc3cb74SMauro Carvalho Chehab 	if (prefix)
25755bc3cb74SMauro Carvalho Chehab 		printk(KERN_DEBUG "%s: ", prefix);
25765bc3cb74SMauro Carvalho Chehab 
25775bc3cb74SMauro Carvalho Chehab 	switch (_IOC_TYPE(cmd)) {
25785bc3cb74SMauro Carvalho Chehab 	case 'd':
25795bc3cb74SMauro Carvalho Chehab 		type = "v4l2_int";
25805bc3cb74SMauro Carvalho Chehab 		break;
25815bc3cb74SMauro Carvalho Chehab 	case 'V':
25825bc3cb74SMauro Carvalho Chehab 		if (_IOC_NR(cmd) >= V4L2_IOCTLS) {
25835bc3cb74SMauro Carvalho Chehab 			type = "v4l2";
25845bc3cb74SMauro Carvalho Chehab 			break;
25855bc3cb74SMauro Carvalho Chehab 		}
25865bc3cb74SMauro Carvalho Chehab 		pr_cont("%s", v4l2_ioctls[_IOC_NR(cmd)].name);
25875bc3cb74SMauro Carvalho Chehab 		return;
25885bc3cb74SMauro Carvalho Chehab 	default:
25895bc3cb74SMauro Carvalho Chehab 		type = "unknown";
25905bc3cb74SMauro Carvalho Chehab 		break;
25915bc3cb74SMauro Carvalho Chehab 	}
25925bc3cb74SMauro Carvalho Chehab 
25935bc3cb74SMauro Carvalho Chehab 	switch (_IOC_DIR(cmd)) {
25945bc3cb74SMauro Carvalho Chehab 	case _IOC_NONE:              dir = "--"; break;
25955bc3cb74SMauro Carvalho Chehab 	case _IOC_READ:              dir = "r-"; break;
25965bc3cb74SMauro Carvalho Chehab 	case _IOC_WRITE:             dir = "-w"; break;
25975bc3cb74SMauro Carvalho Chehab 	case _IOC_READ | _IOC_WRITE: dir = "rw"; break;
25985bc3cb74SMauro Carvalho Chehab 	default:                     dir = "*ERR*"; break;
25995bc3cb74SMauro Carvalho Chehab 	}
26005bc3cb74SMauro Carvalho Chehab 	pr_cont("%s ioctl '%c', dir=%s, #%d (0x%08x)",
26015bc3cb74SMauro Carvalho Chehab 		type, _IOC_TYPE(cmd), dir, _IOC_NR(cmd), cmd);
26025bc3cb74SMauro Carvalho Chehab }
26035bc3cb74SMauro Carvalho Chehab EXPORT_SYMBOL(v4l_printk_ioctl);
26045bc3cb74SMauro Carvalho Chehab 
26055bc3cb74SMauro Carvalho Chehab static long __video_do_ioctl(struct file *file,
26065bc3cb74SMauro Carvalho Chehab 		unsigned int cmd, void *arg)
26075bc3cb74SMauro Carvalho Chehab {
26085bc3cb74SMauro Carvalho Chehab 	struct video_device *vfd = video_devdata(file);
26095bc3cb74SMauro Carvalho Chehab 	const struct v4l2_ioctl_ops *ops = vfd->ioctl_ops;
26105bc3cb74SMauro Carvalho Chehab 	bool write_only = false;
26115bc3cb74SMauro Carvalho Chehab 	struct v4l2_ioctl_info default_info;
26125bc3cb74SMauro Carvalho Chehab 	const struct v4l2_ioctl_info *info;
26135bc3cb74SMauro Carvalho Chehab 	void *fh = file->private_data;
26145bc3cb74SMauro Carvalho Chehab 	struct v4l2_fh *vfh = NULL;
261517028cdbSHans Verkuil 	int dev_debug = vfd->dev_debug;
26165bc3cb74SMauro Carvalho Chehab 	long ret = -ENOTTY;
26175bc3cb74SMauro Carvalho Chehab 
26185bc3cb74SMauro Carvalho Chehab 	if (ops == NULL) {
26195bc3cb74SMauro Carvalho Chehab 		pr_warn("%s: has no ioctl_ops.\n",
26205bc3cb74SMauro Carvalho Chehab 				video_device_node_name(vfd));
26215bc3cb74SMauro Carvalho Chehab 		return ret;
26225bc3cb74SMauro Carvalho Chehab 	}
26235bc3cb74SMauro Carvalho Chehab 
2624b7284bb0SRamakrishnan Muthukrishnan 	if (test_bit(V4L2_FL_USES_V4L2_FH, &vfd->flags))
26255bc3cb74SMauro Carvalho Chehab 		vfh = file->private_data;
26265bc3cb74SMauro Carvalho Chehab 
26275bc3cb74SMauro Carvalho Chehab 	if (v4l2_is_known_ioctl(cmd)) {
26285bc3cb74SMauro Carvalho Chehab 		info = &v4l2_ioctls[_IOC_NR(cmd)];
26295bc3cb74SMauro Carvalho Chehab 
26305bc3cb74SMauro Carvalho Chehab 		if (!test_bit(_IOC_NR(cmd), vfd->valid_ioctls) &&
26315bc3cb74SMauro Carvalho Chehab 		    !((info->flags & INFO_FL_CTRL) && vfh && vfh->ctrl_handler))
26325bc3cb74SMauro Carvalho Chehab 			goto done;
26335bc3cb74SMauro Carvalho Chehab 
2634b7284bb0SRamakrishnan Muthukrishnan 		if (vfh && (info->flags & INFO_FL_PRIO)) {
26355bc3cb74SMauro Carvalho Chehab 			ret = v4l2_prio_check(vfd->prio, vfh->prio);
26365bc3cb74SMauro Carvalho Chehab 			if (ret)
26375bc3cb74SMauro Carvalho Chehab 				goto done;
26385bc3cb74SMauro Carvalho Chehab 		}
26395bc3cb74SMauro Carvalho Chehab 	} else {
26405bc3cb74SMauro Carvalho Chehab 		default_info.ioctl = cmd;
26415bc3cb74SMauro Carvalho Chehab 		default_info.flags = 0;
26425bc3cb74SMauro Carvalho Chehab 		default_info.debug = v4l_print_default;
26435bc3cb74SMauro Carvalho Chehab 		info = &default_info;
26445bc3cb74SMauro Carvalho Chehab 	}
26455bc3cb74SMauro Carvalho Chehab 
26465bc3cb74SMauro Carvalho Chehab 	write_only = _IOC_DIR(cmd) == _IOC_WRITE;
26475bc3cb74SMauro Carvalho Chehab 	if (info->flags & INFO_FL_STD) {
26485bc3cb74SMauro Carvalho Chehab 		typedef int (*vidioc_op)(struct file *file, void *fh, void *p);
26495bc3cb74SMauro Carvalho Chehab 		const void *p = vfd->ioctl_ops;
26505bc3cb74SMauro Carvalho Chehab 		const vidioc_op *vidioc = p + info->u.offset;
26515bc3cb74SMauro Carvalho Chehab 
26525bc3cb74SMauro Carvalho Chehab 		ret = (*vidioc)(file, fh, arg);
26535bc3cb74SMauro Carvalho Chehab 	} else if (info->flags & INFO_FL_FUNC) {
26545bc3cb74SMauro Carvalho Chehab 		ret = info->u.func(ops, file, fh, arg);
26555bc3cb74SMauro Carvalho Chehab 	} else if (!ops->vidioc_default) {
26565bc3cb74SMauro Carvalho Chehab 		ret = -ENOTTY;
26575bc3cb74SMauro Carvalho Chehab 	} else {
26585bc3cb74SMauro Carvalho Chehab 		ret = ops->vidioc_default(file, fh,
2659b7284bb0SRamakrishnan Muthukrishnan 			vfh ? v4l2_prio_check(vfd->prio, vfh->prio) >= 0 : 0,
26605bc3cb74SMauro Carvalho Chehab 			cmd, arg);
26615bc3cb74SMauro Carvalho Chehab 	}
26625bc3cb74SMauro Carvalho Chehab 
26635bc3cb74SMauro Carvalho Chehab done:
266417028cdbSHans Verkuil 	if (dev_debug & (V4L2_DEV_DEBUG_IOCTL | V4L2_DEV_DEBUG_IOCTL_ARG)) {
266517028cdbSHans Verkuil 		if (!(dev_debug & V4L2_DEV_DEBUG_STREAMING) &&
266617028cdbSHans Verkuil 		    (cmd == VIDIOC_QBUF || cmd == VIDIOC_DQBUF))
266717028cdbSHans Verkuil 			return ret;
266817028cdbSHans Verkuil 
26695bc3cb74SMauro Carvalho Chehab 		v4l_printk_ioctl(video_device_node_name(vfd), cmd);
26705bc3cb74SMauro Carvalho Chehab 		if (ret < 0)
2671505d04bdSHans Verkuil 			pr_cont(": error %ld", ret);
267217028cdbSHans Verkuil 		if (!(dev_debug & V4L2_DEV_DEBUG_IOCTL_ARG))
26735bc3cb74SMauro Carvalho Chehab 			pr_cont("\n");
26745bc3cb74SMauro Carvalho Chehab 		else if (_IOC_DIR(cmd) == _IOC_NONE)
26755bc3cb74SMauro Carvalho Chehab 			info->debug(arg, write_only);
26765bc3cb74SMauro Carvalho Chehab 		else {
26775bc3cb74SMauro Carvalho Chehab 			pr_cont(": ");
26785bc3cb74SMauro Carvalho Chehab 			info->debug(arg, write_only);
26795bc3cb74SMauro Carvalho Chehab 		}
26805bc3cb74SMauro Carvalho Chehab 	}
26815bc3cb74SMauro Carvalho Chehab 
26825bc3cb74SMauro Carvalho Chehab 	return ret;
26835bc3cb74SMauro Carvalho Chehab }
26845bc3cb74SMauro Carvalho Chehab 
26855bc3cb74SMauro Carvalho Chehab static int check_array_args(unsigned int cmd, void *parg, size_t *array_size,
2686ba2d35c1SHans Verkuil 			    void __user **user_ptr, void ***kernel_ptr)
26875bc3cb74SMauro Carvalho Chehab {
26885bc3cb74SMauro Carvalho Chehab 	int ret = 0;
26895bc3cb74SMauro Carvalho Chehab 
26905bc3cb74SMauro Carvalho Chehab 	switch (cmd) {
269196b1a702SHans Verkuil 	case VIDIOC_PREPARE_BUF:
26925bc3cb74SMauro Carvalho Chehab 	case VIDIOC_QUERYBUF:
26935bc3cb74SMauro Carvalho Chehab 	case VIDIOC_QBUF:
26945bc3cb74SMauro Carvalho Chehab 	case VIDIOC_DQBUF: {
26955bc3cb74SMauro Carvalho Chehab 		struct v4l2_buffer *buf = parg;
26965bc3cb74SMauro Carvalho Chehab 
26975bc3cb74SMauro Carvalho Chehab 		if (V4L2_TYPE_IS_MULTIPLANAR(buf->type) && buf->length > 0) {
26985bc3cb74SMauro Carvalho Chehab 			if (buf->length > VIDEO_MAX_PLANES) {
26995bc3cb74SMauro Carvalho Chehab 				ret = -EINVAL;
27005bc3cb74SMauro Carvalho Chehab 				break;
27015bc3cb74SMauro Carvalho Chehab 			}
27025bc3cb74SMauro Carvalho Chehab 			*user_ptr = (void __user *)buf->m.planes;
2703ba2d35c1SHans Verkuil 			*kernel_ptr = (void **)&buf->m.planes;
27045bc3cb74SMauro Carvalho Chehab 			*array_size = sizeof(struct v4l2_plane) * buf->length;
27055bc3cb74SMauro Carvalho Chehab 			ret = 1;
27065bc3cb74SMauro Carvalho Chehab 		}
27075bc3cb74SMauro Carvalho Chehab 		break;
27085bc3cb74SMauro Carvalho Chehab 	}
27095bc3cb74SMauro Carvalho Chehab 
2710dd519bb3SHans Verkuil 	case VIDIOC_G_EDID:
2711dd519bb3SHans Verkuil 	case VIDIOC_S_EDID: {
2712dd519bb3SHans Verkuil 		struct v4l2_edid *edid = parg;
2713ed45ce2cSHans Verkuil 
2714ed45ce2cSHans Verkuil 		if (edid->blocks) {
27151b8b10ccSHans Verkuil 			if (edid->blocks > 256) {
27161b8b10ccSHans Verkuil 				ret = -EINVAL;
27171b8b10ccSHans Verkuil 				break;
27181b8b10ccSHans Verkuil 			}
2719ed45ce2cSHans Verkuil 			*user_ptr = (void __user *)edid->edid;
2720ba2d35c1SHans Verkuil 			*kernel_ptr = (void **)&edid->edid;
2721ed45ce2cSHans Verkuil 			*array_size = edid->blocks * 128;
2722ed45ce2cSHans Verkuil 			ret = 1;
2723ed45ce2cSHans Verkuil 		}
2724ed45ce2cSHans Verkuil 		break;
2725ed45ce2cSHans Verkuil 	}
2726ed45ce2cSHans Verkuil 
27275bc3cb74SMauro Carvalho Chehab 	case VIDIOC_S_EXT_CTRLS:
27285bc3cb74SMauro Carvalho Chehab 	case VIDIOC_G_EXT_CTRLS:
27295bc3cb74SMauro Carvalho Chehab 	case VIDIOC_TRY_EXT_CTRLS: {
27305bc3cb74SMauro Carvalho Chehab 		struct v4l2_ext_controls *ctrls = parg;
27315bc3cb74SMauro Carvalho Chehab 
27325bc3cb74SMauro Carvalho Chehab 		if (ctrls->count != 0) {
27335bc3cb74SMauro Carvalho Chehab 			if (ctrls->count > V4L2_CID_MAX_CTRLS) {
27345bc3cb74SMauro Carvalho Chehab 				ret = -EINVAL;
27355bc3cb74SMauro Carvalho Chehab 				break;
27365bc3cb74SMauro Carvalho Chehab 			}
27375bc3cb74SMauro Carvalho Chehab 			*user_ptr = (void __user *)ctrls->controls;
2738ba2d35c1SHans Verkuil 			*kernel_ptr = (void **)&ctrls->controls;
27395bc3cb74SMauro Carvalho Chehab 			*array_size = sizeof(struct v4l2_ext_control)
27405bc3cb74SMauro Carvalho Chehab 				    * ctrls->count;
27415bc3cb74SMauro Carvalho Chehab 			ret = 1;
27425bc3cb74SMauro Carvalho Chehab 		}
27435bc3cb74SMauro Carvalho Chehab 		break;
27445bc3cb74SMauro Carvalho Chehab 	}
27455bc3cb74SMauro Carvalho Chehab 	}
27465bc3cb74SMauro Carvalho Chehab 
27475bc3cb74SMauro Carvalho Chehab 	return ret;
27485bc3cb74SMauro Carvalho Chehab }
27495bc3cb74SMauro Carvalho Chehab 
27505bc3cb74SMauro Carvalho Chehab long
27515bc3cb74SMauro Carvalho Chehab video_usercopy(struct file *file, unsigned int cmd, unsigned long arg,
27525bc3cb74SMauro Carvalho Chehab 	       v4l2_kioctl func)
27535bc3cb74SMauro Carvalho Chehab {
27545bc3cb74SMauro Carvalho Chehab 	char	sbuf[128];
27555bc3cb74SMauro Carvalho Chehab 	void    *mbuf = NULL;
27565bc3cb74SMauro Carvalho Chehab 	void	*parg = (void *)arg;
27575bc3cb74SMauro Carvalho Chehab 	long	err  = -EINVAL;
27585bc3cb74SMauro Carvalho Chehab 	bool	has_array_args;
27595bc3cb74SMauro Carvalho Chehab 	size_t  array_size = 0;
27605bc3cb74SMauro Carvalho Chehab 	void __user *user_ptr = NULL;
27615bc3cb74SMauro Carvalho Chehab 	void	**kernel_ptr = NULL;
27625bc3cb74SMauro Carvalho Chehab 
27635bc3cb74SMauro Carvalho Chehab 	/*  Copy arguments into temp kernel buffer  */
27645bc3cb74SMauro Carvalho Chehab 	if (_IOC_DIR(cmd) != _IOC_NONE) {
27655bc3cb74SMauro Carvalho Chehab 		if (_IOC_SIZE(cmd) <= sizeof(sbuf)) {
27665bc3cb74SMauro Carvalho Chehab 			parg = sbuf;
27675bc3cb74SMauro Carvalho Chehab 		} else {
27685bc3cb74SMauro Carvalho Chehab 			/* too big to allocate from stack */
27695bc3cb74SMauro Carvalho Chehab 			mbuf = kmalloc(_IOC_SIZE(cmd), GFP_KERNEL);
27705bc3cb74SMauro Carvalho Chehab 			if (NULL == mbuf)
27715bc3cb74SMauro Carvalho Chehab 				return -ENOMEM;
27725bc3cb74SMauro Carvalho Chehab 			parg = mbuf;
27735bc3cb74SMauro Carvalho Chehab 		}
27745bc3cb74SMauro Carvalho Chehab 
27755bc3cb74SMauro Carvalho Chehab 		err = -EFAULT;
27765bc3cb74SMauro Carvalho Chehab 		if (_IOC_DIR(cmd) & _IOC_WRITE) {
27775bc3cb74SMauro Carvalho Chehab 			unsigned int n = _IOC_SIZE(cmd);
27785bc3cb74SMauro Carvalho Chehab 
27795bc3cb74SMauro Carvalho Chehab 			/*
27805bc3cb74SMauro Carvalho Chehab 			 * In some cases, only a few fields are used as input,
27815bc3cb74SMauro Carvalho Chehab 			 * i.e. when the app sets "index" and then the driver
27825bc3cb74SMauro Carvalho Chehab 			 * fills in the rest of the structure for the thing
27835bc3cb74SMauro Carvalho Chehab 			 * with that index.  We only need to copy up the first
27845bc3cb74SMauro Carvalho Chehab 			 * non-input field.
27855bc3cb74SMauro Carvalho Chehab 			 */
27865bc3cb74SMauro Carvalho Chehab 			if (v4l2_is_known_ioctl(cmd)) {
27875bc3cb74SMauro Carvalho Chehab 				u32 flags = v4l2_ioctls[_IOC_NR(cmd)].flags;
27885bc3cb74SMauro Carvalho Chehab 				if (flags & INFO_FL_CLEAR_MASK)
27895bc3cb74SMauro Carvalho Chehab 					n = (flags & INFO_FL_CLEAR_MASK) >> 16;
27905bc3cb74SMauro Carvalho Chehab 			}
27915bc3cb74SMauro Carvalho Chehab 
27925bc3cb74SMauro Carvalho Chehab 			if (copy_from_user(parg, (void __user *)arg, n))
27935bc3cb74SMauro Carvalho Chehab 				goto out;
27945bc3cb74SMauro Carvalho Chehab 
27955bc3cb74SMauro Carvalho Chehab 			/* zero out anything we don't copy from userspace */
27965bc3cb74SMauro Carvalho Chehab 			if (n < _IOC_SIZE(cmd))
27975bc3cb74SMauro Carvalho Chehab 				memset((u8 *)parg + n, 0, _IOC_SIZE(cmd) - n);
27985bc3cb74SMauro Carvalho Chehab 		} else {
27995bc3cb74SMauro Carvalho Chehab 			/* read-only ioctl */
28005bc3cb74SMauro Carvalho Chehab 			memset(parg, 0, _IOC_SIZE(cmd));
28015bc3cb74SMauro Carvalho Chehab 		}
28025bc3cb74SMauro Carvalho Chehab 	}
28035bc3cb74SMauro Carvalho Chehab 
28045bc3cb74SMauro Carvalho Chehab 	err = check_array_args(cmd, parg, &array_size, &user_ptr, &kernel_ptr);
28055bc3cb74SMauro Carvalho Chehab 	if (err < 0)
28065bc3cb74SMauro Carvalho Chehab 		goto out;
28075bc3cb74SMauro Carvalho Chehab 	has_array_args = err;
28085bc3cb74SMauro Carvalho Chehab 
28095bc3cb74SMauro Carvalho Chehab 	if (has_array_args) {
28105bc3cb74SMauro Carvalho Chehab 		/*
28115bc3cb74SMauro Carvalho Chehab 		 * When adding new types of array args, make sure that the
28125bc3cb74SMauro Carvalho Chehab 		 * parent argument to ioctl (which contains the pointer to the
28135bc3cb74SMauro Carvalho Chehab 		 * array) fits into sbuf (so that mbuf will still remain
28145bc3cb74SMauro Carvalho Chehab 		 * unused up to here).
28155bc3cb74SMauro Carvalho Chehab 		 */
28165bc3cb74SMauro Carvalho Chehab 		mbuf = kmalloc(array_size, GFP_KERNEL);
28175bc3cb74SMauro Carvalho Chehab 		err = -ENOMEM;
28185bc3cb74SMauro Carvalho Chehab 		if (NULL == mbuf)
28195bc3cb74SMauro Carvalho Chehab 			goto out_array_args;
28205bc3cb74SMauro Carvalho Chehab 		err = -EFAULT;
28215bc3cb74SMauro Carvalho Chehab 		if (copy_from_user(mbuf, user_ptr, array_size))
28225bc3cb74SMauro Carvalho Chehab 			goto out_array_args;
28235bc3cb74SMauro Carvalho Chehab 		*kernel_ptr = mbuf;
28245bc3cb74SMauro Carvalho Chehab 	}
28255bc3cb74SMauro Carvalho Chehab 
28265bc3cb74SMauro Carvalho Chehab 	/* Handles IOCTL */
28275bc3cb74SMauro Carvalho Chehab 	err = func(file, cmd, parg);
28285bc3cb74SMauro Carvalho Chehab 	if (err == -ENOIOCTLCMD)
28295bc3cb74SMauro Carvalho Chehab 		err = -ENOTTY;
2830aa32f4c0SHans Verkuil 	if (err == 0) {
2831aa32f4c0SHans Verkuil 		if (cmd == VIDIOC_DQBUF)
2832aa32f4c0SHans Verkuil 			trace_v4l2_dqbuf(video_devdata(file)->minor, parg);
2833aa32f4c0SHans Verkuil 		else if (cmd == VIDIOC_QBUF)
2834aa32f4c0SHans Verkuil 			trace_v4l2_qbuf(video_devdata(file)->minor, parg);
2835aa32f4c0SHans Verkuil 	}
28365bc3cb74SMauro Carvalho Chehab 
28375bc3cb74SMauro Carvalho Chehab 	if (has_array_args) {
2838ba2d35c1SHans Verkuil 		*kernel_ptr = (void __force *)user_ptr;
28395bc3cb74SMauro Carvalho Chehab 		if (copy_to_user(user_ptr, mbuf, array_size))
28405bc3cb74SMauro Carvalho Chehab 			err = -EFAULT;
28415bc3cb74SMauro Carvalho Chehab 		goto out_array_args;
28425bc3cb74SMauro Carvalho Chehab 	}
28435bc3cb74SMauro Carvalho Chehab 	/* VIDIOC_QUERY_DV_TIMINGS can return an error, but still have valid
28445bc3cb74SMauro Carvalho Chehab 	   results that must be returned. */
28455bc3cb74SMauro Carvalho Chehab 	if (err < 0 && cmd != VIDIOC_QUERY_DV_TIMINGS)
28465bc3cb74SMauro Carvalho Chehab 		goto out;
28475bc3cb74SMauro Carvalho Chehab 
28485bc3cb74SMauro Carvalho Chehab out_array_args:
28495bc3cb74SMauro Carvalho Chehab 	/*  Copy results into user buffer  */
28505bc3cb74SMauro Carvalho Chehab 	switch (_IOC_DIR(cmd)) {
28515bc3cb74SMauro Carvalho Chehab 	case _IOC_READ:
28525bc3cb74SMauro Carvalho Chehab 	case (_IOC_WRITE | _IOC_READ):
28535bc3cb74SMauro Carvalho Chehab 		if (copy_to_user((void __user *)arg, parg, _IOC_SIZE(cmd)))
28545bc3cb74SMauro Carvalho Chehab 			err = -EFAULT;
28555bc3cb74SMauro Carvalho Chehab 		break;
28565bc3cb74SMauro Carvalho Chehab 	}
28575bc3cb74SMauro Carvalho Chehab 
28585bc3cb74SMauro Carvalho Chehab out:
28595bc3cb74SMauro Carvalho Chehab 	kfree(mbuf);
28605bc3cb74SMauro Carvalho Chehab 	return err;
28615bc3cb74SMauro Carvalho Chehab }
28625bc3cb74SMauro Carvalho Chehab EXPORT_SYMBOL(video_usercopy);
28635bc3cb74SMauro Carvalho Chehab 
28645bc3cb74SMauro Carvalho Chehab long video_ioctl2(struct file *file,
28655bc3cb74SMauro Carvalho Chehab 	       unsigned int cmd, unsigned long arg)
28665bc3cb74SMauro Carvalho Chehab {
28675bc3cb74SMauro Carvalho Chehab 	return video_usercopy(file, cmd, arg, __video_do_ioctl);
28685bc3cb74SMauro Carvalho Chehab }
28695bc3cb74SMauro Carvalho Chehab EXPORT_SYMBOL(video_ioctl2);
2870