1*4882a593Smuzhiyun // SPDX-License-Identifier: GPL-2.0-or-later
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun * Video capture interface for Linux version 2
4*4882a593Smuzhiyun *
5*4882a593Smuzhiyun * A generic framework to process V4L2 ioctl commands.
6*4882a593Smuzhiyun *
7*4882a593Smuzhiyun * Authors: Alan Cox, <alan@lxorguk.ukuu.org.uk> (version 1)
8*4882a593Smuzhiyun * Mauro Carvalho Chehab <mchehab@kernel.org> (version 2)
9*4882a593Smuzhiyun */
10*4882a593Smuzhiyun
11*4882a593Smuzhiyun #include <linux/mm.h>
12*4882a593Smuzhiyun #include <linux/module.h>
13*4882a593Smuzhiyun #include <linux/slab.h>
14*4882a593Smuzhiyun #include <linux/types.h>
15*4882a593Smuzhiyun #include <linux/kernel.h>
16*4882a593Smuzhiyun #include <linux/version.h>
17*4882a593Smuzhiyun
18*4882a593Smuzhiyun #include <linux/videodev2.h>
19*4882a593Smuzhiyun
20*4882a593Smuzhiyun #include <media/v4l2-common.h>
21*4882a593Smuzhiyun #include <media/v4l2-ioctl.h>
22*4882a593Smuzhiyun #include <media/v4l2-ctrls.h>
23*4882a593Smuzhiyun #include <media/v4l2-fh.h>
24*4882a593Smuzhiyun #include <media/v4l2-event.h>
25*4882a593Smuzhiyun #include <media/v4l2-device.h>
26*4882a593Smuzhiyun #include <media/videobuf2-v4l2.h>
27*4882a593Smuzhiyun #include <media/v4l2-mc.h>
28*4882a593Smuzhiyun #include <media/v4l2-mem2mem.h>
29*4882a593Smuzhiyun
30*4882a593Smuzhiyun #include <trace/events/v4l2.h>
31*4882a593Smuzhiyun #include <trace/hooks/v4l2core.h>
32*4882a593Smuzhiyun
33*4882a593Smuzhiyun
34*4882a593Smuzhiyun /* Zero out the end of the struct pointed to by p. Everything after, but
35*4882a593Smuzhiyun * not including, the specified field is cleared. */
36*4882a593Smuzhiyun #define CLEAR_AFTER_FIELD(p, field) \
37*4882a593Smuzhiyun memset((u8 *)(p) + offsetof(typeof(*(p)), field) + sizeof((p)->field), \
38*4882a593Smuzhiyun 0, sizeof(*(p)) - offsetof(typeof(*(p)), field) - sizeof((p)->field))
39*4882a593Smuzhiyun
40*4882a593Smuzhiyun #define is_valid_ioctl(vfd, cmd) test_bit(_IOC_NR(cmd), (vfd)->valid_ioctls)
41*4882a593Smuzhiyun
42*4882a593Smuzhiyun struct std_descr {
43*4882a593Smuzhiyun v4l2_std_id std;
44*4882a593Smuzhiyun const char *descr;
45*4882a593Smuzhiyun };
46*4882a593Smuzhiyun
47*4882a593Smuzhiyun static const struct std_descr standards[] = {
48*4882a593Smuzhiyun { V4L2_STD_NTSC, "NTSC" },
49*4882a593Smuzhiyun { V4L2_STD_NTSC_M, "NTSC-M" },
50*4882a593Smuzhiyun { V4L2_STD_NTSC_M_JP, "NTSC-M-JP" },
51*4882a593Smuzhiyun { V4L2_STD_NTSC_M_KR, "NTSC-M-KR" },
52*4882a593Smuzhiyun { V4L2_STD_NTSC_443, "NTSC-443" },
53*4882a593Smuzhiyun { V4L2_STD_PAL, "PAL" },
54*4882a593Smuzhiyun { V4L2_STD_PAL_BG, "PAL-BG" },
55*4882a593Smuzhiyun { V4L2_STD_PAL_B, "PAL-B" },
56*4882a593Smuzhiyun { V4L2_STD_PAL_B1, "PAL-B1" },
57*4882a593Smuzhiyun { V4L2_STD_PAL_G, "PAL-G" },
58*4882a593Smuzhiyun { V4L2_STD_PAL_H, "PAL-H" },
59*4882a593Smuzhiyun { V4L2_STD_PAL_I, "PAL-I" },
60*4882a593Smuzhiyun { V4L2_STD_PAL_DK, "PAL-DK" },
61*4882a593Smuzhiyun { V4L2_STD_PAL_D, "PAL-D" },
62*4882a593Smuzhiyun { V4L2_STD_PAL_D1, "PAL-D1" },
63*4882a593Smuzhiyun { V4L2_STD_PAL_K, "PAL-K" },
64*4882a593Smuzhiyun { V4L2_STD_PAL_M, "PAL-M" },
65*4882a593Smuzhiyun { V4L2_STD_PAL_N, "PAL-N" },
66*4882a593Smuzhiyun { V4L2_STD_PAL_Nc, "PAL-Nc" },
67*4882a593Smuzhiyun { V4L2_STD_PAL_60, "PAL-60" },
68*4882a593Smuzhiyun { V4L2_STD_SECAM, "SECAM" },
69*4882a593Smuzhiyun { V4L2_STD_SECAM_B, "SECAM-B" },
70*4882a593Smuzhiyun { V4L2_STD_SECAM_G, "SECAM-G" },
71*4882a593Smuzhiyun { V4L2_STD_SECAM_H, "SECAM-H" },
72*4882a593Smuzhiyun { V4L2_STD_SECAM_DK, "SECAM-DK" },
73*4882a593Smuzhiyun { V4L2_STD_SECAM_D, "SECAM-D" },
74*4882a593Smuzhiyun { V4L2_STD_SECAM_K, "SECAM-K" },
75*4882a593Smuzhiyun { V4L2_STD_SECAM_K1, "SECAM-K1" },
76*4882a593Smuzhiyun { V4L2_STD_SECAM_L, "SECAM-L" },
77*4882a593Smuzhiyun { V4L2_STD_SECAM_LC, "SECAM-Lc" },
78*4882a593Smuzhiyun { 0, "Unknown" }
79*4882a593Smuzhiyun };
80*4882a593Smuzhiyun
clear_reserved(struct v4l2_format * p)81*4882a593Smuzhiyun static void clear_reserved(struct v4l2_format *p)
82*4882a593Smuzhiyun {
83*4882a593Smuzhiyun int ret = 0;
84*4882a593Smuzhiyun
85*4882a593Smuzhiyun trace_android_vh_clear_reserved_fmt_fields(p, &ret);
86*4882a593Smuzhiyun if (!ret)
87*4882a593Smuzhiyun CLEAR_AFTER_FIELD(p, fmt.pix_mp.xfer_func);
88*4882a593Smuzhiyun }
89*4882a593Smuzhiyun
90*4882a593Smuzhiyun /* video4linux standard ID conversion to standard name
91*4882a593Smuzhiyun */
v4l2_norm_to_name(v4l2_std_id id)92*4882a593Smuzhiyun const char *v4l2_norm_to_name(v4l2_std_id id)
93*4882a593Smuzhiyun {
94*4882a593Smuzhiyun u32 myid = id;
95*4882a593Smuzhiyun int i;
96*4882a593Smuzhiyun
97*4882a593Smuzhiyun /* HACK: ppc32 architecture doesn't have __ucmpdi2 function to handle
98*4882a593Smuzhiyun 64 bit comparisons. So, on that architecture, with some gcc
99*4882a593Smuzhiyun variants, compilation fails. Currently, the max value is 30bit wide.
100*4882a593Smuzhiyun */
101*4882a593Smuzhiyun BUG_ON(myid != id);
102*4882a593Smuzhiyun
103*4882a593Smuzhiyun for (i = 0; standards[i].std; i++)
104*4882a593Smuzhiyun if (myid == standards[i].std)
105*4882a593Smuzhiyun break;
106*4882a593Smuzhiyun return standards[i].descr;
107*4882a593Smuzhiyun }
108*4882a593Smuzhiyun EXPORT_SYMBOL(v4l2_norm_to_name);
109*4882a593Smuzhiyun
110*4882a593Smuzhiyun /* Returns frame period for the given standard */
v4l2_video_std_frame_period(int id,struct v4l2_fract * frameperiod)111*4882a593Smuzhiyun void v4l2_video_std_frame_period(int id, struct v4l2_fract *frameperiod)
112*4882a593Smuzhiyun {
113*4882a593Smuzhiyun if (id & V4L2_STD_525_60) {
114*4882a593Smuzhiyun frameperiod->numerator = 1001;
115*4882a593Smuzhiyun frameperiod->denominator = 30000;
116*4882a593Smuzhiyun } else {
117*4882a593Smuzhiyun frameperiod->numerator = 1;
118*4882a593Smuzhiyun frameperiod->denominator = 25;
119*4882a593Smuzhiyun }
120*4882a593Smuzhiyun }
121*4882a593Smuzhiyun EXPORT_SYMBOL(v4l2_video_std_frame_period);
122*4882a593Smuzhiyun
123*4882a593Smuzhiyun /* Fill in the fields of a v4l2_standard structure according to the
124*4882a593Smuzhiyun 'id' and 'transmission' parameters. Returns negative on error. */
v4l2_video_std_construct(struct v4l2_standard * vs,int id,const char * name)125*4882a593Smuzhiyun int v4l2_video_std_construct(struct v4l2_standard *vs,
126*4882a593Smuzhiyun int id, const char *name)
127*4882a593Smuzhiyun {
128*4882a593Smuzhiyun vs->id = id;
129*4882a593Smuzhiyun v4l2_video_std_frame_period(id, &vs->frameperiod);
130*4882a593Smuzhiyun vs->framelines = (id & V4L2_STD_525_60) ? 525 : 625;
131*4882a593Smuzhiyun strscpy(vs->name, name, sizeof(vs->name));
132*4882a593Smuzhiyun return 0;
133*4882a593Smuzhiyun }
134*4882a593Smuzhiyun EXPORT_SYMBOL(v4l2_video_std_construct);
135*4882a593Smuzhiyun
136*4882a593Smuzhiyun /* Fill in the fields of a v4l2_standard structure according to the
137*4882a593Smuzhiyun * 'id' and 'vs->index' parameters. Returns negative on error. */
v4l_video_std_enumstd(struct v4l2_standard * vs,v4l2_std_id id)138*4882a593Smuzhiyun int v4l_video_std_enumstd(struct v4l2_standard *vs, v4l2_std_id id)
139*4882a593Smuzhiyun {
140*4882a593Smuzhiyun v4l2_std_id curr_id = 0;
141*4882a593Smuzhiyun unsigned int index = vs->index, i, j = 0;
142*4882a593Smuzhiyun const char *descr = "";
143*4882a593Smuzhiyun
144*4882a593Smuzhiyun /* Return -ENODATA if the id for the current input
145*4882a593Smuzhiyun or output is 0, meaning that it doesn't support this API. */
146*4882a593Smuzhiyun if (id == 0)
147*4882a593Smuzhiyun return -ENODATA;
148*4882a593Smuzhiyun
149*4882a593Smuzhiyun /* Return norm array in a canonical way */
150*4882a593Smuzhiyun for (i = 0; i <= index && id; i++) {
151*4882a593Smuzhiyun /* last std value in the standards array is 0, so this
152*4882a593Smuzhiyun while always ends there since (id & 0) == 0. */
153*4882a593Smuzhiyun while ((id & standards[j].std) != standards[j].std)
154*4882a593Smuzhiyun j++;
155*4882a593Smuzhiyun curr_id = standards[j].std;
156*4882a593Smuzhiyun descr = standards[j].descr;
157*4882a593Smuzhiyun j++;
158*4882a593Smuzhiyun if (curr_id == 0)
159*4882a593Smuzhiyun break;
160*4882a593Smuzhiyun if (curr_id != V4L2_STD_PAL &&
161*4882a593Smuzhiyun curr_id != V4L2_STD_SECAM &&
162*4882a593Smuzhiyun curr_id != V4L2_STD_NTSC)
163*4882a593Smuzhiyun id &= ~curr_id;
164*4882a593Smuzhiyun }
165*4882a593Smuzhiyun if (i <= index)
166*4882a593Smuzhiyun return -EINVAL;
167*4882a593Smuzhiyun
168*4882a593Smuzhiyun v4l2_video_std_construct(vs, curr_id, descr);
169*4882a593Smuzhiyun return 0;
170*4882a593Smuzhiyun }
171*4882a593Smuzhiyun
172*4882a593Smuzhiyun /* ----------------------------------------------------------------- */
173*4882a593Smuzhiyun /* some arrays for pretty-printing debug messages of enum types */
174*4882a593Smuzhiyun
175*4882a593Smuzhiyun const char *v4l2_field_names[] = {
176*4882a593Smuzhiyun [V4L2_FIELD_ANY] = "any",
177*4882a593Smuzhiyun [V4L2_FIELD_NONE] = "none",
178*4882a593Smuzhiyun [V4L2_FIELD_TOP] = "top",
179*4882a593Smuzhiyun [V4L2_FIELD_BOTTOM] = "bottom",
180*4882a593Smuzhiyun [V4L2_FIELD_INTERLACED] = "interlaced",
181*4882a593Smuzhiyun [V4L2_FIELD_SEQ_TB] = "seq-tb",
182*4882a593Smuzhiyun [V4L2_FIELD_SEQ_BT] = "seq-bt",
183*4882a593Smuzhiyun [V4L2_FIELD_ALTERNATE] = "alternate",
184*4882a593Smuzhiyun [V4L2_FIELD_INTERLACED_TB] = "interlaced-tb",
185*4882a593Smuzhiyun [V4L2_FIELD_INTERLACED_BT] = "interlaced-bt",
186*4882a593Smuzhiyun };
187*4882a593Smuzhiyun EXPORT_SYMBOL(v4l2_field_names);
188*4882a593Smuzhiyun
189*4882a593Smuzhiyun const char *v4l2_type_names[] = {
190*4882a593Smuzhiyun [0] = "0",
191*4882a593Smuzhiyun [V4L2_BUF_TYPE_VIDEO_CAPTURE] = "vid-cap",
192*4882a593Smuzhiyun [V4L2_BUF_TYPE_VIDEO_OVERLAY] = "vid-overlay",
193*4882a593Smuzhiyun [V4L2_BUF_TYPE_VIDEO_OUTPUT] = "vid-out",
194*4882a593Smuzhiyun [V4L2_BUF_TYPE_VBI_CAPTURE] = "vbi-cap",
195*4882a593Smuzhiyun [V4L2_BUF_TYPE_VBI_OUTPUT] = "vbi-out",
196*4882a593Smuzhiyun [V4L2_BUF_TYPE_SLICED_VBI_CAPTURE] = "sliced-vbi-cap",
197*4882a593Smuzhiyun [V4L2_BUF_TYPE_SLICED_VBI_OUTPUT] = "sliced-vbi-out",
198*4882a593Smuzhiyun [V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY] = "vid-out-overlay",
199*4882a593Smuzhiyun [V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE] = "vid-cap-mplane",
200*4882a593Smuzhiyun [V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE] = "vid-out-mplane",
201*4882a593Smuzhiyun [V4L2_BUF_TYPE_SDR_CAPTURE] = "sdr-cap",
202*4882a593Smuzhiyun [V4L2_BUF_TYPE_SDR_OUTPUT] = "sdr-out",
203*4882a593Smuzhiyun [V4L2_BUF_TYPE_META_CAPTURE] = "meta-cap",
204*4882a593Smuzhiyun [V4L2_BUF_TYPE_META_OUTPUT] = "meta-out",
205*4882a593Smuzhiyun };
206*4882a593Smuzhiyun EXPORT_SYMBOL(v4l2_type_names);
207*4882a593Smuzhiyun
208*4882a593Smuzhiyun static const char *v4l2_memory_names[] = {
209*4882a593Smuzhiyun [V4L2_MEMORY_MMAP] = "mmap",
210*4882a593Smuzhiyun [V4L2_MEMORY_USERPTR] = "userptr",
211*4882a593Smuzhiyun [V4L2_MEMORY_OVERLAY] = "overlay",
212*4882a593Smuzhiyun [V4L2_MEMORY_DMABUF] = "dmabuf",
213*4882a593Smuzhiyun };
214*4882a593Smuzhiyun
215*4882a593Smuzhiyun #define prt_names(a, arr) (((unsigned)(a)) < ARRAY_SIZE(arr) ? arr[a] : "unknown")
216*4882a593Smuzhiyun
217*4882a593Smuzhiyun /* ------------------------------------------------------------------ */
218*4882a593Smuzhiyun /* debug help functions */
219*4882a593Smuzhiyun
v4l_print_querycap(const void * arg,bool write_only)220*4882a593Smuzhiyun static void v4l_print_querycap(const void *arg, bool write_only)
221*4882a593Smuzhiyun {
222*4882a593Smuzhiyun const struct v4l2_capability *p = arg;
223*4882a593Smuzhiyun
224*4882a593Smuzhiyun pr_cont("driver=%.*s, card=%.*s, bus=%.*s, version=0x%08x, capabilities=0x%08x, device_caps=0x%08x\n",
225*4882a593Smuzhiyun (int)sizeof(p->driver), p->driver,
226*4882a593Smuzhiyun (int)sizeof(p->card), p->card,
227*4882a593Smuzhiyun (int)sizeof(p->bus_info), p->bus_info,
228*4882a593Smuzhiyun p->version, p->capabilities, p->device_caps);
229*4882a593Smuzhiyun }
230*4882a593Smuzhiyun
v4l_print_enuminput(const void * arg,bool write_only)231*4882a593Smuzhiyun static void v4l_print_enuminput(const void *arg, bool write_only)
232*4882a593Smuzhiyun {
233*4882a593Smuzhiyun const struct v4l2_input *p = arg;
234*4882a593Smuzhiyun
235*4882a593Smuzhiyun pr_cont("index=%u, name=%.*s, type=%u, audioset=0x%x, tuner=%u, std=0x%08Lx, status=0x%x, capabilities=0x%x\n",
236*4882a593Smuzhiyun p->index, (int)sizeof(p->name), p->name, p->type, p->audioset,
237*4882a593Smuzhiyun p->tuner, (unsigned long long)p->std, p->status,
238*4882a593Smuzhiyun p->capabilities);
239*4882a593Smuzhiyun }
240*4882a593Smuzhiyun
v4l_print_enumoutput(const void * arg,bool write_only)241*4882a593Smuzhiyun static void v4l_print_enumoutput(const void *arg, bool write_only)
242*4882a593Smuzhiyun {
243*4882a593Smuzhiyun const struct v4l2_output *p = arg;
244*4882a593Smuzhiyun
245*4882a593Smuzhiyun pr_cont("index=%u, name=%.*s, type=%u, audioset=0x%x, modulator=%u, std=0x%08Lx, capabilities=0x%x\n",
246*4882a593Smuzhiyun p->index, (int)sizeof(p->name), p->name, p->type, p->audioset,
247*4882a593Smuzhiyun p->modulator, (unsigned long long)p->std, p->capabilities);
248*4882a593Smuzhiyun }
249*4882a593Smuzhiyun
v4l_print_audio(const void * arg,bool write_only)250*4882a593Smuzhiyun static void v4l_print_audio(const void *arg, bool write_only)
251*4882a593Smuzhiyun {
252*4882a593Smuzhiyun const struct v4l2_audio *p = arg;
253*4882a593Smuzhiyun
254*4882a593Smuzhiyun if (write_only)
255*4882a593Smuzhiyun pr_cont("index=%u, mode=0x%x\n", p->index, p->mode);
256*4882a593Smuzhiyun else
257*4882a593Smuzhiyun pr_cont("index=%u, name=%.*s, capability=0x%x, mode=0x%x\n",
258*4882a593Smuzhiyun p->index, (int)sizeof(p->name), p->name,
259*4882a593Smuzhiyun p->capability, p->mode);
260*4882a593Smuzhiyun }
261*4882a593Smuzhiyun
v4l_print_audioout(const void * arg,bool write_only)262*4882a593Smuzhiyun static void v4l_print_audioout(const void *arg, bool write_only)
263*4882a593Smuzhiyun {
264*4882a593Smuzhiyun const struct v4l2_audioout *p = arg;
265*4882a593Smuzhiyun
266*4882a593Smuzhiyun if (write_only)
267*4882a593Smuzhiyun pr_cont("index=%u\n", p->index);
268*4882a593Smuzhiyun else
269*4882a593Smuzhiyun pr_cont("index=%u, name=%.*s, capability=0x%x, mode=0x%x\n",
270*4882a593Smuzhiyun p->index, (int)sizeof(p->name), p->name,
271*4882a593Smuzhiyun p->capability, p->mode);
272*4882a593Smuzhiyun }
273*4882a593Smuzhiyun
v4l_print_fmtdesc(const void * arg,bool write_only)274*4882a593Smuzhiyun static void v4l_print_fmtdesc(const void *arg, bool write_only)
275*4882a593Smuzhiyun {
276*4882a593Smuzhiyun const struct v4l2_fmtdesc *p = arg;
277*4882a593Smuzhiyun
278*4882a593Smuzhiyun pr_cont("index=%u, type=%s, flags=0x%x, pixelformat=%c%c%c%c, mbus_code=0x%04x, description='%.*s'\n",
279*4882a593Smuzhiyun p->index, prt_names(p->type, v4l2_type_names),
280*4882a593Smuzhiyun p->flags, (p->pixelformat & 0xff),
281*4882a593Smuzhiyun (p->pixelformat >> 8) & 0xff,
282*4882a593Smuzhiyun (p->pixelformat >> 16) & 0xff,
283*4882a593Smuzhiyun (p->pixelformat >> 24) & 0xff,
284*4882a593Smuzhiyun p->mbus_code,
285*4882a593Smuzhiyun (int)sizeof(p->description), p->description);
286*4882a593Smuzhiyun }
287*4882a593Smuzhiyun
v4l_print_format(const void * arg,bool write_only)288*4882a593Smuzhiyun static void v4l_print_format(const void *arg, bool write_only)
289*4882a593Smuzhiyun {
290*4882a593Smuzhiyun const struct v4l2_format *p = arg;
291*4882a593Smuzhiyun const struct v4l2_pix_format *pix;
292*4882a593Smuzhiyun const struct v4l2_pix_format_mplane *mp;
293*4882a593Smuzhiyun const struct v4l2_vbi_format *vbi;
294*4882a593Smuzhiyun const struct v4l2_sliced_vbi_format *sliced;
295*4882a593Smuzhiyun const struct v4l2_window *win;
296*4882a593Smuzhiyun const struct v4l2_sdr_format *sdr;
297*4882a593Smuzhiyun const struct v4l2_meta_format *meta;
298*4882a593Smuzhiyun u32 planes;
299*4882a593Smuzhiyun unsigned i;
300*4882a593Smuzhiyun
301*4882a593Smuzhiyun pr_cont("type=%s", prt_names(p->type, v4l2_type_names));
302*4882a593Smuzhiyun switch (p->type) {
303*4882a593Smuzhiyun case V4L2_BUF_TYPE_VIDEO_CAPTURE:
304*4882a593Smuzhiyun case V4L2_BUF_TYPE_VIDEO_OUTPUT:
305*4882a593Smuzhiyun pix = &p->fmt.pix;
306*4882a593Smuzhiyun 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",
307*4882a593Smuzhiyun pix->width, pix->height,
308*4882a593Smuzhiyun (pix->pixelformat & 0xff),
309*4882a593Smuzhiyun (pix->pixelformat >> 8) & 0xff,
310*4882a593Smuzhiyun (pix->pixelformat >> 16) & 0xff,
311*4882a593Smuzhiyun (pix->pixelformat >> 24) & 0xff,
312*4882a593Smuzhiyun prt_names(pix->field, v4l2_field_names),
313*4882a593Smuzhiyun pix->bytesperline, pix->sizeimage,
314*4882a593Smuzhiyun pix->colorspace, pix->flags, pix->ycbcr_enc,
315*4882a593Smuzhiyun pix->quantization, pix->xfer_func);
316*4882a593Smuzhiyun break;
317*4882a593Smuzhiyun case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
318*4882a593Smuzhiyun case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
319*4882a593Smuzhiyun mp = &p->fmt.pix_mp;
320*4882a593Smuzhiyun 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",
321*4882a593Smuzhiyun mp->width, mp->height,
322*4882a593Smuzhiyun (mp->pixelformat & 0xff),
323*4882a593Smuzhiyun (mp->pixelformat >> 8) & 0xff,
324*4882a593Smuzhiyun (mp->pixelformat >> 16) & 0xff,
325*4882a593Smuzhiyun (mp->pixelformat >> 24) & 0xff,
326*4882a593Smuzhiyun prt_names(mp->field, v4l2_field_names),
327*4882a593Smuzhiyun mp->colorspace, mp->num_planes, mp->flags,
328*4882a593Smuzhiyun mp->ycbcr_enc, mp->quantization, mp->xfer_func);
329*4882a593Smuzhiyun planes = min_t(u32, mp->num_planes, VIDEO_MAX_PLANES);
330*4882a593Smuzhiyun for (i = 0; i < planes; i++)
331*4882a593Smuzhiyun printk(KERN_DEBUG "plane %u: bytesperline=%u sizeimage=%u\n", i,
332*4882a593Smuzhiyun mp->plane_fmt[i].bytesperline,
333*4882a593Smuzhiyun mp->plane_fmt[i].sizeimage);
334*4882a593Smuzhiyun break;
335*4882a593Smuzhiyun case V4L2_BUF_TYPE_VIDEO_OVERLAY:
336*4882a593Smuzhiyun case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
337*4882a593Smuzhiyun win = &p->fmt.win;
338*4882a593Smuzhiyun /* Note: we can't print the clip list here since the clips
339*4882a593Smuzhiyun * pointer is a userspace pointer, not a kernelspace
340*4882a593Smuzhiyun * pointer. */
341*4882a593Smuzhiyun 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",
342*4882a593Smuzhiyun win->w.width, win->w.height, win->w.left, win->w.top,
343*4882a593Smuzhiyun prt_names(win->field, v4l2_field_names),
344*4882a593Smuzhiyun win->chromakey, win->clipcount, win->clips,
345*4882a593Smuzhiyun win->bitmap, win->global_alpha);
346*4882a593Smuzhiyun break;
347*4882a593Smuzhiyun case V4L2_BUF_TYPE_VBI_CAPTURE:
348*4882a593Smuzhiyun case V4L2_BUF_TYPE_VBI_OUTPUT:
349*4882a593Smuzhiyun vbi = &p->fmt.vbi;
350*4882a593Smuzhiyun pr_cont(", sampling_rate=%u, offset=%u, samples_per_line=%u, sample_format=%c%c%c%c, start=%u,%u, count=%u,%u\n",
351*4882a593Smuzhiyun vbi->sampling_rate, vbi->offset,
352*4882a593Smuzhiyun vbi->samples_per_line,
353*4882a593Smuzhiyun (vbi->sample_format & 0xff),
354*4882a593Smuzhiyun (vbi->sample_format >> 8) & 0xff,
355*4882a593Smuzhiyun (vbi->sample_format >> 16) & 0xff,
356*4882a593Smuzhiyun (vbi->sample_format >> 24) & 0xff,
357*4882a593Smuzhiyun vbi->start[0], vbi->start[1],
358*4882a593Smuzhiyun vbi->count[0], vbi->count[1]);
359*4882a593Smuzhiyun break;
360*4882a593Smuzhiyun case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
361*4882a593Smuzhiyun case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
362*4882a593Smuzhiyun sliced = &p->fmt.sliced;
363*4882a593Smuzhiyun pr_cont(", service_set=0x%08x, io_size=%d\n",
364*4882a593Smuzhiyun sliced->service_set, sliced->io_size);
365*4882a593Smuzhiyun for (i = 0; i < 24; i++)
366*4882a593Smuzhiyun printk(KERN_DEBUG "line[%02u]=0x%04x, 0x%04x\n", i,
367*4882a593Smuzhiyun sliced->service_lines[0][i],
368*4882a593Smuzhiyun sliced->service_lines[1][i]);
369*4882a593Smuzhiyun break;
370*4882a593Smuzhiyun case V4L2_BUF_TYPE_SDR_CAPTURE:
371*4882a593Smuzhiyun case V4L2_BUF_TYPE_SDR_OUTPUT:
372*4882a593Smuzhiyun sdr = &p->fmt.sdr;
373*4882a593Smuzhiyun pr_cont(", pixelformat=%c%c%c%c\n",
374*4882a593Smuzhiyun (sdr->pixelformat >> 0) & 0xff,
375*4882a593Smuzhiyun (sdr->pixelformat >> 8) & 0xff,
376*4882a593Smuzhiyun (sdr->pixelformat >> 16) & 0xff,
377*4882a593Smuzhiyun (sdr->pixelformat >> 24) & 0xff);
378*4882a593Smuzhiyun break;
379*4882a593Smuzhiyun case V4L2_BUF_TYPE_META_CAPTURE:
380*4882a593Smuzhiyun case V4L2_BUF_TYPE_META_OUTPUT:
381*4882a593Smuzhiyun meta = &p->fmt.meta;
382*4882a593Smuzhiyun pr_cont(", dataformat=%c%c%c%c, buffersize=%u\n",
383*4882a593Smuzhiyun (meta->dataformat >> 0) & 0xff,
384*4882a593Smuzhiyun (meta->dataformat >> 8) & 0xff,
385*4882a593Smuzhiyun (meta->dataformat >> 16) & 0xff,
386*4882a593Smuzhiyun (meta->dataformat >> 24) & 0xff,
387*4882a593Smuzhiyun meta->buffersize);
388*4882a593Smuzhiyun break;
389*4882a593Smuzhiyun }
390*4882a593Smuzhiyun }
391*4882a593Smuzhiyun
v4l_print_framebuffer(const void * arg,bool write_only)392*4882a593Smuzhiyun static void v4l_print_framebuffer(const void *arg, bool write_only)
393*4882a593Smuzhiyun {
394*4882a593Smuzhiyun const struct v4l2_framebuffer *p = arg;
395*4882a593Smuzhiyun
396*4882a593Smuzhiyun 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",
397*4882a593Smuzhiyun p->capability, p->flags, p->base,
398*4882a593Smuzhiyun p->fmt.width, p->fmt.height,
399*4882a593Smuzhiyun (p->fmt.pixelformat & 0xff),
400*4882a593Smuzhiyun (p->fmt.pixelformat >> 8) & 0xff,
401*4882a593Smuzhiyun (p->fmt.pixelformat >> 16) & 0xff,
402*4882a593Smuzhiyun (p->fmt.pixelformat >> 24) & 0xff,
403*4882a593Smuzhiyun p->fmt.bytesperline, p->fmt.sizeimage,
404*4882a593Smuzhiyun p->fmt.colorspace);
405*4882a593Smuzhiyun }
406*4882a593Smuzhiyun
v4l_print_buftype(const void * arg,bool write_only)407*4882a593Smuzhiyun static void v4l_print_buftype(const void *arg, bool write_only)
408*4882a593Smuzhiyun {
409*4882a593Smuzhiyun pr_cont("type=%s\n", prt_names(*(u32 *)arg, v4l2_type_names));
410*4882a593Smuzhiyun }
411*4882a593Smuzhiyun
v4l_print_modulator(const void * arg,bool write_only)412*4882a593Smuzhiyun static void v4l_print_modulator(const void *arg, bool write_only)
413*4882a593Smuzhiyun {
414*4882a593Smuzhiyun const struct v4l2_modulator *p = arg;
415*4882a593Smuzhiyun
416*4882a593Smuzhiyun if (write_only)
417*4882a593Smuzhiyun pr_cont("index=%u, txsubchans=0x%x\n", p->index, p->txsubchans);
418*4882a593Smuzhiyun else
419*4882a593Smuzhiyun pr_cont("index=%u, name=%.*s, capability=0x%x, rangelow=%u, rangehigh=%u, txsubchans=0x%x\n",
420*4882a593Smuzhiyun p->index, (int)sizeof(p->name), p->name, p->capability,
421*4882a593Smuzhiyun p->rangelow, p->rangehigh, p->txsubchans);
422*4882a593Smuzhiyun }
423*4882a593Smuzhiyun
v4l_print_tuner(const void * arg,bool write_only)424*4882a593Smuzhiyun static void v4l_print_tuner(const void *arg, bool write_only)
425*4882a593Smuzhiyun {
426*4882a593Smuzhiyun const struct v4l2_tuner *p = arg;
427*4882a593Smuzhiyun
428*4882a593Smuzhiyun if (write_only)
429*4882a593Smuzhiyun pr_cont("index=%u, audmode=%u\n", p->index, p->audmode);
430*4882a593Smuzhiyun else
431*4882a593Smuzhiyun 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",
432*4882a593Smuzhiyun p->index, (int)sizeof(p->name), p->name, p->type,
433*4882a593Smuzhiyun p->capability, p->rangelow,
434*4882a593Smuzhiyun p->rangehigh, p->signal, p->afc,
435*4882a593Smuzhiyun p->rxsubchans, p->audmode);
436*4882a593Smuzhiyun }
437*4882a593Smuzhiyun
v4l_print_frequency(const void * arg,bool write_only)438*4882a593Smuzhiyun static void v4l_print_frequency(const void *arg, bool write_only)
439*4882a593Smuzhiyun {
440*4882a593Smuzhiyun const struct v4l2_frequency *p = arg;
441*4882a593Smuzhiyun
442*4882a593Smuzhiyun pr_cont("tuner=%u, type=%u, frequency=%u\n",
443*4882a593Smuzhiyun p->tuner, p->type, p->frequency);
444*4882a593Smuzhiyun }
445*4882a593Smuzhiyun
v4l_print_standard(const void * arg,bool write_only)446*4882a593Smuzhiyun static void v4l_print_standard(const void *arg, bool write_only)
447*4882a593Smuzhiyun {
448*4882a593Smuzhiyun const struct v4l2_standard *p = arg;
449*4882a593Smuzhiyun
450*4882a593Smuzhiyun pr_cont("index=%u, id=0x%Lx, name=%.*s, fps=%u/%u, framelines=%u\n",
451*4882a593Smuzhiyun p->index,
452*4882a593Smuzhiyun (unsigned long long)p->id, (int)sizeof(p->name), p->name,
453*4882a593Smuzhiyun p->frameperiod.numerator,
454*4882a593Smuzhiyun p->frameperiod.denominator,
455*4882a593Smuzhiyun p->framelines);
456*4882a593Smuzhiyun }
457*4882a593Smuzhiyun
v4l_print_std(const void * arg,bool write_only)458*4882a593Smuzhiyun static void v4l_print_std(const void *arg, bool write_only)
459*4882a593Smuzhiyun {
460*4882a593Smuzhiyun pr_cont("std=0x%08Lx\n", *(const long long unsigned *)arg);
461*4882a593Smuzhiyun }
462*4882a593Smuzhiyun
v4l_print_hw_freq_seek(const void * arg,bool write_only)463*4882a593Smuzhiyun static void v4l_print_hw_freq_seek(const void *arg, bool write_only)
464*4882a593Smuzhiyun {
465*4882a593Smuzhiyun const struct v4l2_hw_freq_seek *p = arg;
466*4882a593Smuzhiyun
467*4882a593Smuzhiyun pr_cont("tuner=%u, type=%u, seek_upward=%u, wrap_around=%u, spacing=%u, rangelow=%u, rangehigh=%u\n",
468*4882a593Smuzhiyun p->tuner, p->type, p->seek_upward, p->wrap_around, p->spacing,
469*4882a593Smuzhiyun p->rangelow, p->rangehigh);
470*4882a593Smuzhiyun }
471*4882a593Smuzhiyun
v4l_print_requestbuffers(const void * arg,bool write_only)472*4882a593Smuzhiyun static void v4l_print_requestbuffers(const void *arg, bool write_only)
473*4882a593Smuzhiyun {
474*4882a593Smuzhiyun const struct v4l2_requestbuffers *p = arg;
475*4882a593Smuzhiyun
476*4882a593Smuzhiyun pr_cont("count=%d, type=%s, memory=%s\n",
477*4882a593Smuzhiyun p->count,
478*4882a593Smuzhiyun prt_names(p->type, v4l2_type_names),
479*4882a593Smuzhiyun prt_names(p->memory, v4l2_memory_names));
480*4882a593Smuzhiyun }
481*4882a593Smuzhiyun
v4l_print_buffer(const void * arg,bool write_only)482*4882a593Smuzhiyun static void v4l_print_buffer(const void *arg, bool write_only)
483*4882a593Smuzhiyun {
484*4882a593Smuzhiyun const struct v4l2_buffer *p = arg;
485*4882a593Smuzhiyun const struct v4l2_timecode *tc = &p->timecode;
486*4882a593Smuzhiyun const struct v4l2_plane *plane;
487*4882a593Smuzhiyun int i;
488*4882a593Smuzhiyun
489*4882a593Smuzhiyun pr_cont("%02d:%02d:%02d.%09ld index=%d, type=%s, request_fd=%d, flags=0x%08x, field=%s, sequence=%d, memory=%s",
490*4882a593Smuzhiyun (int)p->timestamp.tv_sec / 3600,
491*4882a593Smuzhiyun ((int)p->timestamp.tv_sec / 60) % 60,
492*4882a593Smuzhiyun ((int)p->timestamp.tv_sec % 60),
493*4882a593Smuzhiyun (long)p->timestamp.tv_usec,
494*4882a593Smuzhiyun p->index,
495*4882a593Smuzhiyun prt_names(p->type, v4l2_type_names), p->request_fd,
496*4882a593Smuzhiyun p->flags, prt_names(p->field, v4l2_field_names),
497*4882a593Smuzhiyun p->sequence, prt_names(p->memory, v4l2_memory_names));
498*4882a593Smuzhiyun
499*4882a593Smuzhiyun if (V4L2_TYPE_IS_MULTIPLANAR(p->type) && p->m.planes) {
500*4882a593Smuzhiyun pr_cont("\n");
501*4882a593Smuzhiyun for (i = 0; i < p->length; ++i) {
502*4882a593Smuzhiyun plane = &p->m.planes[i];
503*4882a593Smuzhiyun printk(KERN_DEBUG
504*4882a593Smuzhiyun "plane %d: bytesused=%d, data_offset=0x%08x, offset/userptr=0x%lx, length=%d\n",
505*4882a593Smuzhiyun i, plane->bytesused, plane->data_offset,
506*4882a593Smuzhiyun plane->m.userptr, plane->length);
507*4882a593Smuzhiyun }
508*4882a593Smuzhiyun } else {
509*4882a593Smuzhiyun pr_cont(", bytesused=%d, offset/userptr=0x%lx, length=%d\n",
510*4882a593Smuzhiyun p->bytesused, p->m.userptr, p->length);
511*4882a593Smuzhiyun }
512*4882a593Smuzhiyun
513*4882a593Smuzhiyun printk(KERN_DEBUG "timecode=%02d:%02d:%02d type=%d, flags=0x%08x, frames=%d, userbits=0x%08x\n",
514*4882a593Smuzhiyun tc->hours, tc->minutes, tc->seconds,
515*4882a593Smuzhiyun tc->type, tc->flags, tc->frames, *(__u32 *)tc->userbits);
516*4882a593Smuzhiyun }
517*4882a593Smuzhiyun
v4l_print_exportbuffer(const void * arg,bool write_only)518*4882a593Smuzhiyun static void v4l_print_exportbuffer(const void *arg, bool write_only)
519*4882a593Smuzhiyun {
520*4882a593Smuzhiyun const struct v4l2_exportbuffer *p = arg;
521*4882a593Smuzhiyun
522*4882a593Smuzhiyun pr_cont("fd=%d, type=%s, index=%u, plane=%u, flags=0x%08x\n",
523*4882a593Smuzhiyun p->fd, prt_names(p->type, v4l2_type_names),
524*4882a593Smuzhiyun p->index, p->plane, p->flags);
525*4882a593Smuzhiyun }
526*4882a593Smuzhiyun
v4l_print_create_buffers(const void * arg,bool write_only)527*4882a593Smuzhiyun static void v4l_print_create_buffers(const void *arg, bool write_only)
528*4882a593Smuzhiyun {
529*4882a593Smuzhiyun const struct v4l2_create_buffers *p = arg;
530*4882a593Smuzhiyun
531*4882a593Smuzhiyun pr_cont("index=%d, count=%d, memory=%s, ",
532*4882a593Smuzhiyun p->index, p->count,
533*4882a593Smuzhiyun prt_names(p->memory, v4l2_memory_names));
534*4882a593Smuzhiyun v4l_print_format(&p->format, write_only);
535*4882a593Smuzhiyun }
536*4882a593Smuzhiyun
v4l_print_streamparm(const void * arg,bool write_only)537*4882a593Smuzhiyun static void v4l_print_streamparm(const void *arg, bool write_only)
538*4882a593Smuzhiyun {
539*4882a593Smuzhiyun const struct v4l2_streamparm *p = arg;
540*4882a593Smuzhiyun
541*4882a593Smuzhiyun pr_cont("type=%s", prt_names(p->type, v4l2_type_names));
542*4882a593Smuzhiyun
543*4882a593Smuzhiyun if (p->type == V4L2_BUF_TYPE_VIDEO_CAPTURE ||
544*4882a593Smuzhiyun p->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
545*4882a593Smuzhiyun const struct v4l2_captureparm *c = &p->parm.capture;
546*4882a593Smuzhiyun
547*4882a593Smuzhiyun pr_cont(", capability=0x%x, capturemode=0x%x, timeperframe=%d/%d, extendedmode=%d, readbuffers=%d\n",
548*4882a593Smuzhiyun c->capability, c->capturemode,
549*4882a593Smuzhiyun c->timeperframe.numerator, c->timeperframe.denominator,
550*4882a593Smuzhiyun c->extendedmode, c->readbuffers);
551*4882a593Smuzhiyun } else if (p->type == V4L2_BUF_TYPE_VIDEO_OUTPUT ||
552*4882a593Smuzhiyun p->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
553*4882a593Smuzhiyun const struct v4l2_outputparm *c = &p->parm.output;
554*4882a593Smuzhiyun
555*4882a593Smuzhiyun pr_cont(", capability=0x%x, outputmode=0x%x, timeperframe=%d/%d, extendedmode=%d, writebuffers=%d\n",
556*4882a593Smuzhiyun c->capability, c->outputmode,
557*4882a593Smuzhiyun c->timeperframe.numerator, c->timeperframe.denominator,
558*4882a593Smuzhiyun c->extendedmode, c->writebuffers);
559*4882a593Smuzhiyun } else {
560*4882a593Smuzhiyun pr_cont("\n");
561*4882a593Smuzhiyun }
562*4882a593Smuzhiyun }
563*4882a593Smuzhiyun
v4l_print_queryctrl(const void * arg,bool write_only)564*4882a593Smuzhiyun static void v4l_print_queryctrl(const void *arg, bool write_only)
565*4882a593Smuzhiyun {
566*4882a593Smuzhiyun const struct v4l2_queryctrl *p = arg;
567*4882a593Smuzhiyun
568*4882a593Smuzhiyun pr_cont("id=0x%x, type=%d, name=%.*s, min/max=%d/%d, step=%d, default=%d, flags=0x%08x\n",
569*4882a593Smuzhiyun p->id, p->type, (int)sizeof(p->name), p->name,
570*4882a593Smuzhiyun p->minimum, p->maximum,
571*4882a593Smuzhiyun p->step, p->default_value, p->flags);
572*4882a593Smuzhiyun }
573*4882a593Smuzhiyun
v4l_print_query_ext_ctrl(const void * arg,bool write_only)574*4882a593Smuzhiyun static void v4l_print_query_ext_ctrl(const void *arg, bool write_only)
575*4882a593Smuzhiyun {
576*4882a593Smuzhiyun const struct v4l2_query_ext_ctrl *p = arg;
577*4882a593Smuzhiyun
578*4882a593Smuzhiyun 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",
579*4882a593Smuzhiyun p->id, p->type, (int)sizeof(p->name), p->name,
580*4882a593Smuzhiyun p->minimum, p->maximum,
581*4882a593Smuzhiyun p->step, p->default_value, p->flags,
582*4882a593Smuzhiyun p->elem_size, p->elems, p->nr_of_dims,
583*4882a593Smuzhiyun p->dims[0], p->dims[1], p->dims[2], p->dims[3]);
584*4882a593Smuzhiyun }
585*4882a593Smuzhiyun
v4l_print_querymenu(const void * arg,bool write_only)586*4882a593Smuzhiyun static void v4l_print_querymenu(const void *arg, bool write_only)
587*4882a593Smuzhiyun {
588*4882a593Smuzhiyun const struct v4l2_querymenu *p = arg;
589*4882a593Smuzhiyun
590*4882a593Smuzhiyun pr_cont("id=0x%x, index=%d\n", p->id, p->index);
591*4882a593Smuzhiyun }
592*4882a593Smuzhiyun
v4l_print_control(const void * arg,bool write_only)593*4882a593Smuzhiyun static void v4l_print_control(const void *arg, bool write_only)
594*4882a593Smuzhiyun {
595*4882a593Smuzhiyun const struct v4l2_control *p = arg;
596*4882a593Smuzhiyun const char *name = v4l2_ctrl_get_name(p->id);
597*4882a593Smuzhiyun
598*4882a593Smuzhiyun if (name)
599*4882a593Smuzhiyun pr_cont("name=%s, ", name);
600*4882a593Smuzhiyun pr_cont("id=0x%x, value=%d\n", p->id, p->value);
601*4882a593Smuzhiyun }
602*4882a593Smuzhiyun
v4l_print_ext_controls(const void * arg,bool write_only)603*4882a593Smuzhiyun static void v4l_print_ext_controls(const void *arg, bool write_only)
604*4882a593Smuzhiyun {
605*4882a593Smuzhiyun const struct v4l2_ext_controls *p = arg;
606*4882a593Smuzhiyun int i;
607*4882a593Smuzhiyun
608*4882a593Smuzhiyun pr_cont("which=0x%x, count=%d, error_idx=%d, request_fd=%d",
609*4882a593Smuzhiyun p->which, p->count, p->error_idx, p->request_fd);
610*4882a593Smuzhiyun for (i = 0; i < p->count; i++) {
611*4882a593Smuzhiyun unsigned int id = p->controls[i].id;
612*4882a593Smuzhiyun const char *name = v4l2_ctrl_get_name(id);
613*4882a593Smuzhiyun
614*4882a593Smuzhiyun if (name)
615*4882a593Smuzhiyun pr_cont(", name=%s", name);
616*4882a593Smuzhiyun if (!p->controls[i].size)
617*4882a593Smuzhiyun pr_cont(", id/val=0x%x/0x%x", id, p->controls[i].value);
618*4882a593Smuzhiyun else
619*4882a593Smuzhiyun pr_cont(", id/size=0x%x/%u", id, p->controls[i].size);
620*4882a593Smuzhiyun }
621*4882a593Smuzhiyun pr_cont("\n");
622*4882a593Smuzhiyun }
623*4882a593Smuzhiyun
v4l_print_cropcap(const void * arg,bool write_only)624*4882a593Smuzhiyun static void v4l_print_cropcap(const void *arg, bool write_only)
625*4882a593Smuzhiyun {
626*4882a593Smuzhiyun const struct v4l2_cropcap *p = arg;
627*4882a593Smuzhiyun
628*4882a593Smuzhiyun pr_cont("type=%s, bounds wxh=%dx%d, x,y=%d,%d, defrect wxh=%dx%d, x,y=%d,%d, pixelaspect %d/%d\n",
629*4882a593Smuzhiyun prt_names(p->type, v4l2_type_names),
630*4882a593Smuzhiyun p->bounds.width, p->bounds.height,
631*4882a593Smuzhiyun p->bounds.left, p->bounds.top,
632*4882a593Smuzhiyun p->defrect.width, p->defrect.height,
633*4882a593Smuzhiyun p->defrect.left, p->defrect.top,
634*4882a593Smuzhiyun p->pixelaspect.numerator, p->pixelaspect.denominator);
635*4882a593Smuzhiyun }
636*4882a593Smuzhiyun
v4l_print_crop(const void * arg,bool write_only)637*4882a593Smuzhiyun static void v4l_print_crop(const void *arg, bool write_only)
638*4882a593Smuzhiyun {
639*4882a593Smuzhiyun const struct v4l2_crop *p = arg;
640*4882a593Smuzhiyun
641*4882a593Smuzhiyun pr_cont("type=%s, wxh=%dx%d, x,y=%d,%d\n",
642*4882a593Smuzhiyun prt_names(p->type, v4l2_type_names),
643*4882a593Smuzhiyun p->c.width, p->c.height,
644*4882a593Smuzhiyun p->c.left, p->c.top);
645*4882a593Smuzhiyun }
646*4882a593Smuzhiyun
v4l_print_selection(const void * arg,bool write_only)647*4882a593Smuzhiyun static void v4l_print_selection(const void *arg, bool write_only)
648*4882a593Smuzhiyun {
649*4882a593Smuzhiyun const struct v4l2_selection *p = arg;
650*4882a593Smuzhiyun
651*4882a593Smuzhiyun pr_cont("type=%s, target=%d, flags=0x%x, wxh=%dx%d, x,y=%d,%d\n",
652*4882a593Smuzhiyun prt_names(p->type, v4l2_type_names),
653*4882a593Smuzhiyun p->target, p->flags,
654*4882a593Smuzhiyun p->r.width, p->r.height, p->r.left, p->r.top);
655*4882a593Smuzhiyun }
656*4882a593Smuzhiyun
v4l_print_jpegcompression(const void * arg,bool write_only)657*4882a593Smuzhiyun static void v4l_print_jpegcompression(const void *arg, bool write_only)
658*4882a593Smuzhiyun {
659*4882a593Smuzhiyun const struct v4l2_jpegcompression *p = arg;
660*4882a593Smuzhiyun
661*4882a593Smuzhiyun pr_cont("quality=%d, APPn=%d, APP_len=%d, COM_len=%d, jpeg_markers=0x%x\n",
662*4882a593Smuzhiyun p->quality, p->APPn, p->APP_len,
663*4882a593Smuzhiyun p->COM_len, p->jpeg_markers);
664*4882a593Smuzhiyun }
665*4882a593Smuzhiyun
v4l_print_enc_idx(const void * arg,bool write_only)666*4882a593Smuzhiyun static void v4l_print_enc_idx(const void *arg, bool write_only)
667*4882a593Smuzhiyun {
668*4882a593Smuzhiyun const struct v4l2_enc_idx *p = arg;
669*4882a593Smuzhiyun
670*4882a593Smuzhiyun pr_cont("entries=%d, entries_cap=%d\n",
671*4882a593Smuzhiyun p->entries, p->entries_cap);
672*4882a593Smuzhiyun }
673*4882a593Smuzhiyun
v4l_print_encoder_cmd(const void * arg,bool write_only)674*4882a593Smuzhiyun static void v4l_print_encoder_cmd(const void *arg, bool write_only)
675*4882a593Smuzhiyun {
676*4882a593Smuzhiyun const struct v4l2_encoder_cmd *p = arg;
677*4882a593Smuzhiyun
678*4882a593Smuzhiyun pr_cont("cmd=%d, flags=0x%x\n",
679*4882a593Smuzhiyun p->cmd, p->flags);
680*4882a593Smuzhiyun }
681*4882a593Smuzhiyun
v4l_print_decoder_cmd(const void * arg,bool write_only)682*4882a593Smuzhiyun static void v4l_print_decoder_cmd(const void *arg, bool write_only)
683*4882a593Smuzhiyun {
684*4882a593Smuzhiyun const struct v4l2_decoder_cmd *p = arg;
685*4882a593Smuzhiyun
686*4882a593Smuzhiyun pr_cont("cmd=%d, flags=0x%x\n", p->cmd, p->flags);
687*4882a593Smuzhiyun
688*4882a593Smuzhiyun if (p->cmd == V4L2_DEC_CMD_START)
689*4882a593Smuzhiyun pr_info("speed=%d, format=%u\n",
690*4882a593Smuzhiyun p->start.speed, p->start.format);
691*4882a593Smuzhiyun else if (p->cmd == V4L2_DEC_CMD_STOP)
692*4882a593Smuzhiyun pr_info("pts=%llu\n", p->stop.pts);
693*4882a593Smuzhiyun }
694*4882a593Smuzhiyun
v4l_print_dbg_chip_info(const void * arg,bool write_only)695*4882a593Smuzhiyun static void v4l_print_dbg_chip_info(const void *arg, bool write_only)
696*4882a593Smuzhiyun {
697*4882a593Smuzhiyun const struct v4l2_dbg_chip_info *p = arg;
698*4882a593Smuzhiyun
699*4882a593Smuzhiyun pr_cont("type=%u, ", p->match.type);
700*4882a593Smuzhiyun if (p->match.type == V4L2_CHIP_MATCH_I2C_DRIVER)
701*4882a593Smuzhiyun pr_cont("name=%.*s, ",
702*4882a593Smuzhiyun (int)sizeof(p->match.name), p->match.name);
703*4882a593Smuzhiyun else
704*4882a593Smuzhiyun pr_cont("addr=%u, ", p->match.addr);
705*4882a593Smuzhiyun pr_cont("name=%.*s\n", (int)sizeof(p->name), p->name);
706*4882a593Smuzhiyun }
707*4882a593Smuzhiyun
v4l_print_dbg_register(const void * arg,bool write_only)708*4882a593Smuzhiyun static void v4l_print_dbg_register(const void *arg, bool write_only)
709*4882a593Smuzhiyun {
710*4882a593Smuzhiyun const struct v4l2_dbg_register *p = arg;
711*4882a593Smuzhiyun
712*4882a593Smuzhiyun pr_cont("type=%u, ", p->match.type);
713*4882a593Smuzhiyun if (p->match.type == V4L2_CHIP_MATCH_I2C_DRIVER)
714*4882a593Smuzhiyun pr_cont("name=%.*s, ",
715*4882a593Smuzhiyun (int)sizeof(p->match.name), p->match.name);
716*4882a593Smuzhiyun else
717*4882a593Smuzhiyun pr_cont("addr=%u, ", p->match.addr);
718*4882a593Smuzhiyun pr_cont("reg=0x%llx, val=0x%llx\n",
719*4882a593Smuzhiyun p->reg, p->val);
720*4882a593Smuzhiyun }
721*4882a593Smuzhiyun
v4l_print_dv_timings(const void * arg,bool write_only)722*4882a593Smuzhiyun static void v4l_print_dv_timings(const void *arg, bool write_only)
723*4882a593Smuzhiyun {
724*4882a593Smuzhiyun const struct v4l2_dv_timings *p = arg;
725*4882a593Smuzhiyun
726*4882a593Smuzhiyun switch (p->type) {
727*4882a593Smuzhiyun case V4L2_DV_BT_656_1120:
728*4882a593Smuzhiyun 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",
729*4882a593Smuzhiyun p->bt.interlaced, p->bt.pixelclock,
730*4882a593Smuzhiyun p->bt.width, p->bt.height,
731*4882a593Smuzhiyun p->bt.polarities, p->bt.hfrontporch,
732*4882a593Smuzhiyun p->bt.hsync, p->bt.hbackporch,
733*4882a593Smuzhiyun p->bt.vfrontporch, p->bt.vsync,
734*4882a593Smuzhiyun p->bt.vbackporch, p->bt.il_vfrontporch,
735*4882a593Smuzhiyun p->bt.il_vsync, p->bt.il_vbackporch,
736*4882a593Smuzhiyun p->bt.standards, p->bt.flags);
737*4882a593Smuzhiyun break;
738*4882a593Smuzhiyun default:
739*4882a593Smuzhiyun pr_cont("type=%d\n", p->type);
740*4882a593Smuzhiyun break;
741*4882a593Smuzhiyun }
742*4882a593Smuzhiyun }
743*4882a593Smuzhiyun
v4l_print_enum_dv_timings(const void * arg,bool write_only)744*4882a593Smuzhiyun static void v4l_print_enum_dv_timings(const void *arg, bool write_only)
745*4882a593Smuzhiyun {
746*4882a593Smuzhiyun const struct v4l2_enum_dv_timings *p = arg;
747*4882a593Smuzhiyun
748*4882a593Smuzhiyun pr_cont("index=%u, ", p->index);
749*4882a593Smuzhiyun v4l_print_dv_timings(&p->timings, write_only);
750*4882a593Smuzhiyun }
751*4882a593Smuzhiyun
v4l_print_dv_timings_cap(const void * arg,bool write_only)752*4882a593Smuzhiyun static void v4l_print_dv_timings_cap(const void *arg, bool write_only)
753*4882a593Smuzhiyun {
754*4882a593Smuzhiyun const struct v4l2_dv_timings_cap *p = arg;
755*4882a593Smuzhiyun
756*4882a593Smuzhiyun switch (p->type) {
757*4882a593Smuzhiyun case V4L2_DV_BT_656_1120:
758*4882a593Smuzhiyun pr_cont("type=bt-656/1120, width=%u-%u, height=%u-%u, pixelclock=%llu-%llu, standards=0x%x, capabilities=0x%x\n",
759*4882a593Smuzhiyun p->bt.min_width, p->bt.max_width,
760*4882a593Smuzhiyun p->bt.min_height, p->bt.max_height,
761*4882a593Smuzhiyun p->bt.min_pixelclock, p->bt.max_pixelclock,
762*4882a593Smuzhiyun p->bt.standards, p->bt.capabilities);
763*4882a593Smuzhiyun break;
764*4882a593Smuzhiyun default:
765*4882a593Smuzhiyun pr_cont("type=%u\n", p->type);
766*4882a593Smuzhiyun break;
767*4882a593Smuzhiyun }
768*4882a593Smuzhiyun }
769*4882a593Smuzhiyun
v4l_print_frmsizeenum(const void * arg,bool write_only)770*4882a593Smuzhiyun static void v4l_print_frmsizeenum(const void *arg, bool write_only)
771*4882a593Smuzhiyun {
772*4882a593Smuzhiyun const struct v4l2_frmsizeenum *p = arg;
773*4882a593Smuzhiyun
774*4882a593Smuzhiyun pr_cont("index=%u, pixelformat=%c%c%c%c, type=%u",
775*4882a593Smuzhiyun p->index,
776*4882a593Smuzhiyun (p->pixel_format & 0xff),
777*4882a593Smuzhiyun (p->pixel_format >> 8) & 0xff,
778*4882a593Smuzhiyun (p->pixel_format >> 16) & 0xff,
779*4882a593Smuzhiyun (p->pixel_format >> 24) & 0xff,
780*4882a593Smuzhiyun p->type);
781*4882a593Smuzhiyun switch (p->type) {
782*4882a593Smuzhiyun case V4L2_FRMSIZE_TYPE_DISCRETE:
783*4882a593Smuzhiyun pr_cont(", wxh=%ux%u\n",
784*4882a593Smuzhiyun p->discrete.width, p->discrete.height);
785*4882a593Smuzhiyun break;
786*4882a593Smuzhiyun case V4L2_FRMSIZE_TYPE_STEPWISE:
787*4882a593Smuzhiyun pr_cont(", min=%ux%u, max=%ux%u, step=%ux%u\n",
788*4882a593Smuzhiyun p->stepwise.min_width,
789*4882a593Smuzhiyun p->stepwise.min_height,
790*4882a593Smuzhiyun p->stepwise.max_width,
791*4882a593Smuzhiyun p->stepwise.max_height,
792*4882a593Smuzhiyun p->stepwise.step_width,
793*4882a593Smuzhiyun p->stepwise.step_height);
794*4882a593Smuzhiyun break;
795*4882a593Smuzhiyun case V4L2_FRMSIZE_TYPE_CONTINUOUS:
796*4882a593Smuzhiyun default:
797*4882a593Smuzhiyun pr_cont("\n");
798*4882a593Smuzhiyun break;
799*4882a593Smuzhiyun }
800*4882a593Smuzhiyun }
801*4882a593Smuzhiyun
v4l_print_frmivalenum(const void * arg,bool write_only)802*4882a593Smuzhiyun static void v4l_print_frmivalenum(const void *arg, bool write_only)
803*4882a593Smuzhiyun {
804*4882a593Smuzhiyun const struct v4l2_frmivalenum *p = arg;
805*4882a593Smuzhiyun
806*4882a593Smuzhiyun pr_cont("index=%u, pixelformat=%c%c%c%c, wxh=%ux%u, type=%u",
807*4882a593Smuzhiyun p->index,
808*4882a593Smuzhiyun (p->pixel_format & 0xff),
809*4882a593Smuzhiyun (p->pixel_format >> 8) & 0xff,
810*4882a593Smuzhiyun (p->pixel_format >> 16) & 0xff,
811*4882a593Smuzhiyun (p->pixel_format >> 24) & 0xff,
812*4882a593Smuzhiyun p->width, p->height, p->type);
813*4882a593Smuzhiyun switch (p->type) {
814*4882a593Smuzhiyun case V4L2_FRMIVAL_TYPE_DISCRETE:
815*4882a593Smuzhiyun pr_cont(", fps=%d/%d\n",
816*4882a593Smuzhiyun p->discrete.numerator,
817*4882a593Smuzhiyun p->discrete.denominator);
818*4882a593Smuzhiyun break;
819*4882a593Smuzhiyun case V4L2_FRMIVAL_TYPE_STEPWISE:
820*4882a593Smuzhiyun pr_cont(", min=%d/%d, max=%d/%d, step=%d/%d\n",
821*4882a593Smuzhiyun p->stepwise.min.numerator,
822*4882a593Smuzhiyun p->stepwise.min.denominator,
823*4882a593Smuzhiyun p->stepwise.max.numerator,
824*4882a593Smuzhiyun p->stepwise.max.denominator,
825*4882a593Smuzhiyun p->stepwise.step.numerator,
826*4882a593Smuzhiyun p->stepwise.step.denominator);
827*4882a593Smuzhiyun break;
828*4882a593Smuzhiyun case V4L2_FRMIVAL_TYPE_CONTINUOUS:
829*4882a593Smuzhiyun default:
830*4882a593Smuzhiyun pr_cont("\n");
831*4882a593Smuzhiyun break;
832*4882a593Smuzhiyun }
833*4882a593Smuzhiyun }
834*4882a593Smuzhiyun
v4l_print_event(const void * arg,bool write_only)835*4882a593Smuzhiyun static void v4l_print_event(const void *arg, bool write_only)
836*4882a593Smuzhiyun {
837*4882a593Smuzhiyun const struct v4l2_event *p = arg;
838*4882a593Smuzhiyun const struct v4l2_event_ctrl *c;
839*4882a593Smuzhiyun
840*4882a593Smuzhiyun pr_cont("type=0x%x, pending=%u, sequence=%u, id=%u, timestamp=%llu.%9.9llu\n",
841*4882a593Smuzhiyun p->type, p->pending, p->sequence, p->id,
842*4882a593Smuzhiyun p->timestamp.tv_sec, p->timestamp.tv_nsec);
843*4882a593Smuzhiyun switch (p->type) {
844*4882a593Smuzhiyun case V4L2_EVENT_VSYNC:
845*4882a593Smuzhiyun printk(KERN_DEBUG "field=%s\n",
846*4882a593Smuzhiyun prt_names(p->u.vsync.field, v4l2_field_names));
847*4882a593Smuzhiyun break;
848*4882a593Smuzhiyun case V4L2_EVENT_CTRL:
849*4882a593Smuzhiyun c = &p->u.ctrl;
850*4882a593Smuzhiyun printk(KERN_DEBUG "changes=0x%x, type=%u, ",
851*4882a593Smuzhiyun c->changes, c->type);
852*4882a593Smuzhiyun if (c->type == V4L2_CTRL_TYPE_INTEGER64)
853*4882a593Smuzhiyun pr_cont("value64=%lld, ", c->value64);
854*4882a593Smuzhiyun else
855*4882a593Smuzhiyun pr_cont("value=%d, ", c->value);
856*4882a593Smuzhiyun pr_cont("flags=0x%x, minimum=%d, maximum=%d, step=%d, default_value=%d\n",
857*4882a593Smuzhiyun c->flags, c->minimum, c->maximum,
858*4882a593Smuzhiyun c->step, c->default_value);
859*4882a593Smuzhiyun break;
860*4882a593Smuzhiyun case V4L2_EVENT_FRAME_SYNC:
861*4882a593Smuzhiyun pr_cont("frame_sequence=%u\n",
862*4882a593Smuzhiyun p->u.frame_sync.frame_sequence);
863*4882a593Smuzhiyun break;
864*4882a593Smuzhiyun }
865*4882a593Smuzhiyun }
866*4882a593Smuzhiyun
v4l_print_event_subscription(const void * arg,bool write_only)867*4882a593Smuzhiyun static void v4l_print_event_subscription(const void *arg, bool write_only)
868*4882a593Smuzhiyun {
869*4882a593Smuzhiyun const struct v4l2_event_subscription *p = arg;
870*4882a593Smuzhiyun
871*4882a593Smuzhiyun pr_cont("type=0x%x, id=0x%x, flags=0x%x\n",
872*4882a593Smuzhiyun p->type, p->id, p->flags);
873*4882a593Smuzhiyun }
874*4882a593Smuzhiyun
v4l_print_sliced_vbi_cap(const void * arg,bool write_only)875*4882a593Smuzhiyun static void v4l_print_sliced_vbi_cap(const void *arg, bool write_only)
876*4882a593Smuzhiyun {
877*4882a593Smuzhiyun const struct v4l2_sliced_vbi_cap *p = arg;
878*4882a593Smuzhiyun int i;
879*4882a593Smuzhiyun
880*4882a593Smuzhiyun pr_cont("type=%s, service_set=0x%08x\n",
881*4882a593Smuzhiyun prt_names(p->type, v4l2_type_names), p->service_set);
882*4882a593Smuzhiyun for (i = 0; i < 24; i++)
883*4882a593Smuzhiyun printk(KERN_DEBUG "line[%02u]=0x%04x, 0x%04x\n", i,
884*4882a593Smuzhiyun p->service_lines[0][i],
885*4882a593Smuzhiyun p->service_lines[1][i]);
886*4882a593Smuzhiyun }
887*4882a593Smuzhiyun
v4l_print_freq_band(const void * arg,bool write_only)888*4882a593Smuzhiyun static void v4l_print_freq_band(const void *arg, bool write_only)
889*4882a593Smuzhiyun {
890*4882a593Smuzhiyun const struct v4l2_frequency_band *p = arg;
891*4882a593Smuzhiyun
892*4882a593Smuzhiyun pr_cont("tuner=%u, type=%u, index=%u, capability=0x%x, rangelow=%u, rangehigh=%u, modulation=0x%x\n",
893*4882a593Smuzhiyun p->tuner, p->type, p->index,
894*4882a593Smuzhiyun p->capability, p->rangelow,
895*4882a593Smuzhiyun p->rangehigh, p->modulation);
896*4882a593Smuzhiyun }
897*4882a593Smuzhiyun
v4l_print_edid(const void * arg,bool write_only)898*4882a593Smuzhiyun static void v4l_print_edid(const void *arg, bool write_only)
899*4882a593Smuzhiyun {
900*4882a593Smuzhiyun const struct v4l2_edid *p = arg;
901*4882a593Smuzhiyun
902*4882a593Smuzhiyun pr_cont("pad=%u, start_block=%u, blocks=%u\n",
903*4882a593Smuzhiyun p->pad, p->start_block, p->blocks);
904*4882a593Smuzhiyun }
905*4882a593Smuzhiyun
v4l_print_u32(const void * arg,bool write_only)906*4882a593Smuzhiyun static void v4l_print_u32(const void *arg, bool write_only)
907*4882a593Smuzhiyun {
908*4882a593Smuzhiyun pr_cont("value=%u\n", *(const u32 *)arg);
909*4882a593Smuzhiyun }
910*4882a593Smuzhiyun
v4l_print_newline(const void * arg,bool write_only)911*4882a593Smuzhiyun static void v4l_print_newline(const void *arg, bool write_only)
912*4882a593Smuzhiyun {
913*4882a593Smuzhiyun pr_cont("\n");
914*4882a593Smuzhiyun }
915*4882a593Smuzhiyun
v4l_print_default(const void * arg,bool write_only)916*4882a593Smuzhiyun static void v4l_print_default(const void *arg, bool write_only)
917*4882a593Smuzhiyun {
918*4882a593Smuzhiyun pr_cont("driver-specific ioctl\n");
919*4882a593Smuzhiyun }
920*4882a593Smuzhiyun
check_ext_ctrls(struct v4l2_ext_controls * c,unsigned long ioctl)921*4882a593Smuzhiyun static bool check_ext_ctrls(struct v4l2_ext_controls *c, unsigned long ioctl)
922*4882a593Smuzhiyun {
923*4882a593Smuzhiyun __u32 i;
924*4882a593Smuzhiyun
925*4882a593Smuzhiyun /* zero the reserved fields */
926*4882a593Smuzhiyun c->reserved[0] = 0;
927*4882a593Smuzhiyun for (i = 0; i < c->count; i++)
928*4882a593Smuzhiyun c->controls[i].reserved2[0] = 0;
929*4882a593Smuzhiyun
930*4882a593Smuzhiyun switch (c->which) {
931*4882a593Smuzhiyun case V4L2_CID_PRIVATE_BASE:
932*4882a593Smuzhiyun /*
933*4882a593Smuzhiyun * V4L2_CID_PRIVATE_BASE cannot be used as control class
934*4882a593Smuzhiyun * when using extended controls.
935*4882a593Smuzhiyun * Only when passed in through VIDIOC_G_CTRL and VIDIOC_S_CTRL
936*4882a593Smuzhiyun * is it allowed for backwards compatibility.
937*4882a593Smuzhiyun */
938*4882a593Smuzhiyun if (ioctl == VIDIOC_G_CTRL || ioctl == VIDIOC_S_CTRL)
939*4882a593Smuzhiyun return false;
940*4882a593Smuzhiyun break;
941*4882a593Smuzhiyun case V4L2_CTRL_WHICH_DEF_VAL:
942*4882a593Smuzhiyun /* Default value cannot be changed */
943*4882a593Smuzhiyun if (ioctl == VIDIOC_S_EXT_CTRLS ||
944*4882a593Smuzhiyun ioctl == VIDIOC_TRY_EXT_CTRLS) {
945*4882a593Smuzhiyun c->error_idx = c->count;
946*4882a593Smuzhiyun return false;
947*4882a593Smuzhiyun }
948*4882a593Smuzhiyun return true;
949*4882a593Smuzhiyun case V4L2_CTRL_WHICH_CUR_VAL:
950*4882a593Smuzhiyun return true;
951*4882a593Smuzhiyun case V4L2_CTRL_WHICH_REQUEST_VAL:
952*4882a593Smuzhiyun c->error_idx = c->count;
953*4882a593Smuzhiyun return false;
954*4882a593Smuzhiyun }
955*4882a593Smuzhiyun
956*4882a593Smuzhiyun /* Check that all controls are from the same control class. */
957*4882a593Smuzhiyun for (i = 0; i < c->count; i++) {
958*4882a593Smuzhiyun if (V4L2_CTRL_ID2WHICH(c->controls[i].id) != c->which) {
959*4882a593Smuzhiyun c->error_idx = ioctl == VIDIOC_TRY_EXT_CTRLS ? i :
960*4882a593Smuzhiyun c->count;
961*4882a593Smuzhiyun return false;
962*4882a593Smuzhiyun }
963*4882a593Smuzhiyun }
964*4882a593Smuzhiyun return true;
965*4882a593Smuzhiyun }
966*4882a593Smuzhiyun
check_fmt(struct file * file,enum v4l2_buf_type type)967*4882a593Smuzhiyun static int check_fmt(struct file *file, enum v4l2_buf_type type)
968*4882a593Smuzhiyun {
969*4882a593Smuzhiyun const u32 vid_caps = V4L2_CAP_VIDEO_CAPTURE |
970*4882a593Smuzhiyun V4L2_CAP_VIDEO_CAPTURE_MPLANE |
971*4882a593Smuzhiyun V4L2_CAP_VIDEO_OUTPUT |
972*4882a593Smuzhiyun V4L2_CAP_VIDEO_OUTPUT_MPLANE |
973*4882a593Smuzhiyun V4L2_CAP_VIDEO_M2M | V4L2_CAP_VIDEO_M2M_MPLANE;
974*4882a593Smuzhiyun const u32 meta_caps = V4L2_CAP_META_CAPTURE |
975*4882a593Smuzhiyun V4L2_CAP_META_OUTPUT;
976*4882a593Smuzhiyun struct video_device *vfd = video_devdata(file);
977*4882a593Smuzhiyun const struct v4l2_ioctl_ops *ops = vfd->ioctl_ops;
978*4882a593Smuzhiyun bool is_vid = vfd->vfl_type == VFL_TYPE_VIDEO &&
979*4882a593Smuzhiyun (vfd->device_caps & vid_caps);
980*4882a593Smuzhiyun bool is_vbi = vfd->vfl_type == VFL_TYPE_VBI;
981*4882a593Smuzhiyun bool is_sdr = vfd->vfl_type == VFL_TYPE_SDR;
982*4882a593Smuzhiyun bool is_tch = vfd->vfl_type == VFL_TYPE_TOUCH;
983*4882a593Smuzhiyun bool is_meta = vfd->vfl_type == VFL_TYPE_VIDEO &&
984*4882a593Smuzhiyun (vfd->device_caps & meta_caps);
985*4882a593Smuzhiyun bool is_rx = vfd->vfl_dir != VFL_DIR_TX;
986*4882a593Smuzhiyun bool is_tx = vfd->vfl_dir != VFL_DIR_RX;
987*4882a593Smuzhiyun
988*4882a593Smuzhiyun if (ops == NULL)
989*4882a593Smuzhiyun return -EINVAL;
990*4882a593Smuzhiyun
991*4882a593Smuzhiyun switch (type) {
992*4882a593Smuzhiyun case V4L2_BUF_TYPE_VIDEO_CAPTURE:
993*4882a593Smuzhiyun if ((is_vid || is_tch) && is_rx &&
994*4882a593Smuzhiyun (ops->vidioc_g_fmt_vid_cap || ops->vidioc_g_fmt_vid_cap_mplane))
995*4882a593Smuzhiyun return 0;
996*4882a593Smuzhiyun break;
997*4882a593Smuzhiyun case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
998*4882a593Smuzhiyun if ((is_vid || is_tch) && is_rx && ops->vidioc_g_fmt_vid_cap_mplane)
999*4882a593Smuzhiyun return 0;
1000*4882a593Smuzhiyun break;
1001*4882a593Smuzhiyun case V4L2_BUF_TYPE_VIDEO_OVERLAY:
1002*4882a593Smuzhiyun if (is_vid && is_rx && ops->vidioc_g_fmt_vid_overlay)
1003*4882a593Smuzhiyun return 0;
1004*4882a593Smuzhiyun break;
1005*4882a593Smuzhiyun case V4L2_BUF_TYPE_VIDEO_OUTPUT:
1006*4882a593Smuzhiyun if (is_vid && is_tx &&
1007*4882a593Smuzhiyun (ops->vidioc_g_fmt_vid_out || ops->vidioc_g_fmt_vid_out_mplane))
1008*4882a593Smuzhiyun return 0;
1009*4882a593Smuzhiyun break;
1010*4882a593Smuzhiyun case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
1011*4882a593Smuzhiyun if (is_vid && is_tx && ops->vidioc_g_fmt_vid_out_mplane)
1012*4882a593Smuzhiyun return 0;
1013*4882a593Smuzhiyun break;
1014*4882a593Smuzhiyun case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
1015*4882a593Smuzhiyun if (is_vid && is_tx && ops->vidioc_g_fmt_vid_out_overlay)
1016*4882a593Smuzhiyun return 0;
1017*4882a593Smuzhiyun break;
1018*4882a593Smuzhiyun case V4L2_BUF_TYPE_VBI_CAPTURE:
1019*4882a593Smuzhiyun if (is_vbi && is_rx && ops->vidioc_g_fmt_vbi_cap)
1020*4882a593Smuzhiyun return 0;
1021*4882a593Smuzhiyun break;
1022*4882a593Smuzhiyun case V4L2_BUF_TYPE_VBI_OUTPUT:
1023*4882a593Smuzhiyun if (is_vbi && is_tx && ops->vidioc_g_fmt_vbi_out)
1024*4882a593Smuzhiyun return 0;
1025*4882a593Smuzhiyun break;
1026*4882a593Smuzhiyun case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
1027*4882a593Smuzhiyun if (is_vbi && is_rx && ops->vidioc_g_fmt_sliced_vbi_cap)
1028*4882a593Smuzhiyun return 0;
1029*4882a593Smuzhiyun break;
1030*4882a593Smuzhiyun case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
1031*4882a593Smuzhiyun if (is_vbi && is_tx && ops->vidioc_g_fmt_sliced_vbi_out)
1032*4882a593Smuzhiyun return 0;
1033*4882a593Smuzhiyun break;
1034*4882a593Smuzhiyun case V4L2_BUF_TYPE_SDR_CAPTURE:
1035*4882a593Smuzhiyun if (is_sdr && is_rx && ops->vidioc_g_fmt_sdr_cap)
1036*4882a593Smuzhiyun return 0;
1037*4882a593Smuzhiyun break;
1038*4882a593Smuzhiyun case V4L2_BUF_TYPE_SDR_OUTPUT:
1039*4882a593Smuzhiyun if (is_sdr && is_tx && ops->vidioc_g_fmt_sdr_out)
1040*4882a593Smuzhiyun return 0;
1041*4882a593Smuzhiyun break;
1042*4882a593Smuzhiyun case V4L2_BUF_TYPE_META_CAPTURE:
1043*4882a593Smuzhiyun if (is_meta && is_rx && ops->vidioc_g_fmt_meta_cap)
1044*4882a593Smuzhiyun return 0;
1045*4882a593Smuzhiyun break;
1046*4882a593Smuzhiyun case V4L2_BUF_TYPE_META_OUTPUT:
1047*4882a593Smuzhiyun if (is_meta && is_tx && ops->vidioc_g_fmt_meta_out)
1048*4882a593Smuzhiyun return 0;
1049*4882a593Smuzhiyun break;
1050*4882a593Smuzhiyun default:
1051*4882a593Smuzhiyun break;
1052*4882a593Smuzhiyun }
1053*4882a593Smuzhiyun return -EINVAL;
1054*4882a593Smuzhiyun }
1055*4882a593Smuzhiyun
v4l_sanitize_format(struct v4l2_format * fmt)1056*4882a593Smuzhiyun static void v4l_sanitize_format(struct v4l2_format *fmt)
1057*4882a593Smuzhiyun {
1058*4882a593Smuzhiyun unsigned int offset;
1059*4882a593Smuzhiyun
1060*4882a593Smuzhiyun /* Make sure num_planes is not bogus */
1061*4882a593Smuzhiyun if (fmt->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE ||
1062*4882a593Smuzhiyun fmt->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)
1063*4882a593Smuzhiyun fmt->fmt.pix_mp.num_planes = min_t(u32, fmt->fmt.pix_mp.num_planes,
1064*4882a593Smuzhiyun VIDEO_MAX_PLANES);
1065*4882a593Smuzhiyun
1066*4882a593Smuzhiyun /*
1067*4882a593Smuzhiyun * The v4l2_pix_format structure has been extended with fields that were
1068*4882a593Smuzhiyun * not previously required to be set to zero by applications. The priv
1069*4882a593Smuzhiyun * field, when set to a magic value, indicates the the extended fields
1070*4882a593Smuzhiyun * are valid. Otherwise they will contain undefined values. To simplify
1071*4882a593Smuzhiyun * the API towards drivers zero the extended fields and set the priv
1072*4882a593Smuzhiyun * field to the magic value when the extended pixel format structure
1073*4882a593Smuzhiyun * isn't used by applications.
1074*4882a593Smuzhiyun */
1075*4882a593Smuzhiyun
1076*4882a593Smuzhiyun if (fmt->type != V4L2_BUF_TYPE_VIDEO_CAPTURE &&
1077*4882a593Smuzhiyun fmt->type != V4L2_BUF_TYPE_VIDEO_OUTPUT)
1078*4882a593Smuzhiyun return;
1079*4882a593Smuzhiyun
1080*4882a593Smuzhiyun if (fmt->fmt.pix.priv == V4L2_PIX_FMT_PRIV_MAGIC)
1081*4882a593Smuzhiyun return;
1082*4882a593Smuzhiyun
1083*4882a593Smuzhiyun fmt->fmt.pix.priv = V4L2_PIX_FMT_PRIV_MAGIC;
1084*4882a593Smuzhiyun
1085*4882a593Smuzhiyun offset = offsetof(struct v4l2_pix_format, priv)
1086*4882a593Smuzhiyun + sizeof(fmt->fmt.pix.priv);
1087*4882a593Smuzhiyun memset(((void *)&fmt->fmt.pix) + offset, 0,
1088*4882a593Smuzhiyun sizeof(fmt->fmt.pix) - offset);
1089*4882a593Smuzhiyun }
1090*4882a593Smuzhiyun
v4l_querycap(const struct v4l2_ioctl_ops * ops,struct file * file,void * fh,void * arg)1091*4882a593Smuzhiyun static int v4l_querycap(const struct v4l2_ioctl_ops *ops,
1092*4882a593Smuzhiyun struct file *file, void *fh, void *arg)
1093*4882a593Smuzhiyun {
1094*4882a593Smuzhiyun struct v4l2_capability *cap = (struct v4l2_capability *)arg;
1095*4882a593Smuzhiyun struct video_device *vfd = video_devdata(file);
1096*4882a593Smuzhiyun int ret;
1097*4882a593Smuzhiyun
1098*4882a593Smuzhiyun cap->version = LINUX_VERSION_CODE;
1099*4882a593Smuzhiyun cap->device_caps = vfd->device_caps;
1100*4882a593Smuzhiyun cap->capabilities = vfd->device_caps | V4L2_CAP_DEVICE_CAPS;
1101*4882a593Smuzhiyun
1102*4882a593Smuzhiyun ret = ops->vidioc_querycap(file, fh, cap);
1103*4882a593Smuzhiyun
1104*4882a593Smuzhiyun /*
1105*4882a593Smuzhiyun * Drivers must not change device_caps, so check for this and
1106*4882a593Smuzhiyun * warn if this happened.
1107*4882a593Smuzhiyun */
1108*4882a593Smuzhiyun WARN_ON(cap->device_caps != vfd->device_caps);
1109*4882a593Smuzhiyun /*
1110*4882a593Smuzhiyun * Check that capabilities is a superset of
1111*4882a593Smuzhiyun * vfd->device_caps | V4L2_CAP_DEVICE_CAPS
1112*4882a593Smuzhiyun */
1113*4882a593Smuzhiyun WARN_ON((cap->capabilities &
1114*4882a593Smuzhiyun (vfd->device_caps | V4L2_CAP_DEVICE_CAPS)) !=
1115*4882a593Smuzhiyun (vfd->device_caps | V4L2_CAP_DEVICE_CAPS));
1116*4882a593Smuzhiyun cap->capabilities |= V4L2_CAP_EXT_PIX_FORMAT;
1117*4882a593Smuzhiyun cap->device_caps |= V4L2_CAP_EXT_PIX_FORMAT;
1118*4882a593Smuzhiyun
1119*4882a593Smuzhiyun return ret;
1120*4882a593Smuzhiyun }
1121*4882a593Smuzhiyun
v4l_g_input(const struct v4l2_ioctl_ops * ops,struct file * file,void * fh,void * arg)1122*4882a593Smuzhiyun static int v4l_g_input(const struct v4l2_ioctl_ops *ops,
1123*4882a593Smuzhiyun struct file *file, void *fh, void *arg)
1124*4882a593Smuzhiyun {
1125*4882a593Smuzhiyun struct video_device *vfd = video_devdata(file);
1126*4882a593Smuzhiyun
1127*4882a593Smuzhiyun if (vfd->device_caps & V4L2_CAP_IO_MC) {
1128*4882a593Smuzhiyun *(int *)arg = 0;
1129*4882a593Smuzhiyun return 0;
1130*4882a593Smuzhiyun }
1131*4882a593Smuzhiyun
1132*4882a593Smuzhiyun return ops->vidioc_g_input(file, fh, arg);
1133*4882a593Smuzhiyun }
1134*4882a593Smuzhiyun
v4l_g_output(const struct v4l2_ioctl_ops * ops,struct file * file,void * fh,void * arg)1135*4882a593Smuzhiyun static int v4l_g_output(const struct v4l2_ioctl_ops *ops,
1136*4882a593Smuzhiyun struct file *file, void *fh, void *arg)
1137*4882a593Smuzhiyun {
1138*4882a593Smuzhiyun struct video_device *vfd = video_devdata(file);
1139*4882a593Smuzhiyun
1140*4882a593Smuzhiyun if (vfd->device_caps & V4L2_CAP_IO_MC) {
1141*4882a593Smuzhiyun *(int *)arg = 0;
1142*4882a593Smuzhiyun return 0;
1143*4882a593Smuzhiyun }
1144*4882a593Smuzhiyun
1145*4882a593Smuzhiyun return ops->vidioc_g_output(file, fh, arg);
1146*4882a593Smuzhiyun }
1147*4882a593Smuzhiyun
v4l_s_input(const struct v4l2_ioctl_ops * ops,struct file * file,void * fh,void * arg)1148*4882a593Smuzhiyun static int v4l_s_input(const struct v4l2_ioctl_ops *ops,
1149*4882a593Smuzhiyun struct file *file, void *fh, void *arg)
1150*4882a593Smuzhiyun {
1151*4882a593Smuzhiyun struct video_device *vfd = video_devdata(file);
1152*4882a593Smuzhiyun int ret;
1153*4882a593Smuzhiyun
1154*4882a593Smuzhiyun ret = v4l_enable_media_source(vfd);
1155*4882a593Smuzhiyun if (ret)
1156*4882a593Smuzhiyun return ret;
1157*4882a593Smuzhiyun
1158*4882a593Smuzhiyun if (vfd->device_caps & V4L2_CAP_IO_MC)
1159*4882a593Smuzhiyun return *(int *)arg ? -EINVAL : 0;
1160*4882a593Smuzhiyun
1161*4882a593Smuzhiyun return ops->vidioc_s_input(file, fh, *(unsigned int *)arg);
1162*4882a593Smuzhiyun }
1163*4882a593Smuzhiyun
v4l_s_output(const struct v4l2_ioctl_ops * ops,struct file * file,void * fh,void * arg)1164*4882a593Smuzhiyun static int v4l_s_output(const struct v4l2_ioctl_ops *ops,
1165*4882a593Smuzhiyun struct file *file, void *fh, void *arg)
1166*4882a593Smuzhiyun {
1167*4882a593Smuzhiyun struct video_device *vfd = video_devdata(file);
1168*4882a593Smuzhiyun
1169*4882a593Smuzhiyun if (vfd->device_caps & V4L2_CAP_IO_MC)
1170*4882a593Smuzhiyun return *(int *)arg ? -EINVAL : 0;
1171*4882a593Smuzhiyun
1172*4882a593Smuzhiyun return ops->vidioc_s_output(file, fh, *(unsigned int *)arg);
1173*4882a593Smuzhiyun }
1174*4882a593Smuzhiyun
v4l_g_priority(const struct v4l2_ioctl_ops * ops,struct file * file,void * fh,void * arg)1175*4882a593Smuzhiyun static int v4l_g_priority(const struct v4l2_ioctl_ops *ops,
1176*4882a593Smuzhiyun struct file *file, void *fh, void *arg)
1177*4882a593Smuzhiyun {
1178*4882a593Smuzhiyun struct video_device *vfd;
1179*4882a593Smuzhiyun u32 *p = arg;
1180*4882a593Smuzhiyun
1181*4882a593Smuzhiyun vfd = video_devdata(file);
1182*4882a593Smuzhiyun *p = v4l2_prio_max(vfd->prio);
1183*4882a593Smuzhiyun return 0;
1184*4882a593Smuzhiyun }
1185*4882a593Smuzhiyun
v4l_s_priority(const struct v4l2_ioctl_ops * ops,struct file * file,void * fh,void * arg)1186*4882a593Smuzhiyun static int v4l_s_priority(const struct v4l2_ioctl_ops *ops,
1187*4882a593Smuzhiyun struct file *file, void *fh, void *arg)
1188*4882a593Smuzhiyun {
1189*4882a593Smuzhiyun struct video_device *vfd;
1190*4882a593Smuzhiyun struct v4l2_fh *vfh;
1191*4882a593Smuzhiyun u32 *p = arg;
1192*4882a593Smuzhiyun
1193*4882a593Smuzhiyun vfd = video_devdata(file);
1194*4882a593Smuzhiyun if (!test_bit(V4L2_FL_USES_V4L2_FH, &vfd->flags))
1195*4882a593Smuzhiyun return -ENOTTY;
1196*4882a593Smuzhiyun vfh = file->private_data;
1197*4882a593Smuzhiyun return v4l2_prio_change(vfd->prio, &vfh->prio, *p);
1198*4882a593Smuzhiyun }
1199*4882a593Smuzhiyun
v4l_enuminput(const struct v4l2_ioctl_ops * ops,struct file * file,void * fh,void * arg)1200*4882a593Smuzhiyun static int v4l_enuminput(const struct v4l2_ioctl_ops *ops,
1201*4882a593Smuzhiyun struct file *file, void *fh, void *arg)
1202*4882a593Smuzhiyun {
1203*4882a593Smuzhiyun struct video_device *vfd = video_devdata(file);
1204*4882a593Smuzhiyun struct v4l2_input *p = arg;
1205*4882a593Smuzhiyun
1206*4882a593Smuzhiyun /*
1207*4882a593Smuzhiyun * We set the flags for CAP_DV_TIMINGS &
1208*4882a593Smuzhiyun * CAP_STD here based on ioctl handler provided by the
1209*4882a593Smuzhiyun * driver. If the driver doesn't support these
1210*4882a593Smuzhiyun * for a specific input, it must override these flags.
1211*4882a593Smuzhiyun */
1212*4882a593Smuzhiyun if (is_valid_ioctl(vfd, VIDIOC_S_STD))
1213*4882a593Smuzhiyun p->capabilities |= V4L2_IN_CAP_STD;
1214*4882a593Smuzhiyun
1215*4882a593Smuzhiyun if (vfd->device_caps & V4L2_CAP_IO_MC) {
1216*4882a593Smuzhiyun if (p->index)
1217*4882a593Smuzhiyun return -EINVAL;
1218*4882a593Smuzhiyun strscpy(p->name, vfd->name, sizeof(p->name));
1219*4882a593Smuzhiyun p->type = V4L2_INPUT_TYPE_CAMERA;
1220*4882a593Smuzhiyun return 0;
1221*4882a593Smuzhiyun }
1222*4882a593Smuzhiyun
1223*4882a593Smuzhiyun return ops->vidioc_enum_input(file, fh, p);
1224*4882a593Smuzhiyun }
1225*4882a593Smuzhiyun
v4l_enumoutput(const struct v4l2_ioctl_ops * ops,struct file * file,void * fh,void * arg)1226*4882a593Smuzhiyun static int v4l_enumoutput(const struct v4l2_ioctl_ops *ops,
1227*4882a593Smuzhiyun struct file *file, void *fh, void *arg)
1228*4882a593Smuzhiyun {
1229*4882a593Smuzhiyun struct video_device *vfd = video_devdata(file);
1230*4882a593Smuzhiyun struct v4l2_output *p = arg;
1231*4882a593Smuzhiyun
1232*4882a593Smuzhiyun /*
1233*4882a593Smuzhiyun * We set the flags for CAP_DV_TIMINGS &
1234*4882a593Smuzhiyun * CAP_STD here based on ioctl handler provided by the
1235*4882a593Smuzhiyun * driver. If the driver doesn't support these
1236*4882a593Smuzhiyun * for a specific output, it must override these flags.
1237*4882a593Smuzhiyun */
1238*4882a593Smuzhiyun if (is_valid_ioctl(vfd, VIDIOC_S_STD))
1239*4882a593Smuzhiyun p->capabilities |= V4L2_OUT_CAP_STD;
1240*4882a593Smuzhiyun
1241*4882a593Smuzhiyun if (vfd->device_caps & V4L2_CAP_IO_MC) {
1242*4882a593Smuzhiyun if (p->index)
1243*4882a593Smuzhiyun return -EINVAL;
1244*4882a593Smuzhiyun strscpy(p->name, vfd->name, sizeof(p->name));
1245*4882a593Smuzhiyun p->type = V4L2_OUTPUT_TYPE_ANALOG;
1246*4882a593Smuzhiyun return 0;
1247*4882a593Smuzhiyun }
1248*4882a593Smuzhiyun
1249*4882a593Smuzhiyun return ops->vidioc_enum_output(file, fh, p);
1250*4882a593Smuzhiyun }
1251*4882a593Smuzhiyun
v4l_fill_fmtdesc(struct v4l2_fmtdesc * fmt)1252*4882a593Smuzhiyun static void v4l_fill_fmtdesc(struct v4l2_fmtdesc *fmt)
1253*4882a593Smuzhiyun {
1254*4882a593Smuzhiyun const unsigned sz = sizeof(fmt->description);
1255*4882a593Smuzhiyun const char *descr = NULL;
1256*4882a593Smuzhiyun u32 flags = 0;
1257*4882a593Smuzhiyun
1258*4882a593Smuzhiyun /*
1259*4882a593Smuzhiyun * We depart from the normal coding style here since the descriptions
1260*4882a593Smuzhiyun * should be aligned so it is easy to see which descriptions will be
1261*4882a593Smuzhiyun * longer than 31 characters (the max length for a description).
1262*4882a593Smuzhiyun * And frankly, this is easier to read anyway.
1263*4882a593Smuzhiyun *
1264*4882a593Smuzhiyun * Note that gcc will use O(log N) comparisons to find the right case.
1265*4882a593Smuzhiyun */
1266*4882a593Smuzhiyun switch (fmt->pixelformat) {
1267*4882a593Smuzhiyun /* Max description length mask: descr = "0123456789012345678901234567890" */
1268*4882a593Smuzhiyun case V4L2_PIX_FMT_RGB332: descr = "8-bit RGB 3-3-2"; break;
1269*4882a593Smuzhiyun case V4L2_PIX_FMT_RGB444: descr = "16-bit A/XRGB 4-4-4-4"; break;
1270*4882a593Smuzhiyun case V4L2_PIX_FMT_ARGB444: descr = "16-bit ARGB 4-4-4-4"; break;
1271*4882a593Smuzhiyun case V4L2_PIX_FMT_XRGB444: descr = "16-bit XRGB 4-4-4-4"; break;
1272*4882a593Smuzhiyun case V4L2_PIX_FMT_RGBA444: descr = "16-bit RGBA 4-4-4-4"; break;
1273*4882a593Smuzhiyun case V4L2_PIX_FMT_RGBX444: descr = "16-bit RGBX 4-4-4-4"; break;
1274*4882a593Smuzhiyun case V4L2_PIX_FMT_ABGR444: descr = "16-bit ABGR 4-4-4-4"; break;
1275*4882a593Smuzhiyun case V4L2_PIX_FMT_XBGR444: descr = "16-bit XBGR 4-4-4-4"; break;
1276*4882a593Smuzhiyun case V4L2_PIX_FMT_BGRA444: descr = "16-bit BGRA 4-4-4-4"; break;
1277*4882a593Smuzhiyun case V4L2_PIX_FMT_BGRX444: descr = "16-bit BGRX 4-4-4-4"; break;
1278*4882a593Smuzhiyun case V4L2_PIX_FMT_RGB555: descr = "16-bit A/XRGB 1-5-5-5"; break;
1279*4882a593Smuzhiyun case V4L2_PIX_FMT_ARGB555: descr = "16-bit ARGB 1-5-5-5"; break;
1280*4882a593Smuzhiyun case V4L2_PIX_FMT_XRGB555: descr = "16-bit XRGB 1-5-5-5"; break;
1281*4882a593Smuzhiyun case V4L2_PIX_FMT_ABGR555: descr = "16-bit ABGR 1-5-5-5"; break;
1282*4882a593Smuzhiyun case V4L2_PIX_FMT_XBGR555: descr = "16-bit XBGR 1-5-5-5"; break;
1283*4882a593Smuzhiyun case V4L2_PIX_FMT_RGBA555: descr = "16-bit RGBA 5-5-5-1"; break;
1284*4882a593Smuzhiyun case V4L2_PIX_FMT_RGBX555: descr = "16-bit RGBX 5-5-5-1"; break;
1285*4882a593Smuzhiyun case V4L2_PIX_FMT_BGRA555: descr = "16-bit BGRA 5-5-5-1"; break;
1286*4882a593Smuzhiyun case V4L2_PIX_FMT_BGRX555: descr = "16-bit BGRX 5-5-5-1"; break;
1287*4882a593Smuzhiyun case V4L2_PIX_FMT_RGB565: descr = "16-bit RGB 5-6-5"; break;
1288*4882a593Smuzhiyun case V4L2_PIX_FMT_RGB555X: descr = "16-bit A/XRGB 1-5-5-5 BE"; break;
1289*4882a593Smuzhiyun case V4L2_PIX_FMT_ARGB555X: descr = "16-bit ARGB 1-5-5-5 BE"; break;
1290*4882a593Smuzhiyun case V4L2_PIX_FMT_XRGB555X: descr = "16-bit XRGB 1-5-5-5 BE"; break;
1291*4882a593Smuzhiyun case V4L2_PIX_FMT_RGB565X: descr = "16-bit RGB 5-6-5 BE"; break;
1292*4882a593Smuzhiyun case V4L2_PIX_FMT_BGR666: descr = "18-bit BGRX 6-6-6-14"; break;
1293*4882a593Smuzhiyun case V4L2_PIX_FMT_BGR24: descr = "24-bit BGR 8-8-8"; break;
1294*4882a593Smuzhiyun case V4L2_PIX_FMT_RGB24: descr = "24-bit RGB 8-8-8"; break;
1295*4882a593Smuzhiyun case V4L2_PIX_FMT_BGR32: descr = "32-bit BGRA/X 8-8-8-8"; break;
1296*4882a593Smuzhiyun case V4L2_PIX_FMT_ABGR32: descr = "32-bit BGRA 8-8-8-8"; break;
1297*4882a593Smuzhiyun case V4L2_PIX_FMT_XBGR32: descr = "32-bit BGRX 8-8-8-8"; break;
1298*4882a593Smuzhiyun case V4L2_PIX_FMT_RGB32: descr = "32-bit A/XRGB 8-8-8-8"; break;
1299*4882a593Smuzhiyun case V4L2_PIX_FMT_ARGB32: descr = "32-bit ARGB 8-8-8-8"; break;
1300*4882a593Smuzhiyun case V4L2_PIX_FMT_XRGB32: descr = "32-bit XRGB 8-8-8-8"; break;
1301*4882a593Smuzhiyun case V4L2_PIX_FMT_BGRA32: descr = "32-bit ABGR 8-8-8-8"; break;
1302*4882a593Smuzhiyun case V4L2_PIX_FMT_BGRX32: descr = "32-bit XBGR 8-8-8-8"; break;
1303*4882a593Smuzhiyun case V4L2_PIX_FMT_RGBA32: descr = "32-bit RGBA 8-8-8-8"; break;
1304*4882a593Smuzhiyun case V4L2_PIX_FMT_RGBX32: descr = "32-bit RGBX 8-8-8-8"; break;
1305*4882a593Smuzhiyun case V4L2_PIX_FMT_GREY: descr = "8-bit Greyscale"; break;
1306*4882a593Smuzhiyun case V4L2_PIX_FMT_Y4: descr = "4-bit Greyscale"; break;
1307*4882a593Smuzhiyun case V4L2_PIX_FMT_Y6: descr = "6-bit Greyscale"; break;
1308*4882a593Smuzhiyun case V4L2_PIX_FMT_Y10: descr = "10-bit Greyscale"; break;
1309*4882a593Smuzhiyun case V4L2_PIX_FMT_Y12: descr = "12-bit Greyscale"; break;
1310*4882a593Smuzhiyun case V4L2_PIX_FMT_Y14: descr = "14-bit Greyscale"; break;
1311*4882a593Smuzhiyun case V4L2_PIX_FMT_Y16: descr = "16-bit Greyscale"; break;
1312*4882a593Smuzhiyun case V4L2_PIX_FMT_Y16_BE: descr = "16-bit Greyscale BE"; break;
1313*4882a593Smuzhiyun case V4L2_PIX_FMT_Y10BPACK: descr = "10-bit Greyscale (Packed)"; break;
1314*4882a593Smuzhiyun case V4L2_PIX_FMT_Y10P: descr = "10-bit Greyscale (MIPI Packed)"; break;
1315*4882a593Smuzhiyun case V4L2_PIX_FMT_Y8I: descr = "Interleaved 8-bit Greyscale"; break;
1316*4882a593Smuzhiyun case V4L2_PIX_FMT_Y12I: descr = "Interleaved 12-bit Greyscale"; break;
1317*4882a593Smuzhiyun case V4L2_PIX_FMT_Z16: descr = "16-bit Depth"; break;
1318*4882a593Smuzhiyun case V4L2_PIX_FMT_INZI: descr = "Planar 10:16 Greyscale Depth"; break;
1319*4882a593Smuzhiyun case V4L2_PIX_FMT_CNF4: descr = "4-bit Depth Confidence (Packed)"; break;
1320*4882a593Smuzhiyun case V4L2_PIX_FMT_PAL8: descr = "8-bit Palette"; break;
1321*4882a593Smuzhiyun case V4L2_PIX_FMT_UV8: descr = "8-bit Chrominance UV 4-4"; break;
1322*4882a593Smuzhiyun case V4L2_PIX_FMT_YVU410: descr = "Planar YVU 4:1:0"; break;
1323*4882a593Smuzhiyun case V4L2_PIX_FMT_YVU420: descr = "Planar YVU 4:2:0"; break;
1324*4882a593Smuzhiyun case V4L2_PIX_FMT_YUYV: descr = "YUYV 4:2:2"; break;
1325*4882a593Smuzhiyun case V4L2_PIX_FMT_YYUV: descr = "YYUV 4:2:2"; break;
1326*4882a593Smuzhiyun case V4L2_PIX_FMT_YVYU: descr = "YVYU 4:2:2"; break;
1327*4882a593Smuzhiyun case V4L2_PIX_FMT_UYVY: descr = "UYVY 4:2:2"; break;
1328*4882a593Smuzhiyun case V4L2_PIX_FMT_VYUY: descr = "VYUY 4:2:2"; break;
1329*4882a593Smuzhiyun case V4L2_PIX_FMT_YUV422P: descr = "Planar YUV 4:2:2"; break;
1330*4882a593Smuzhiyun case V4L2_PIX_FMT_YUV411P: descr = "Planar YUV 4:1:1"; break;
1331*4882a593Smuzhiyun case V4L2_PIX_FMT_Y41P: descr = "YUV 4:1:1 (Packed)"; break;
1332*4882a593Smuzhiyun case V4L2_PIX_FMT_YUV444: descr = "16-bit A/XYUV 4-4-4-4"; break;
1333*4882a593Smuzhiyun case V4L2_PIX_FMT_YUV555: descr = "16-bit A/XYUV 1-5-5-5"; break;
1334*4882a593Smuzhiyun case V4L2_PIX_FMT_YUV565: descr = "16-bit YUV 5-6-5"; break;
1335*4882a593Smuzhiyun case V4L2_PIX_FMT_YUV32: descr = "32-bit A/XYUV 8-8-8-8"; break;
1336*4882a593Smuzhiyun case V4L2_PIX_FMT_AYUV32: descr = "32-bit AYUV 8-8-8-8"; break;
1337*4882a593Smuzhiyun case V4L2_PIX_FMT_XYUV32: descr = "32-bit XYUV 8-8-8-8"; break;
1338*4882a593Smuzhiyun case V4L2_PIX_FMT_VUYA32: descr = "32-bit VUYA 8-8-8-8"; break;
1339*4882a593Smuzhiyun case V4L2_PIX_FMT_VUYX32: descr = "32-bit VUYX 8-8-8-8"; break;
1340*4882a593Smuzhiyun case V4L2_PIX_FMT_YUV410: descr = "Planar YUV 4:1:0"; break;
1341*4882a593Smuzhiyun case V4L2_PIX_FMT_YUV420: descr = "Planar YUV 4:2:0"; break;
1342*4882a593Smuzhiyun case V4L2_PIX_FMT_HI240: descr = "8-bit Dithered RGB (BTTV)"; break;
1343*4882a593Smuzhiyun case V4L2_PIX_FMT_HM12: descr = "YUV 4:2:0 (16x16 Macroblocks)"; break;
1344*4882a593Smuzhiyun case V4L2_PIX_FMT_M420: descr = "YUV 4:2:0 (M420)"; break;
1345*4882a593Smuzhiyun case V4L2_PIX_FMT_NV12: descr = "Y/CbCr 4:2:0"; break;
1346*4882a593Smuzhiyun case V4L2_PIX_FMT_NV21: descr = "Y/CrCb 4:2:0"; break;
1347*4882a593Smuzhiyun case V4L2_PIX_FMT_NV16: descr = "Y/CbCr 4:2:2"; break;
1348*4882a593Smuzhiyun case V4L2_PIX_FMT_NV61: descr = "Y/CrCb 4:2:2"; break;
1349*4882a593Smuzhiyun case V4L2_PIX_FMT_NV24: descr = "Y/CbCr 4:4:4"; break;
1350*4882a593Smuzhiyun case V4L2_PIX_FMT_NV42: descr = "Y/CrCb 4:4:4"; break;
1351*4882a593Smuzhiyun case V4L2_PIX_FMT_NV12M: descr = "Y/CbCr 4:2:0 (N-C)"; break;
1352*4882a593Smuzhiyun case V4L2_PIX_FMT_NV21M: descr = "Y/CrCb 4:2:0 (N-C)"; break;
1353*4882a593Smuzhiyun case V4L2_PIX_FMT_NV16M: descr = "Y/CbCr 4:2:2 (N-C)"; break;
1354*4882a593Smuzhiyun case V4L2_PIX_FMT_NV61M: descr = "Y/CrCb 4:2:2 (N-C)"; break;
1355*4882a593Smuzhiyun case V4L2_PIX_FMT_NV12MT: descr = "Y/CbCr 4:2:0 (64x32 MB, N-C)"; break;
1356*4882a593Smuzhiyun case V4L2_PIX_FMT_NV12MT_16X16: descr = "Y/CbCr 4:2:0 (16x16 MB, N-C)"; break;
1357*4882a593Smuzhiyun case V4L2_PIX_FMT_YUV420M: descr = "Planar YUV 4:2:0 (N-C)"; break;
1358*4882a593Smuzhiyun case V4L2_PIX_FMT_YVU420M: descr = "Planar YVU 4:2:0 (N-C)"; break;
1359*4882a593Smuzhiyun case V4L2_PIX_FMT_YUV422M: descr = "Planar YUV 4:2:2 (N-C)"; break;
1360*4882a593Smuzhiyun case V4L2_PIX_FMT_YVU422M: descr = "Planar YVU 4:2:2 (N-C)"; break;
1361*4882a593Smuzhiyun case V4L2_PIX_FMT_YUV444M: descr = "Planar YUV 4:4:4 (N-C)"; break;
1362*4882a593Smuzhiyun case V4L2_PIX_FMT_YVU444M: descr = "Planar YVU 4:4:4 (N-C)"; break;
1363*4882a593Smuzhiyun case V4L2_PIX_FMT_SBGGR8: descr = "8-bit Bayer BGBG/GRGR"; break;
1364*4882a593Smuzhiyun case V4L2_PIX_FMT_SGBRG8: descr = "8-bit Bayer GBGB/RGRG"; break;
1365*4882a593Smuzhiyun case V4L2_PIX_FMT_SGRBG8: descr = "8-bit Bayer GRGR/BGBG"; break;
1366*4882a593Smuzhiyun case V4L2_PIX_FMT_SRGGB8: descr = "8-bit Bayer RGRG/GBGB"; break;
1367*4882a593Smuzhiyun case V4L2_PIX_FMT_SBGGR10: descr = "10-bit Bayer BGBG/GRGR"; break;
1368*4882a593Smuzhiyun case V4L2_PIX_FMT_SGBRG10: descr = "10-bit Bayer GBGB/RGRG"; break;
1369*4882a593Smuzhiyun case V4L2_PIX_FMT_SGRBG10: descr = "10-bit Bayer GRGR/BGBG"; break;
1370*4882a593Smuzhiyun case V4L2_PIX_FMT_SRGGB10: descr = "10-bit Bayer RGRG/GBGB"; break;
1371*4882a593Smuzhiyun case V4L2_PIX_FMT_SBGGR10P: descr = "10-bit Bayer BGBG/GRGR Packed"; break;
1372*4882a593Smuzhiyun case V4L2_PIX_FMT_SGBRG10P: descr = "10-bit Bayer GBGB/RGRG Packed"; break;
1373*4882a593Smuzhiyun case V4L2_PIX_FMT_SGRBG10P: descr = "10-bit Bayer GRGR/BGBG Packed"; break;
1374*4882a593Smuzhiyun case V4L2_PIX_FMT_SRGGB10P: descr = "10-bit Bayer RGRG/GBGB Packed"; break;
1375*4882a593Smuzhiyun case V4L2_PIX_FMT_IPU3_SBGGR10: descr = "10-bit bayer BGGR IPU3 Packed"; break;
1376*4882a593Smuzhiyun case V4L2_PIX_FMT_IPU3_SGBRG10: descr = "10-bit bayer GBRG IPU3 Packed"; break;
1377*4882a593Smuzhiyun case V4L2_PIX_FMT_IPU3_SGRBG10: descr = "10-bit bayer GRBG IPU3 Packed"; break;
1378*4882a593Smuzhiyun case V4L2_PIX_FMT_IPU3_SRGGB10: descr = "10-bit bayer RGGB IPU3 Packed"; break;
1379*4882a593Smuzhiyun case V4L2_PIX_FMT_SBGGR10ALAW8: descr = "8-bit Bayer BGBG/GRGR (A-law)"; break;
1380*4882a593Smuzhiyun case V4L2_PIX_FMT_SGBRG10ALAW8: descr = "8-bit Bayer GBGB/RGRG (A-law)"; break;
1381*4882a593Smuzhiyun case V4L2_PIX_FMT_SGRBG10ALAW8: descr = "8-bit Bayer GRGR/BGBG (A-law)"; break;
1382*4882a593Smuzhiyun case V4L2_PIX_FMT_SRGGB10ALAW8: descr = "8-bit Bayer RGRG/GBGB (A-law)"; break;
1383*4882a593Smuzhiyun case V4L2_PIX_FMT_SBGGR10DPCM8: descr = "8-bit Bayer BGBG/GRGR (DPCM)"; break;
1384*4882a593Smuzhiyun case V4L2_PIX_FMT_SGBRG10DPCM8: descr = "8-bit Bayer GBGB/RGRG (DPCM)"; break;
1385*4882a593Smuzhiyun case V4L2_PIX_FMT_SGRBG10DPCM8: descr = "8-bit Bayer GRGR/BGBG (DPCM)"; break;
1386*4882a593Smuzhiyun case V4L2_PIX_FMT_SRGGB10DPCM8: descr = "8-bit Bayer RGRG/GBGB (DPCM)"; break;
1387*4882a593Smuzhiyun case V4L2_PIX_FMT_SBGGR12: descr = "12-bit Bayer BGBG/GRGR"; break;
1388*4882a593Smuzhiyun case V4L2_PIX_FMT_SGBRG12: descr = "12-bit Bayer GBGB/RGRG"; break;
1389*4882a593Smuzhiyun case V4L2_PIX_FMT_SGRBG12: descr = "12-bit Bayer GRGR/BGBG"; break;
1390*4882a593Smuzhiyun case V4L2_PIX_FMT_SRGGB12: descr = "12-bit Bayer RGRG/GBGB"; break;
1391*4882a593Smuzhiyun case V4L2_PIX_FMT_SBGGR12P: descr = "12-bit Bayer BGBG/GRGR Packed"; break;
1392*4882a593Smuzhiyun case V4L2_PIX_FMT_SGBRG12P: descr = "12-bit Bayer GBGB/RGRG Packed"; break;
1393*4882a593Smuzhiyun case V4L2_PIX_FMT_SGRBG12P: descr = "12-bit Bayer GRGR/BGBG Packed"; break;
1394*4882a593Smuzhiyun case V4L2_PIX_FMT_SRGGB12P: descr = "12-bit Bayer RGRG/GBGB Packed"; break;
1395*4882a593Smuzhiyun case V4L2_PIX_FMT_SBGGR14: descr = "14-bit Bayer BGBG/GRGR"; break;
1396*4882a593Smuzhiyun case V4L2_PIX_FMT_SGBRG14: descr = "14-bit Bayer GBGB/RGRG"; break;
1397*4882a593Smuzhiyun case V4L2_PIX_FMT_SGRBG14: descr = "14-bit Bayer GRGR/BGBG"; break;
1398*4882a593Smuzhiyun case V4L2_PIX_FMT_SRGGB14: descr = "14-bit Bayer RGRG/GBGB"; break;
1399*4882a593Smuzhiyun case V4L2_PIX_FMT_SBGGR14P: descr = "14-bit Bayer BGBG/GRGR Packed"; break;
1400*4882a593Smuzhiyun case V4L2_PIX_FMT_SGBRG14P: descr = "14-bit Bayer GBGB/RGRG Packed"; break;
1401*4882a593Smuzhiyun case V4L2_PIX_FMT_SGRBG14P: descr = "14-bit Bayer GRGR/BGBG Packed"; break;
1402*4882a593Smuzhiyun case V4L2_PIX_FMT_SRGGB14P: descr = "14-bit Bayer RGRG/GBGB Packed"; break;
1403*4882a593Smuzhiyun case V4L2_PIX_FMT_SBGGR16: descr = "16-bit Bayer BGBG/GRGR"; break;
1404*4882a593Smuzhiyun case V4L2_PIX_FMT_SGBRG16: descr = "16-bit Bayer GBGB/RGRG"; break;
1405*4882a593Smuzhiyun case V4L2_PIX_FMT_SGRBG16: descr = "16-bit Bayer GRGR/BGBG"; break;
1406*4882a593Smuzhiyun case V4L2_PIX_FMT_SRGGB16: descr = "16-bit Bayer RGRG/GBGB"; break;
1407*4882a593Smuzhiyun case V4L2_PIX_FMT_SN9C20X_I420: descr = "GSPCA SN9C20X I420"; break;
1408*4882a593Smuzhiyun case V4L2_PIX_FMT_SPCA501: descr = "GSPCA SPCA501"; break;
1409*4882a593Smuzhiyun case V4L2_PIX_FMT_SPCA505: descr = "GSPCA SPCA505"; break;
1410*4882a593Smuzhiyun case V4L2_PIX_FMT_SPCA508: descr = "GSPCA SPCA508"; break;
1411*4882a593Smuzhiyun case V4L2_PIX_FMT_STV0680: descr = "GSPCA STV0680"; break;
1412*4882a593Smuzhiyun case V4L2_PIX_FMT_TM6000: descr = "A/V + VBI Mux Packet"; break;
1413*4882a593Smuzhiyun case V4L2_PIX_FMT_CIT_YYVYUY: descr = "GSPCA CIT YYVYUY"; break;
1414*4882a593Smuzhiyun case V4L2_PIX_FMT_KONICA420: descr = "GSPCA KONICA420"; break;
1415*4882a593Smuzhiyun case V4L2_PIX_FMT_HSV24: descr = "24-bit HSV 8-8-8"; break;
1416*4882a593Smuzhiyun case V4L2_PIX_FMT_HSV32: descr = "32-bit XHSV 8-8-8-8"; break;
1417*4882a593Smuzhiyun case V4L2_SDR_FMT_CU8: descr = "Complex U8"; break;
1418*4882a593Smuzhiyun case V4L2_SDR_FMT_CU16LE: descr = "Complex U16LE"; break;
1419*4882a593Smuzhiyun case V4L2_SDR_FMT_CS8: descr = "Complex S8"; break;
1420*4882a593Smuzhiyun case V4L2_SDR_FMT_CS14LE: descr = "Complex S14LE"; break;
1421*4882a593Smuzhiyun case V4L2_SDR_FMT_RU12LE: descr = "Real U12LE"; break;
1422*4882a593Smuzhiyun case V4L2_SDR_FMT_PCU16BE: descr = "Planar Complex U16BE"; break;
1423*4882a593Smuzhiyun case V4L2_SDR_FMT_PCU18BE: descr = "Planar Complex U18BE"; break;
1424*4882a593Smuzhiyun case V4L2_SDR_FMT_PCU20BE: descr = "Planar Complex U20BE"; break;
1425*4882a593Smuzhiyun case V4L2_TCH_FMT_DELTA_TD16: descr = "16-bit Signed Deltas"; break;
1426*4882a593Smuzhiyun case V4L2_TCH_FMT_DELTA_TD08: descr = "8-bit Signed Deltas"; break;
1427*4882a593Smuzhiyun case V4L2_TCH_FMT_TU16: descr = "16-bit Unsigned Touch Data"; break;
1428*4882a593Smuzhiyun case V4L2_TCH_FMT_TU08: descr = "8-bit Unsigned Touch Data"; break;
1429*4882a593Smuzhiyun case V4L2_META_FMT_VSP1_HGO: descr = "R-Car VSP1 1-D Histogram"; break;
1430*4882a593Smuzhiyun case V4L2_META_FMT_VSP1_HGT: descr = "R-Car VSP1 2-D Histogram"; break;
1431*4882a593Smuzhiyun case V4L2_META_FMT_UVC: descr = "UVC Payload Header Metadata"; break;
1432*4882a593Smuzhiyun case V4L2_META_FMT_D4XX: descr = "Intel D4xx UVC Metadata"; break;
1433*4882a593Smuzhiyun case V4L2_META_FMT_VIVID: descr = "Vivid Metadata"; break;
1434*4882a593Smuzhiyun
1435*4882a593Smuzhiyun default:
1436*4882a593Smuzhiyun /* Compressed formats */
1437*4882a593Smuzhiyun flags = V4L2_FMT_FLAG_COMPRESSED;
1438*4882a593Smuzhiyun switch (fmt->pixelformat) {
1439*4882a593Smuzhiyun /* Max description length mask: descr = "0123456789012345678901234567890" */
1440*4882a593Smuzhiyun case V4L2_PIX_FMT_MJPEG: descr = "Motion-JPEG"; break;
1441*4882a593Smuzhiyun case V4L2_PIX_FMT_JPEG: descr = "JFIF JPEG"; break;
1442*4882a593Smuzhiyun case V4L2_PIX_FMT_DV: descr = "1394"; break;
1443*4882a593Smuzhiyun case V4L2_PIX_FMT_MPEG: descr = "MPEG-1/2/4"; break;
1444*4882a593Smuzhiyun case V4L2_PIX_FMT_H264: descr = "H.264"; break;
1445*4882a593Smuzhiyun case V4L2_PIX_FMT_H264_NO_SC: descr = "H.264 (No Start Codes)"; break;
1446*4882a593Smuzhiyun case V4L2_PIX_FMT_H264_MVC: descr = "H.264 MVC"; break;
1447*4882a593Smuzhiyun case V4L2_PIX_FMT_H264_SLICE: descr = "H.264 Parsed Slice Data"; break;
1448*4882a593Smuzhiyun case V4L2_PIX_FMT_H263: descr = "H.263"; break;
1449*4882a593Smuzhiyun case V4L2_PIX_FMT_MPEG1: descr = "MPEG-1 ES"; break;
1450*4882a593Smuzhiyun case V4L2_PIX_FMT_MPEG2: descr = "MPEG-2 ES"; break;
1451*4882a593Smuzhiyun case V4L2_PIX_FMT_MPEG2_SLICE: descr = "MPEG-2 Parsed Slice Data"; break;
1452*4882a593Smuzhiyun case V4L2_PIX_FMT_MPEG4: descr = "MPEG-4 Part 2 ES"; break;
1453*4882a593Smuzhiyun case V4L2_PIX_FMT_XVID: descr = "Xvid"; break;
1454*4882a593Smuzhiyun case V4L2_PIX_FMT_VC1_ANNEX_G: descr = "VC-1 (SMPTE 412M Annex G)"; break;
1455*4882a593Smuzhiyun case V4L2_PIX_FMT_VC1_ANNEX_L: descr = "VC-1 (SMPTE 412M Annex L)"; break;
1456*4882a593Smuzhiyun case V4L2_PIX_FMT_VP8: descr = "VP8"; break;
1457*4882a593Smuzhiyun case V4L2_PIX_FMT_VP8_FRAME: descr = "VP8 Frame"; break;
1458*4882a593Smuzhiyun case V4L2_PIX_FMT_VP9: descr = "VP9"; break;
1459*4882a593Smuzhiyun case V4L2_PIX_FMT_HEVC: descr = "HEVC"; break; /* aka H.265 */
1460*4882a593Smuzhiyun case V4L2_PIX_FMT_HEVC_SLICE: descr = "HEVC Parsed Slice Data"; break;
1461*4882a593Smuzhiyun case V4L2_PIX_FMT_FWHT: descr = "FWHT"; break; /* used in vicodec */
1462*4882a593Smuzhiyun case V4L2_PIX_FMT_FWHT_STATELESS: descr = "FWHT Stateless"; break; /* used in vicodec */
1463*4882a593Smuzhiyun case V4L2_PIX_FMT_CPIA1: descr = "GSPCA CPiA YUV"; break;
1464*4882a593Smuzhiyun case V4L2_PIX_FMT_WNVA: descr = "WNVA"; break;
1465*4882a593Smuzhiyun case V4L2_PIX_FMT_SN9C10X: descr = "GSPCA SN9C10X"; break;
1466*4882a593Smuzhiyun case V4L2_PIX_FMT_PWC1: descr = "Raw Philips Webcam Type (Old)"; break;
1467*4882a593Smuzhiyun case V4L2_PIX_FMT_PWC2: descr = "Raw Philips Webcam Type (New)"; break;
1468*4882a593Smuzhiyun case V4L2_PIX_FMT_ET61X251: descr = "GSPCA ET61X251"; break;
1469*4882a593Smuzhiyun case V4L2_PIX_FMT_SPCA561: descr = "GSPCA SPCA561"; break;
1470*4882a593Smuzhiyun case V4L2_PIX_FMT_PAC207: descr = "GSPCA PAC207"; break;
1471*4882a593Smuzhiyun case V4L2_PIX_FMT_MR97310A: descr = "GSPCA MR97310A"; break;
1472*4882a593Smuzhiyun case V4L2_PIX_FMT_JL2005BCD: descr = "GSPCA JL2005BCD"; break;
1473*4882a593Smuzhiyun case V4L2_PIX_FMT_SN9C2028: descr = "GSPCA SN9C2028"; break;
1474*4882a593Smuzhiyun case V4L2_PIX_FMT_SQ905C: descr = "GSPCA SQ905C"; break;
1475*4882a593Smuzhiyun case V4L2_PIX_FMT_PJPG: descr = "GSPCA PJPG"; break;
1476*4882a593Smuzhiyun case V4L2_PIX_FMT_OV511: descr = "GSPCA OV511"; break;
1477*4882a593Smuzhiyun case V4L2_PIX_FMT_OV518: descr = "GSPCA OV518"; break;
1478*4882a593Smuzhiyun case V4L2_PIX_FMT_JPGL: descr = "JPEG Lite"; break;
1479*4882a593Smuzhiyun case V4L2_PIX_FMT_SE401: descr = "GSPCA SE401"; break;
1480*4882a593Smuzhiyun case V4L2_PIX_FMT_S5C_UYVY_JPG: descr = "S5C73MX interleaved UYVY/JPEG"; break;
1481*4882a593Smuzhiyun case V4L2_PIX_FMT_MT21C: descr = "Mediatek Compressed Format"; break;
1482*4882a593Smuzhiyun case V4L2_PIX_FMT_SUNXI_TILED_NV12: descr = "Sunxi Tiled NV12 Format"; break;
1483*4882a593Smuzhiyun default:
1484*4882a593Smuzhiyun trace_android_vh_fill_ext_fmtdesc(fmt, &descr);
1485*4882a593Smuzhiyun if (descr)
1486*4882a593Smuzhiyun break;
1487*4882a593Smuzhiyun if (fmt->description[0])
1488*4882a593Smuzhiyun return;
1489*4882a593Smuzhiyun WARN(1, "Unknown pixelformat 0x%08x\n", fmt->pixelformat);
1490*4882a593Smuzhiyun flags = 0;
1491*4882a593Smuzhiyun snprintf(fmt->description, sz, "%c%c%c%c%s",
1492*4882a593Smuzhiyun (char)(fmt->pixelformat & 0x7f),
1493*4882a593Smuzhiyun (char)((fmt->pixelformat >> 8) & 0x7f),
1494*4882a593Smuzhiyun (char)((fmt->pixelformat >> 16) & 0x7f),
1495*4882a593Smuzhiyun (char)((fmt->pixelformat >> 24) & 0x7f),
1496*4882a593Smuzhiyun (fmt->pixelformat & (1UL << 31)) ? "-BE" : "");
1497*4882a593Smuzhiyun break;
1498*4882a593Smuzhiyun }
1499*4882a593Smuzhiyun }
1500*4882a593Smuzhiyun
1501*4882a593Smuzhiyun if (descr)
1502*4882a593Smuzhiyun WARN_ON(strscpy(fmt->description, descr, sz) < 0);
1503*4882a593Smuzhiyun fmt->flags |= flags;
1504*4882a593Smuzhiyun }
1505*4882a593Smuzhiyun
v4l_enum_fmt(const struct v4l2_ioctl_ops * ops,struct file * file,void * fh,void * arg)1506*4882a593Smuzhiyun static int v4l_enum_fmt(const struct v4l2_ioctl_ops *ops,
1507*4882a593Smuzhiyun struct file *file, void *fh, void *arg)
1508*4882a593Smuzhiyun {
1509*4882a593Smuzhiyun struct video_device *vdev = video_devdata(file);
1510*4882a593Smuzhiyun struct v4l2_fmtdesc *p = arg;
1511*4882a593Smuzhiyun int ret = check_fmt(file, p->type);
1512*4882a593Smuzhiyun u32 mbus_code;
1513*4882a593Smuzhiyun u32 cap_mask;
1514*4882a593Smuzhiyun
1515*4882a593Smuzhiyun if (ret)
1516*4882a593Smuzhiyun return ret;
1517*4882a593Smuzhiyun ret = -EINVAL;
1518*4882a593Smuzhiyun
1519*4882a593Smuzhiyun if (!(vdev->device_caps & V4L2_CAP_IO_MC))
1520*4882a593Smuzhiyun p->mbus_code = 0;
1521*4882a593Smuzhiyun
1522*4882a593Smuzhiyun mbus_code = p->mbus_code;
1523*4882a593Smuzhiyun CLEAR_AFTER_FIELD(p, type);
1524*4882a593Smuzhiyun p->mbus_code = mbus_code;
1525*4882a593Smuzhiyun
1526*4882a593Smuzhiyun switch (p->type) {
1527*4882a593Smuzhiyun case V4L2_BUF_TYPE_VIDEO_CAPTURE:
1528*4882a593Smuzhiyun case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
1529*4882a593Smuzhiyun cap_mask = V4L2_CAP_VIDEO_CAPTURE_MPLANE |
1530*4882a593Smuzhiyun V4L2_CAP_VIDEO_M2M_MPLANE;
1531*4882a593Smuzhiyun if (!!(vdev->device_caps & cap_mask) !=
1532*4882a593Smuzhiyun (p->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE))
1533*4882a593Smuzhiyun break;
1534*4882a593Smuzhiyun
1535*4882a593Smuzhiyun if (unlikely(!ops->vidioc_enum_fmt_vid_cap))
1536*4882a593Smuzhiyun break;
1537*4882a593Smuzhiyun ret = ops->vidioc_enum_fmt_vid_cap(file, fh, arg);
1538*4882a593Smuzhiyun break;
1539*4882a593Smuzhiyun case V4L2_BUF_TYPE_VIDEO_OVERLAY:
1540*4882a593Smuzhiyun if (unlikely(!ops->vidioc_enum_fmt_vid_overlay))
1541*4882a593Smuzhiyun break;
1542*4882a593Smuzhiyun ret = ops->vidioc_enum_fmt_vid_overlay(file, fh, arg);
1543*4882a593Smuzhiyun break;
1544*4882a593Smuzhiyun case V4L2_BUF_TYPE_VIDEO_OUTPUT:
1545*4882a593Smuzhiyun case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
1546*4882a593Smuzhiyun cap_mask = V4L2_CAP_VIDEO_OUTPUT_MPLANE |
1547*4882a593Smuzhiyun V4L2_CAP_VIDEO_M2M_MPLANE;
1548*4882a593Smuzhiyun if (!!(vdev->device_caps & cap_mask) !=
1549*4882a593Smuzhiyun (p->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE))
1550*4882a593Smuzhiyun break;
1551*4882a593Smuzhiyun
1552*4882a593Smuzhiyun if (unlikely(!ops->vidioc_enum_fmt_vid_out))
1553*4882a593Smuzhiyun break;
1554*4882a593Smuzhiyun ret = ops->vidioc_enum_fmt_vid_out(file, fh, arg);
1555*4882a593Smuzhiyun break;
1556*4882a593Smuzhiyun case V4L2_BUF_TYPE_SDR_CAPTURE:
1557*4882a593Smuzhiyun if (unlikely(!ops->vidioc_enum_fmt_sdr_cap))
1558*4882a593Smuzhiyun break;
1559*4882a593Smuzhiyun ret = ops->vidioc_enum_fmt_sdr_cap(file, fh, arg);
1560*4882a593Smuzhiyun break;
1561*4882a593Smuzhiyun case V4L2_BUF_TYPE_SDR_OUTPUT:
1562*4882a593Smuzhiyun if (unlikely(!ops->vidioc_enum_fmt_sdr_out))
1563*4882a593Smuzhiyun break;
1564*4882a593Smuzhiyun ret = ops->vidioc_enum_fmt_sdr_out(file, fh, arg);
1565*4882a593Smuzhiyun break;
1566*4882a593Smuzhiyun case V4L2_BUF_TYPE_META_CAPTURE:
1567*4882a593Smuzhiyun if (unlikely(!ops->vidioc_enum_fmt_meta_cap))
1568*4882a593Smuzhiyun break;
1569*4882a593Smuzhiyun ret = ops->vidioc_enum_fmt_meta_cap(file, fh, arg);
1570*4882a593Smuzhiyun break;
1571*4882a593Smuzhiyun case V4L2_BUF_TYPE_META_OUTPUT:
1572*4882a593Smuzhiyun if (unlikely(!ops->vidioc_enum_fmt_meta_out))
1573*4882a593Smuzhiyun break;
1574*4882a593Smuzhiyun ret = ops->vidioc_enum_fmt_meta_out(file, fh, arg);
1575*4882a593Smuzhiyun break;
1576*4882a593Smuzhiyun }
1577*4882a593Smuzhiyun if (ret == 0)
1578*4882a593Smuzhiyun v4l_fill_fmtdesc(p);
1579*4882a593Smuzhiyun return ret;
1580*4882a593Smuzhiyun }
1581*4882a593Smuzhiyun
v4l_pix_format_touch(struct v4l2_pix_format * p)1582*4882a593Smuzhiyun static void v4l_pix_format_touch(struct v4l2_pix_format *p)
1583*4882a593Smuzhiyun {
1584*4882a593Smuzhiyun /*
1585*4882a593Smuzhiyun * The v4l2_pix_format structure contains fields that make no sense for
1586*4882a593Smuzhiyun * touch. Set them to default values in this case.
1587*4882a593Smuzhiyun */
1588*4882a593Smuzhiyun
1589*4882a593Smuzhiyun p->field = V4L2_FIELD_NONE;
1590*4882a593Smuzhiyun p->colorspace = V4L2_COLORSPACE_RAW;
1591*4882a593Smuzhiyun p->flags = 0;
1592*4882a593Smuzhiyun p->ycbcr_enc = 0;
1593*4882a593Smuzhiyun p->quantization = 0;
1594*4882a593Smuzhiyun p->xfer_func = 0;
1595*4882a593Smuzhiyun }
1596*4882a593Smuzhiyun
v4l_g_fmt(const struct v4l2_ioctl_ops * ops,struct file * file,void * fh,void * arg)1597*4882a593Smuzhiyun static int v4l_g_fmt(const struct v4l2_ioctl_ops *ops,
1598*4882a593Smuzhiyun struct file *file, void *fh, void *arg)
1599*4882a593Smuzhiyun {
1600*4882a593Smuzhiyun struct v4l2_format *p = arg;
1601*4882a593Smuzhiyun struct video_device *vfd = video_devdata(file);
1602*4882a593Smuzhiyun int ret = check_fmt(file, p->type);
1603*4882a593Smuzhiyun
1604*4882a593Smuzhiyun if (ret)
1605*4882a593Smuzhiyun return ret;
1606*4882a593Smuzhiyun
1607*4882a593Smuzhiyun /*
1608*4882a593Smuzhiyun * fmt can't be cleared for these overlay types due to the 'clips'
1609*4882a593Smuzhiyun * 'clipcount' and 'bitmap' pointers in struct v4l2_window.
1610*4882a593Smuzhiyun * Those are provided by the user. So handle these two overlay types
1611*4882a593Smuzhiyun * first, and then just do a simple memset for the other types.
1612*4882a593Smuzhiyun */
1613*4882a593Smuzhiyun switch (p->type) {
1614*4882a593Smuzhiyun case V4L2_BUF_TYPE_VIDEO_OVERLAY:
1615*4882a593Smuzhiyun case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY: {
1616*4882a593Smuzhiyun struct v4l2_clip __user *clips = p->fmt.win.clips;
1617*4882a593Smuzhiyun u32 clipcount = p->fmt.win.clipcount;
1618*4882a593Smuzhiyun void __user *bitmap = p->fmt.win.bitmap;
1619*4882a593Smuzhiyun
1620*4882a593Smuzhiyun memset(&p->fmt, 0, sizeof(p->fmt));
1621*4882a593Smuzhiyun p->fmt.win.clips = clips;
1622*4882a593Smuzhiyun p->fmt.win.clipcount = clipcount;
1623*4882a593Smuzhiyun p->fmt.win.bitmap = bitmap;
1624*4882a593Smuzhiyun break;
1625*4882a593Smuzhiyun }
1626*4882a593Smuzhiyun default:
1627*4882a593Smuzhiyun memset(&p->fmt, 0, sizeof(p->fmt));
1628*4882a593Smuzhiyun break;
1629*4882a593Smuzhiyun }
1630*4882a593Smuzhiyun
1631*4882a593Smuzhiyun switch (p->type) {
1632*4882a593Smuzhiyun case V4L2_BUF_TYPE_VIDEO_CAPTURE:
1633*4882a593Smuzhiyun if (unlikely(!ops->vidioc_g_fmt_vid_cap))
1634*4882a593Smuzhiyun break;
1635*4882a593Smuzhiyun p->fmt.pix.priv = V4L2_PIX_FMT_PRIV_MAGIC;
1636*4882a593Smuzhiyun ret = ops->vidioc_g_fmt_vid_cap(file, fh, arg);
1637*4882a593Smuzhiyun /* just in case the driver zeroed it again */
1638*4882a593Smuzhiyun p->fmt.pix.priv = V4L2_PIX_FMT_PRIV_MAGIC;
1639*4882a593Smuzhiyun if (vfd->vfl_type == VFL_TYPE_TOUCH)
1640*4882a593Smuzhiyun v4l_pix_format_touch(&p->fmt.pix);
1641*4882a593Smuzhiyun return ret;
1642*4882a593Smuzhiyun case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
1643*4882a593Smuzhiyun return ops->vidioc_g_fmt_vid_cap_mplane(file, fh, arg);
1644*4882a593Smuzhiyun case V4L2_BUF_TYPE_VIDEO_OVERLAY:
1645*4882a593Smuzhiyun return ops->vidioc_g_fmt_vid_overlay(file, fh, arg);
1646*4882a593Smuzhiyun case V4L2_BUF_TYPE_VBI_CAPTURE:
1647*4882a593Smuzhiyun return ops->vidioc_g_fmt_vbi_cap(file, fh, arg);
1648*4882a593Smuzhiyun case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
1649*4882a593Smuzhiyun return ops->vidioc_g_fmt_sliced_vbi_cap(file, fh, arg);
1650*4882a593Smuzhiyun case V4L2_BUF_TYPE_VIDEO_OUTPUT:
1651*4882a593Smuzhiyun if (unlikely(!ops->vidioc_g_fmt_vid_out))
1652*4882a593Smuzhiyun break;
1653*4882a593Smuzhiyun p->fmt.pix.priv = V4L2_PIX_FMT_PRIV_MAGIC;
1654*4882a593Smuzhiyun ret = ops->vidioc_g_fmt_vid_out(file, fh, arg);
1655*4882a593Smuzhiyun /* just in case the driver zeroed it again */
1656*4882a593Smuzhiyun p->fmt.pix.priv = V4L2_PIX_FMT_PRIV_MAGIC;
1657*4882a593Smuzhiyun return ret;
1658*4882a593Smuzhiyun case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
1659*4882a593Smuzhiyun return ops->vidioc_g_fmt_vid_out_mplane(file, fh, arg);
1660*4882a593Smuzhiyun case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
1661*4882a593Smuzhiyun return ops->vidioc_g_fmt_vid_out_overlay(file, fh, arg);
1662*4882a593Smuzhiyun case V4L2_BUF_TYPE_VBI_OUTPUT:
1663*4882a593Smuzhiyun return ops->vidioc_g_fmt_vbi_out(file, fh, arg);
1664*4882a593Smuzhiyun case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
1665*4882a593Smuzhiyun return ops->vidioc_g_fmt_sliced_vbi_out(file, fh, arg);
1666*4882a593Smuzhiyun case V4L2_BUF_TYPE_SDR_CAPTURE:
1667*4882a593Smuzhiyun return ops->vidioc_g_fmt_sdr_cap(file, fh, arg);
1668*4882a593Smuzhiyun case V4L2_BUF_TYPE_SDR_OUTPUT:
1669*4882a593Smuzhiyun return ops->vidioc_g_fmt_sdr_out(file, fh, arg);
1670*4882a593Smuzhiyun case V4L2_BUF_TYPE_META_CAPTURE:
1671*4882a593Smuzhiyun return ops->vidioc_g_fmt_meta_cap(file, fh, arg);
1672*4882a593Smuzhiyun case V4L2_BUF_TYPE_META_OUTPUT:
1673*4882a593Smuzhiyun return ops->vidioc_g_fmt_meta_out(file, fh, arg);
1674*4882a593Smuzhiyun }
1675*4882a593Smuzhiyun return -EINVAL;
1676*4882a593Smuzhiyun }
1677*4882a593Smuzhiyun
v4l_s_fmt(const struct v4l2_ioctl_ops * ops,struct file * file,void * fh,void * arg)1678*4882a593Smuzhiyun static int v4l_s_fmt(const struct v4l2_ioctl_ops *ops,
1679*4882a593Smuzhiyun struct file *file, void *fh, void *arg)
1680*4882a593Smuzhiyun {
1681*4882a593Smuzhiyun struct v4l2_format *p = arg;
1682*4882a593Smuzhiyun struct video_device *vfd = video_devdata(file);
1683*4882a593Smuzhiyun int ret = check_fmt(file, p->type);
1684*4882a593Smuzhiyun unsigned int i;
1685*4882a593Smuzhiyun
1686*4882a593Smuzhiyun if (ret)
1687*4882a593Smuzhiyun return ret;
1688*4882a593Smuzhiyun
1689*4882a593Smuzhiyun ret = v4l_enable_media_source(vfd);
1690*4882a593Smuzhiyun if (ret)
1691*4882a593Smuzhiyun return ret;
1692*4882a593Smuzhiyun v4l_sanitize_format(p);
1693*4882a593Smuzhiyun
1694*4882a593Smuzhiyun switch (p->type) {
1695*4882a593Smuzhiyun case V4L2_BUF_TYPE_VIDEO_CAPTURE:
1696*4882a593Smuzhiyun if (unlikely(!ops->vidioc_s_fmt_vid_cap))
1697*4882a593Smuzhiyun break;
1698*4882a593Smuzhiyun CLEAR_AFTER_FIELD(p, fmt.pix);
1699*4882a593Smuzhiyun ret = ops->vidioc_s_fmt_vid_cap(file, fh, arg);
1700*4882a593Smuzhiyun /* just in case the driver zeroed it again */
1701*4882a593Smuzhiyun p->fmt.pix.priv = V4L2_PIX_FMT_PRIV_MAGIC;
1702*4882a593Smuzhiyun if (vfd->vfl_type == VFL_TYPE_TOUCH)
1703*4882a593Smuzhiyun v4l_pix_format_touch(&p->fmt.pix);
1704*4882a593Smuzhiyun return ret;
1705*4882a593Smuzhiyun case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
1706*4882a593Smuzhiyun if (unlikely(!ops->vidioc_s_fmt_vid_cap_mplane))
1707*4882a593Smuzhiyun break;
1708*4882a593Smuzhiyun clear_reserved(p);
1709*4882a593Smuzhiyun for (i = 0; i < p->fmt.pix_mp.num_planes; i++)
1710*4882a593Smuzhiyun CLEAR_AFTER_FIELD(&p->fmt.pix_mp.plane_fmt[i],
1711*4882a593Smuzhiyun bytesperline);
1712*4882a593Smuzhiyun return ops->vidioc_s_fmt_vid_cap_mplane(file, fh, arg);
1713*4882a593Smuzhiyun case V4L2_BUF_TYPE_VIDEO_OVERLAY:
1714*4882a593Smuzhiyun if (unlikely(!ops->vidioc_s_fmt_vid_overlay))
1715*4882a593Smuzhiyun break;
1716*4882a593Smuzhiyun CLEAR_AFTER_FIELD(p, fmt.win);
1717*4882a593Smuzhiyun return ops->vidioc_s_fmt_vid_overlay(file, fh, arg);
1718*4882a593Smuzhiyun case V4L2_BUF_TYPE_VBI_CAPTURE:
1719*4882a593Smuzhiyun if (unlikely(!ops->vidioc_s_fmt_vbi_cap))
1720*4882a593Smuzhiyun break;
1721*4882a593Smuzhiyun CLEAR_AFTER_FIELD(p, fmt.vbi.flags);
1722*4882a593Smuzhiyun return ops->vidioc_s_fmt_vbi_cap(file, fh, arg);
1723*4882a593Smuzhiyun case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
1724*4882a593Smuzhiyun if (unlikely(!ops->vidioc_s_fmt_sliced_vbi_cap))
1725*4882a593Smuzhiyun break;
1726*4882a593Smuzhiyun CLEAR_AFTER_FIELD(p, fmt.sliced.io_size);
1727*4882a593Smuzhiyun return ops->vidioc_s_fmt_sliced_vbi_cap(file, fh, arg);
1728*4882a593Smuzhiyun case V4L2_BUF_TYPE_VIDEO_OUTPUT:
1729*4882a593Smuzhiyun if (unlikely(!ops->vidioc_s_fmt_vid_out))
1730*4882a593Smuzhiyun break;
1731*4882a593Smuzhiyun CLEAR_AFTER_FIELD(p, fmt.pix);
1732*4882a593Smuzhiyun ret = ops->vidioc_s_fmt_vid_out(file, fh, arg);
1733*4882a593Smuzhiyun /* just in case the driver zeroed it again */
1734*4882a593Smuzhiyun p->fmt.pix.priv = V4L2_PIX_FMT_PRIV_MAGIC;
1735*4882a593Smuzhiyun return ret;
1736*4882a593Smuzhiyun case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
1737*4882a593Smuzhiyun if (unlikely(!ops->vidioc_s_fmt_vid_out_mplane))
1738*4882a593Smuzhiyun break;
1739*4882a593Smuzhiyun clear_reserved(p);
1740*4882a593Smuzhiyun for (i = 0; i < p->fmt.pix_mp.num_planes; i++)
1741*4882a593Smuzhiyun CLEAR_AFTER_FIELD(&p->fmt.pix_mp.plane_fmt[i],
1742*4882a593Smuzhiyun bytesperline);
1743*4882a593Smuzhiyun return ops->vidioc_s_fmt_vid_out_mplane(file, fh, arg);
1744*4882a593Smuzhiyun case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
1745*4882a593Smuzhiyun if (unlikely(!ops->vidioc_s_fmt_vid_out_overlay))
1746*4882a593Smuzhiyun break;
1747*4882a593Smuzhiyun CLEAR_AFTER_FIELD(p, fmt.win);
1748*4882a593Smuzhiyun return ops->vidioc_s_fmt_vid_out_overlay(file, fh, arg);
1749*4882a593Smuzhiyun case V4L2_BUF_TYPE_VBI_OUTPUT:
1750*4882a593Smuzhiyun if (unlikely(!ops->vidioc_s_fmt_vbi_out))
1751*4882a593Smuzhiyun break;
1752*4882a593Smuzhiyun CLEAR_AFTER_FIELD(p, fmt.vbi.flags);
1753*4882a593Smuzhiyun return ops->vidioc_s_fmt_vbi_out(file, fh, arg);
1754*4882a593Smuzhiyun case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
1755*4882a593Smuzhiyun if (unlikely(!ops->vidioc_s_fmt_sliced_vbi_out))
1756*4882a593Smuzhiyun break;
1757*4882a593Smuzhiyun CLEAR_AFTER_FIELD(p, fmt.sliced.io_size);
1758*4882a593Smuzhiyun return ops->vidioc_s_fmt_sliced_vbi_out(file, fh, arg);
1759*4882a593Smuzhiyun case V4L2_BUF_TYPE_SDR_CAPTURE:
1760*4882a593Smuzhiyun if (unlikely(!ops->vidioc_s_fmt_sdr_cap))
1761*4882a593Smuzhiyun break;
1762*4882a593Smuzhiyun CLEAR_AFTER_FIELD(p, fmt.sdr.buffersize);
1763*4882a593Smuzhiyun return ops->vidioc_s_fmt_sdr_cap(file, fh, arg);
1764*4882a593Smuzhiyun case V4L2_BUF_TYPE_SDR_OUTPUT:
1765*4882a593Smuzhiyun if (unlikely(!ops->vidioc_s_fmt_sdr_out))
1766*4882a593Smuzhiyun break;
1767*4882a593Smuzhiyun CLEAR_AFTER_FIELD(p, fmt.sdr.buffersize);
1768*4882a593Smuzhiyun return ops->vidioc_s_fmt_sdr_out(file, fh, arg);
1769*4882a593Smuzhiyun case V4L2_BUF_TYPE_META_CAPTURE:
1770*4882a593Smuzhiyun if (unlikely(!ops->vidioc_s_fmt_meta_cap))
1771*4882a593Smuzhiyun break;
1772*4882a593Smuzhiyun CLEAR_AFTER_FIELD(p, fmt.meta);
1773*4882a593Smuzhiyun return ops->vidioc_s_fmt_meta_cap(file, fh, arg);
1774*4882a593Smuzhiyun case V4L2_BUF_TYPE_META_OUTPUT:
1775*4882a593Smuzhiyun if (unlikely(!ops->vidioc_s_fmt_meta_out))
1776*4882a593Smuzhiyun break;
1777*4882a593Smuzhiyun CLEAR_AFTER_FIELD(p, fmt.meta);
1778*4882a593Smuzhiyun return ops->vidioc_s_fmt_meta_out(file, fh, arg);
1779*4882a593Smuzhiyun }
1780*4882a593Smuzhiyun return -EINVAL;
1781*4882a593Smuzhiyun }
1782*4882a593Smuzhiyun
v4l_try_fmt(const struct v4l2_ioctl_ops * ops,struct file * file,void * fh,void * arg)1783*4882a593Smuzhiyun static int v4l_try_fmt(const struct v4l2_ioctl_ops *ops,
1784*4882a593Smuzhiyun struct file *file, void *fh, void *arg)
1785*4882a593Smuzhiyun {
1786*4882a593Smuzhiyun struct v4l2_format *p = arg;
1787*4882a593Smuzhiyun struct video_device *vfd = video_devdata(file);
1788*4882a593Smuzhiyun int ret = check_fmt(file, p->type);
1789*4882a593Smuzhiyun unsigned int i;
1790*4882a593Smuzhiyun
1791*4882a593Smuzhiyun if (ret)
1792*4882a593Smuzhiyun return ret;
1793*4882a593Smuzhiyun
1794*4882a593Smuzhiyun v4l_sanitize_format(p);
1795*4882a593Smuzhiyun
1796*4882a593Smuzhiyun switch (p->type) {
1797*4882a593Smuzhiyun case V4L2_BUF_TYPE_VIDEO_CAPTURE:
1798*4882a593Smuzhiyun if (unlikely(!ops->vidioc_try_fmt_vid_cap))
1799*4882a593Smuzhiyun break;
1800*4882a593Smuzhiyun CLEAR_AFTER_FIELD(p, fmt.pix);
1801*4882a593Smuzhiyun ret = ops->vidioc_try_fmt_vid_cap(file, fh, arg);
1802*4882a593Smuzhiyun /* just in case the driver zeroed it again */
1803*4882a593Smuzhiyun p->fmt.pix.priv = V4L2_PIX_FMT_PRIV_MAGIC;
1804*4882a593Smuzhiyun if (vfd->vfl_type == VFL_TYPE_TOUCH)
1805*4882a593Smuzhiyun v4l_pix_format_touch(&p->fmt.pix);
1806*4882a593Smuzhiyun return ret;
1807*4882a593Smuzhiyun case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
1808*4882a593Smuzhiyun if (unlikely(!ops->vidioc_try_fmt_vid_cap_mplane))
1809*4882a593Smuzhiyun break;
1810*4882a593Smuzhiyun clear_reserved(p);
1811*4882a593Smuzhiyun for (i = 0; i < p->fmt.pix_mp.num_planes; i++)
1812*4882a593Smuzhiyun CLEAR_AFTER_FIELD(&p->fmt.pix_mp.plane_fmt[i],
1813*4882a593Smuzhiyun bytesperline);
1814*4882a593Smuzhiyun return ops->vidioc_try_fmt_vid_cap_mplane(file, fh, arg);
1815*4882a593Smuzhiyun case V4L2_BUF_TYPE_VIDEO_OVERLAY:
1816*4882a593Smuzhiyun if (unlikely(!ops->vidioc_try_fmt_vid_overlay))
1817*4882a593Smuzhiyun break;
1818*4882a593Smuzhiyun CLEAR_AFTER_FIELD(p, fmt.win);
1819*4882a593Smuzhiyun return ops->vidioc_try_fmt_vid_overlay(file, fh, arg);
1820*4882a593Smuzhiyun case V4L2_BUF_TYPE_VBI_CAPTURE:
1821*4882a593Smuzhiyun if (unlikely(!ops->vidioc_try_fmt_vbi_cap))
1822*4882a593Smuzhiyun break;
1823*4882a593Smuzhiyun CLEAR_AFTER_FIELD(p, fmt.vbi.flags);
1824*4882a593Smuzhiyun return ops->vidioc_try_fmt_vbi_cap(file, fh, arg);
1825*4882a593Smuzhiyun case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
1826*4882a593Smuzhiyun if (unlikely(!ops->vidioc_try_fmt_sliced_vbi_cap))
1827*4882a593Smuzhiyun break;
1828*4882a593Smuzhiyun CLEAR_AFTER_FIELD(p, fmt.sliced.io_size);
1829*4882a593Smuzhiyun return ops->vidioc_try_fmt_sliced_vbi_cap(file, fh, arg);
1830*4882a593Smuzhiyun case V4L2_BUF_TYPE_VIDEO_OUTPUT:
1831*4882a593Smuzhiyun if (unlikely(!ops->vidioc_try_fmt_vid_out))
1832*4882a593Smuzhiyun break;
1833*4882a593Smuzhiyun CLEAR_AFTER_FIELD(p, fmt.pix);
1834*4882a593Smuzhiyun ret = ops->vidioc_try_fmt_vid_out(file, fh, arg);
1835*4882a593Smuzhiyun /* just in case the driver zeroed it again */
1836*4882a593Smuzhiyun p->fmt.pix.priv = V4L2_PIX_FMT_PRIV_MAGIC;
1837*4882a593Smuzhiyun return ret;
1838*4882a593Smuzhiyun case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
1839*4882a593Smuzhiyun if (unlikely(!ops->vidioc_try_fmt_vid_out_mplane))
1840*4882a593Smuzhiyun break;
1841*4882a593Smuzhiyun clear_reserved(p);
1842*4882a593Smuzhiyun for (i = 0; i < p->fmt.pix_mp.num_planes; i++)
1843*4882a593Smuzhiyun CLEAR_AFTER_FIELD(&p->fmt.pix_mp.plane_fmt[i],
1844*4882a593Smuzhiyun bytesperline);
1845*4882a593Smuzhiyun return ops->vidioc_try_fmt_vid_out_mplane(file, fh, arg);
1846*4882a593Smuzhiyun case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
1847*4882a593Smuzhiyun if (unlikely(!ops->vidioc_try_fmt_vid_out_overlay))
1848*4882a593Smuzhiyun break;
1849*4882a593Smuzhiyun CLEAR_AFTER_FIELD(p, fmt.win);
1850*4882a593Smuzhiyun return ops->vidioc_try_fmt_vid_out_overlay(file, fh, arg);
1851*4882a593Smuzhiyun case V4L2_BUF_TYPE_VBI_OUTPUT:
1852*4882a593Smuzhiyun if (unlikely(!ops->vidioc_try_fmt_vbi_out))
1853*4882a593Smuzhiyun break;
1854*4882a593Smuzhiyun CLEAR_AFTER_FIELD(p, fmt.vbi.flags);
1855*4882a593Smuzhiyun return ops->vidioc_try_fmt_vbi_out(file, fh, arg);
1856*4882a593Smuzhiyun case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
1857*4882a593Smuzhiyun if (unlikely(!ops->vidioc_try_fmt_sliced_vbi_out))
1858*4882a593Smuzhiyun break;
1859*4882a593Smuzhiyun CLEAR_AFTER_FIELD(p, fmt.sliced.io_size);
1860*4882a593Smuzhiyun return ops->vidioc_try_fmt_sliced_vbi_out(file, fh, arg);
1861*4882a593Smuzhiyun case V4L2_BUF_TYPE_SDR_CAPTURE:
1862*4882a593Smuzhiyun if (unlikely(!ops->vidioc_try_fmt_sdr_cap))
1863*4882a593Smuzhiyun break;
1864*4882a593Smuzhiyun CLEAR_AFTER_FIELD(p, fmt.sdr.buffersize);
1865*4882a593Smuzhiyun return ops->vidioc_try_fmt_sdr_cap(file, fh, arg);
1866*4882a593Smuzhiyun case V4L2_BUF_TYPE_SDR_OUTPUT:
1867*4882a593Smuzhiyun if (unlikely(!ops->vidioc_try_fmt_sdr_out))
1868*4882a593Smuzhiyun break;
1869*4882a593Smuzhiyun CLEAR_AFTER_FIELD(p, fmt.sdr.buffersize);
1870*4882a593Smuzhiyun return ops->vidioc_try_fmt_sdr_out(file, fh, arg);
1871*4882a593Smuzhiyun case V4L2_BUF_TYPE_META_CAPTURE:
1872*4882a593Smuzhiyun if (unlikely(!ops->vidioc_try_fmt_meta_cap))
1873*4882a593Smuzhiyun break;
1874*4882a593Smuzhiyun CLEAR_AFTER_FIELD(p, fmt.meta);
1875*4882a593Smuzhiyun return ops->vidioc_try_fmt_meta_cap(file, fh, arg);
1876*4882a593Smuzhiyun case V4L2_BUF_TYPE_META_OUTPUT:
1877*4882a593Smuzhiyun if (unlikely(!ops->vidioc_try_fmt_meta_out))
1878*4882a593Smuzhiyun break;
1879*4882a593Smuzhiyun CLEAR_AFTER_FIELD(p, fmt.meta);
1880*4882a593Smuzhiyun return ops->vidioc_try_fmt_meta_out(file, fh, arg);
1881*4882a593Smuzhiyun }
1882*4882a593Smuzhiyun return -EINVAL;
1883*4882a593Smuzhiyun }
1884*4882a593Smuzhiyun
v4l_streamon(const struct v4l2_ioctl_ops * ops,struct file * file,void * fh,void * arg)1885*4882a593Smuzhiyun static int v4l_streamon(const struct v4l2_ioctl_ops *ops,
1886*4882a593Smuzhiyun struct file *file, void *fh, void *arg)
1887*4882a593Smuzhiyun {
1888*4882a593Smuzhiyun return ops->vidioc_streamon(file, fh, *(unsigned int *)arg);
1889*4882a593Smuzhiyun }
1890*4882a593Smuzhiyun
v4l_streamoff(const struct v4l2_ioctl_ops * ops,struct file * file,void * fh,void * arg)1891*4882a593Smuzhiyun static int v4l_streamoff(const struct v4l2_ioctl_ops *ops,
1892*4882a593Smuzhiyun struct file *file, void *fh, void *arg)
1893*4882a593Smuzhiyun {
1894*4882a593Smuzhiyun return ops->vidioc_streamoff(file, fh, *(unsigned int *)arg);
1895*4882a593Smuzhiyun }
1896*4882a593Smuzhiyun
v4l_g_tuner(const struct v4l2_ioctl_ops * ops,struct file * file,void * fh,void * arg)1897*4882a593Smuzhiyun static int v4l_g_tuner(const struct v4l2_ioctl_ops *ops,
1898*4882a593Smuzhiyun struct file *file, void *fh, void *arg)
1899*4882a593Smuzhiyun {
1900*4882a593Smuzhiyun struct video_device *vfd = video_devdata(file);
1901*4882a593Smuzhiyun struct v4l2_tuner *p = arg;
1902*4882a593Smuzhiyun int err;
1903*4882a593Smuzhiyun
1904*4882a593Smuzhiyun p->type = (vfd->vfl_type == VFL_TYPE_RADIO) ?
1905*4882a593Smuzhiyun V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV;
1906*4882a593Smuzhiyun err = ops->vidioc_g_tuner(file, fh, p);
1907*4882a593Smuzhiyun if (!err)
1908*4882a593Smuzhiyun p->capability |= V4L2_TUNER_CAP_FREQ_BANDS;
1909*4882a593Smuzhiyun return err;
1910*4882a593Smuzhiyun }
1911*4882a593Smuzhiyun
v4l_s_tuner(const struct v4l2_ioctl_ops * ops,struct file * file,void * fh,void * arg)1912*4882a593Smuzhiyun static int v4l_s_tuner(const struct v4l2_ioctl_ops *ops,
1913*4882a593Smuzhiyun struct file *file, void *fh, void *arg)
1914*4882a593Smuzhiyun {
1915*4882a593Smuzhiyun struct video_device *vfd = video_devdata(file);
1916*4882a593Smuzhiyun struct v4l2_tuner *p = arg;
1917*4882a593Smuzhiyun int ret;
1918*4882a593Smuzhiyun
1919*4882a593Smuzhiyun ret = v4l_enable_media_source(vfd);
1920*4882a593Smuzhiyun if (ret)
1921*4882a593Smuzhiyun return ret;
1922*4882a593Smuzhiyun p->type = (vfd->vfl_type == VFL_TYPE_RADIO) ?
1923*4882a593Smuzhiyun V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV;
1924*4882a593Smuzhiyun return ops->vidioc_s_tuner(file, fh, p);
1925*4882a593Smuzhiyun }
1926*4882a593Smuzhiyun
v4l_g_modulator(const struct v4l2_ioctl_ops * ops,struct file * file,void * fh,void * arg)1927*4882a593Smuzhiyun static int v4l_g_modulator(const struct v4l2_ioctl_ops *ops,
1928*4882a593Smuzhiyun struct file *file, void *fh, void *arg)
1929*4882a593Smuzhiyun {
1930*4882a593Smuzhiyun struct video_device *vfd = video_devdata(file);
1931*4882a593Smuzhiyun struct v4l2_modulator *p = arg;
1932*4882a593Smuzhiyun int err;
1933*4882a593Smuzhiyun
1934*4882a593Smuzhiyun if (vfd->vfl_type == VFL_TYPE_RADIO)
1935*4882a593Smuzhiyun p->type = V4L2_TUNER_RADIO;
1936*4882a593Smuzhiyun
1937*4882a593Smuzhiyun err = ops->vidioc_g_modulator(file, fh, p);
1938*4882a593Smuzhiyun if (!err)
1939*4882a593Smuzhiyun p->capability |= V4L2_TUNER_CAP_FREQ_BANDS;
1940*4882a593Smuzhiyun return err;
1941*4882a593Smuzhiyun }
1942*4882a593Smuzhiyun
v4l_s_modulator(const struct v4l2_ioctl_ops * ops,struct file * file,void * fh,void * arg)1943*4882a593Smuzhiyun static int v4l_s_modulator(const struct v4l2_ioctl_ops *ops,
1944*4882a593Smuzhiyun struct file *file, void *fh, void *arg)
1945*4882a593Smuzhiyun {
1946*4882a593Smuzhiyun struct video_device *vfd = video_devdata(file);
1947*4882a593Smuzhiyun struct v4l2_modulator *p = arg;
1948*4882a593Smuzhiyun
1949*4882a593Smuzhiyun if (vfd->vfl_type == VFL_TYPE_RADIO)
1950*4882a593Smuzhiyun p->type = V4L2_TUNER_RADIO;
1951*4882a593Smuzhiyun
1952*4882a593Smuzhiyun return ops->vidioc_s_modulator(file, fh, p);
1953*4882a593Smuzhiyun }
1954*4882a593Smuzhiyun
v4l_g_frequency(const struct v4l2_ioctl_ops * ops,struct file * file,void * fh,void * arg)1955*4882a593Smuzhiyun static int v4l_g_frequency(const struct v4l2_ioctl_ops *ops,
1956*4882a593Smuzhiyun struct file *file, void *fh, void *arg)
1957*4882a593Smuzhiyun {
1958*4882a593Smuzhiyun struct video_device *vfd = video_devdata(file);
1959*4882a593Smuzhiyun struct v4l2_frequency *p = arg;
1960*4882a593Smuzhiyun
1961*4882a593Smuzhiyun if (vfd->vfl_type == VFL_TYPE_SDR)
1962*4882a593Smuzhiyun p->type = V4L2_TUNER_SDR;
1963*4882a593Smuzhiyun else
1964*4882a593Smuzhiyun p->type = (vfd->vfl_type == VFL_TYPE_RADIO) ?
1965*4882a593Smuzhiyun V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV;
1966*4882a593Smuzhiyun return ops->vidioc_g_frequency(file, fh, p);
1967*4882a593Smuzhiyun }
1968*4882a593Smuzhiyun
v4l_s_frequency(const struct v4l2_ioctl_ops * ops,struct file * file,void * fh,void * arg)1969*4882a593Smuzhiyun static int v4l_s_frequency(const struct v4l2_ioctl_ops *ops,
1970*4882a593Smuzhiyun struct file *file, void *fh, void *arg)
1971*4882a593Smuzhiyun {
1972*4882a593Smuzhiyun struct video_device *vfd = video_devdata(file);
1973*4882a593Smuzhiyun const struct v4l2_frequency *p = arg;
1974*4882a593Smuzhiyun enum v4l2_tuner_type type;
1975*4882a593Smuzhiyun int ret;
1976*4882a593Smuzhiyun
1977*4882a593Smuzhiyun ret = v4l_enable_media_source(vfd);
1978*4882a593Smuzhiyun if (ret)
1979*4882a593Smuzhiyun return ret;
1980*4882a593Smuzhiyun if (vfd->vfl_type == VFL_TYPE_SDR) {
1981*4882a593Smuzhiyun if (p->type != V4L2_TUNER_SDR && p->type != V4L2_TUNER_RF)
1982*4882a593Smuzhiyun return -EINVAL;
1983*4882a593Smuzhiyun } else {
1984*4882a593Smuzhiyun type = (vfd->vfl_type == VFL_TYPE_RADIO) ?
1985*4882a593Smuzhiyun V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV;
1986*4882a593Smuzhiyun if (type != p->type)
1987*4882a593Smuzhiyun return -EINVAL;
1988*4882a593Smuzhiyun }
1989*4882a593Smuzhiyun return ops->vidioc_s_frequency(file, fh, p);
1990*4882a593Smuzhiyun }
1991*4882a593Smuzhiyun
v4l_enumstd(const struct v4l2_ioctl_ops * ops,struct file * file,void * fh,void * arg)1992*4882a593Smuzhiyun static int v4l_enumstd(const struct v4l2_ioctl_ops *ops,
1993*4882a593Smuzhiyun struct file *file, void *fh, void *arg)
1994*4882a593Smuzhiyun {
1995*4882a593Smuzhiyun struct video_device *vfd = video_devdata(file);
1996*4882a593Smuzhiyun struct v4l2_standard *p = arg;
1997*4882a593Smuzhiyun
1998*4882a593Smuzhiyun return v4l_video_std_enumstd(p, vfd->tvnorms);
1999*4882a593Smuzhiyun }
2000*4882a593Smuzhiyun
v4l_s_std(const struct v4l2_ioctl_ops * ops,struct file * file,void * fh,void * arg)2001*4882a593Smuzhiyun static int v4l_s_std(const struct v4l2_ioctl_ops *ops,
2002*4882a593Smuzhiyun struct file *file, void *fh, void *arg)
2003*4882a593Smuzhiyun {
2004*4882a593Smuzhiyun struct video_device *vfd = video_devdata(file);
2005*4882a593Smuzhiyun v4l2_std_id id = *(v4l2_std_id *)arg, norm;
2006*4882a593Smuzhiyun int ret;
2007*4882a593Smuzhiyun
2008*4882a593Smuzhiyun ret = v4l_enable_media_source(vfd);
2009*4882a593Smuzhiyun if (ret)
2010*4882a593Smuzhiyun return ret;
2011*4882a593Smuzhiyun norm = id & vfd->tvnorms;
2012*4882a593Smuzhiyun if (vfd->tvnorms && !norm) /* Check if std is supported */
2013*4882a593Smuzhiyun return -EINVAL;
2014*4882a593Smuzhiyun
2015*4882a593Smuzhiyun /* Calls the specific handler */
2016*4882a593Smuzhiyun return ops->vidioc_s_std(file, fh, norm);
2017*4882a593Smuzhiyun }
2018*4882a593Smuzhiyun
v4l_querystd(const struct v4l2_ioctl_ops * ops,struct file * file,void * fh,void * arg)2019*4882a593Smuzhiyun static int v4l_querystd(const struct v4l2_ioctl_ops *ops,
2020*4882a593Smuzhiyun struct file *file, void *fh, void *arg)
2021*4882a593Smuzhiyun {
2022*4882a593Smuzhiyun struct video_device *vfd = video_devdata(file);
2023*4882a593Smuzhiyun v4l2_std_id *p = arg;
2024*4882a593Smuzhiyun int ret;
2025*4882a593Smuzhiyun
2026*4882a593Smuzhiyun ret = v4l_enable_media_source(vfd);
2027*4882a593Smuzhiyun if (ret)
2028*4882a593Smuzhiyun return ret;
2029*4882a593Smuzhiyun /*
2030*4882a593Smuzhiyun * If no signal is detected, then the driver should return
2031*4882a593Smuzhiyun * V4L2_STD_UNKNOWN. Otherwise it should return tvnorms with
2032*4882a593Smuzhiyun * any standards that do not apply removed.
2033*4882a593Smuzhiyun *
2034*4882a593Smuzhiyun * This means that tuners, audio and video decoders can join
2035*4882a593Smuzhiyun * their efforts to improve the standards detection.
2036*4882a593Smuzhiyun */
2037*4882a593Smuzhiyun *p = vfd->tvnorms;
2038*4882a593Smuzhiyun return ops->vidioc_querystd(file, fh, arg);
2039*4882a593Smuzhiyun }
2040*4882a593Smuzhiyun
v4l_s_hw_freq_seek(const struct v4l2_ioctl_ops * ops,struct file * file,void * fh,void * arg)2041*4882a593Smuzhiyun static int v4l_s_hw_freq_seek(const struct v4l2_ioctl_ops *ops,
2042*4882a593Smuzhiyun struct file *file, void *fh, void *arg)
2043*4882a593Smuzhiyun {
2044*4882a593Smuzhiyun struct video_device *vfd = video_devdata(file);
2045*4882a593Smuzhiyun struct v4l2_hw_freq_seek *p = arg;
2046*4882a593Smuzhiyun enum v4l2_tuner_type type;
2047*4882a593Smuzhiyun int ret;
2048*4882a593Smuzhiyun
2049*4882a593Smuzhiyun ret = v4l_enable_media_source(vfd);
2050*4882a593Smuzhiyun if (ret)
2051*4882a593Smuzhiyun return ret;
2052*4882a593Smuzhiyun /* s_hw_freq_seek is not supported for SDR for now */
2053*4882a593Smuzhiyun if (vfd->vfl_type == VFL_TYPE_SDR)
2054*4882a593Smuzhiyun return -EINVAL;
2055*4882a593Smuzhiyun
2056*4882a593Smuzhiyun type = (vfd->vfl_type == VFL_TYPE_RADIO) ?
2057*4882a593Smuzhiyun V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV;
2058*4882a593Smuzhiyun if (p->type != type)
2059*4882a593Smuzhiyun return -EINVAL;
2060*4882a593Smuzhiyun return ops->vidioc_s_hw_freq_seek(file, fh, p);
2061*4882a593Smuzhiyun }
2062*4882a593Smuzhiyun
v4l_overlay(const struct v4l2_ioctl_ops * ops,struct file * file,void * fh,void * arg)2063*4882a593Smuzhiyun static int v4l_overlay(const struct v4l2_ioctl_ops *ops,
2064*4882a593Smuzhiyun struct file *file, void *fh, void *arg)
2065*4882a593Smuzhiyun {
2066*4882a593Smuzhiyun return ops->vidioc_overlay(file, fh, *(unsigned int *)arg);
2067*4882a593Smuzhiyun }
2068*4882a593Smuzhiyun
v4l_reqbufs(const struct v4l2_ioctl_ops * ops,struct file * file,void * fh,void * arg)2069*4882a593Smuzhiyun static int v4l_reqbufs(const struct v4l2_ioctl_ops *ops,
2070*4882a593Smuzhiyun struct file *file, void *fh, void *arg)
2071*4882a593Smuzhiyun {
2072*4882a593Smuzhiyun struct v4l2_requestbuffers *p = arg;
2073*4882a593Smuzhiyun int ret = check_fmt(file, p->type);
2074*4882a593Smuzhiyun
2075*4882a593Smuzhiyun if (ret)
2076*4882a593Smuzhiyun return ret;
2077*4882a593Smuzhiyun
2078*4882a593Smuzhiyun CLEAR_AFTER_FIELD(p, capabilities);
2079*4882a593Smuzhiyun
2080*4882a593Smuzhiyun return ops->vidioc_reqbufs(file, fh, p);
2081*4882a593Smuzhiyun }
2082*4882a593Smuzhiyun
v4l_querybuf(const struct v4l2_ioctl_ops * ops,struct file * file,void * fh,void * arg)2083*4882a593Smuzhiyun static int v4l_querybuf(const struct v4l2_ioctl_ops *ops,
2084*4882a593Smuzhiyun struct file *file, void *fh, void *arg)
2085*4882a593Smuzhiyun {
2086*4882a593Smuzhiyun struct v4l2_buffer *p = arg;
2087*4882a593Smuzhiyun int ret = check_fmt(file, p->type);
2088*4882a593Smuzhiyun
2089*4882a593Smuzhiyun return ret ? ret : ops->vidioc_querybuf(file, fh, p);
2090*4882a593Smuzhiyun }
2091*4882a593Smuzhiyun
v4l_qbuf(const struct v4l2_ioctl_ops * ops,struct file * file,void * fh,void * arg)2092*4882a593Smuzhiyun static int v4l_qbuf(const struct v4l2_ioctl_ops *ops,
2093*4882a593Smuzhiyun struct file *file, void *fh, void *arg)
2094*4882a593Smuzhiyun {
2095*4882a593Smuzhiyun struct v4l2_buffer *p = arg;
2096*4882a593Smuzhiyun int ret = check_fmt(file, p->type);
2097*4882a593Smuzhiyun
2098*4882a593Smuzhiyun return ret ? ret : ops->vidioc_qbuf(file, fh, p);
2099*4882a593Smuzhiyun }
2100*4882a593Smuzhiyun
v4l_dqbuf(const struct v4l2_ioctl_ops * ops,struct file * file,void * fh,void * arg)2101*4882a593Smuzhiyun static int v4l_dqbuf(const struct v4l2_ioctl_ops *ops,
2102*4882a593Smuzhiyun struct file *file, void *fh, void *arg)
2103*4882a593Smuzhiyun {
2104*4882a593Smuzhiyun struct v4l2_buffer *p = arg;
2105*4882a593Smuzhiyun int ret = check_fmt(file, p->type);
2106*4882a593Smuzhiyun
2107*4882a593Smuzhiyun return ret ? ret : ops->vidioc_dqbuf(file, fh, p);
2108*4882a593Smuzhiyun }
2109*4882a593Smuzhiyun
v4l_create_bufs(const struct v4l2_ioctl_ops * ops,struct file * file,void * fh,void * arg)2110*4882a593Smuzhiyun static int v4l_create_bufs(const struct v4l2_ioctl_ops *ops,
2111*4882a593Smuzhiyun struct file *file, void *fh, void *arg)
2112*4882a593Smuzhiyun {
2113*4882a593Smuzhiyun struct v4l2_create_buffers *create = arg;
2114*4882a593Smuzhiyun int ret = check_fmt(file, create->format.type);
2115*4882a593Smuzhiyun
2116*4882a593Smuzhiyun if (ret)
2117*4882a593Smuzhiyun return ret;
2118*4882a593Smuzhiyun
2119*4882a593Smuzhiyun CLEAR_AFTER_FIELD(create, capabilities);
2120*4882a593Smuzhiyun
2121*4882a593Smuzhiyun v4l_sanitize_format(&create->format);
2122*4882a593Smuzhiyun
2123*4882a593Smuzhiyun ret = ops->vidioc_create_bufs(file, fh, create);
2124*4882a593Smuzhiyun
2125*4882a593Smuzhiyun if (create->format.type == V4L2_BUF_TYPE_VIDEO_CAPTURE ||
2126*4882a593Smuzhiyun create->format.type == V4L2_BUF_TYPE_VIDEO_OUTPUT)
2127*4882a593Smuzhiyun create->format.fmt.pix.priv = V4L2_PIX_FMT_PRIV_MAGIC;
2128*4882a593Smuzhiyun
2129*4882a593Smuzhiyun return ret;
2130*4882a593Smuzhiyun }
2131*4882a593Smuzhiyun
v4l_prepare_buf(const struct v4l2_ioctl_ops * ops,struct file * file,void * fh,void * arg)2132*4882a593Smuzhiyun static int v4l_prepare_buf(const struct v4l2_ioctl_ops *ops,
2133*4882a593Smuzhiyun struct file *file, void *fh, void *arg)
2134*4882a593Smuzhiyun {
2135*4882a593Smuzhiyun struct v4l2_buffer *b = arg;
2136*4882a593Smuzhiyun int ret = check_fmt(file, b->type);
2137*4882a593Smuzhiyun
2138*4882a593Smuzhiyun return ret ? ret : ops->vidioc_prepare_buf(file, fh, b);
2139*4882a593Smuzhiyun }
2140*4882a593Smuzhiyun
v4l_g_parm(const struct v4l2_ioctl_ops * ops,struct file * file,void * fh,void * arg)2141*4882a593Smuzhiyun static int v4l_g_parm(const struct v4l2_ioctl_ops *ops,
2142*4882a593Smuzhiyun struct file *file, void *fh, void *arg)
2143*4882a593Smuzhiyun {
2144*4882a593Smuzhiyun struct video_device *vfd = video_devdata(file);
2145*4882a593Smuzhiyun struct v4l2_streamparm *p = arg;
2146*4882a593Smuzhiyun v4l2_std_id std;
2147*4882a593Smuzhiyun int ret = check_fmt(file, p->type);
2148*4882a593Smuzhiyun
2149*4882a593Smuzhiyun if (ret)
2150*4882a593Smuzhiyun return ret;
2151*4882a593Smuzhiyun if (ops->vidioc_g_parm)
2152*4882a593Smuzhiyun return ops->vidioc_g_parm(file, fh, p);
2153*4882a593Smuzhiyun if (p->type != V4L2_BUF_TYPE_VIDEO_CAPTURE &&
2154*4882a593Smuzhiyun p->type != V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
2155*4882a593Smuzhiyun return -EINVAL;
2156*4882a593Smuzhiyun if (vfd->device_caps & V4L2_CAP_READWRITE)
2157*4882a593Smuzhiyun p->parm.capture.readbuffers = 2;
2158*4882a593Smuzhiyun ret = ops->vidioc_g_std(file, fh, &std);
2159*4882a593Smuzhiyun if (ret == 0)
2160*4882a593Smuzhiyun v4l2_video_std_frame_period(std, &p->parm.capture.timeperframe);
2161*4882a593Smuzhiyun return ret;
2162*4882a593Smuzhiyun }
2163*4882a593Smuzhiyun
v4l_s_parm(const struct v4l2_ioctl_ops * ops,struct file * file,void * fh,void * arg)2164*4882a593Smuzhiyun static int v4l_s_parm(const struct v4l2_ioctl_ops *ops,
2165*4882a593Smuzhiyun struct file *file, void *fh, void *arg)
2166*4882a593Smuzhiyun {
2167*4882a593Smuzhiyun struct v4l2_streamparm *p = arg;
2168*4882a593Smuzhiyun int ret = check_fmt(file, p->type);
2169*4882a593Smuzhiyun
2170*4882a593Smuzhiyun if (ret)
2171*4882a593Smuzhiyun return ret;
2172*4882a593Smuzhiyun
2173*4882a593Smuzhiyun /* Note: extendedmode is never used in drivers */
2174*4882a593Smuzhiyun if (V4L2_TYPE_IS_OUTPUT(p->type)) {
2175*4882a593Smuzhiyun memset(p->parm.output.reserved, 0,
2176*4882a593Smuzhiyun sizeof(p->parm.output.reserved));
2177*4882a593Smuzhiyun p->parm.output.extendedmode = 0;
2178*4882a593Smuzhiyun p->parm.output.outputmode &= V4L2_MODE_HIGHQUALITY;
2179*4882a593Smuzhiyun } else {
2180*4882a593Smuzhiyun memset(p->parm.capture.reserved, 0,
2181*4882a593Smuzhiyun sizeof(p->parm.capture.reserved));
2182*4882a593Smuzhiyun p->parm.capture.extendedmode = 0;
2183*4882a593Smuzhiyun p->parm.capture.capturemode &= V4L2_MODE_HIGHQUALITY;
2184*4882a593Smuzhiyun }
2185*4882a593Smuzhiyun return ops->vidioc_s_parm(file, fh, p);
2186*4882a593Smuzhiyun }
2187*4882a593Smuzhiyun
v4l_queryctrl(const struct v4l2_ioctl_ops * ops,struct file * file,void * fh,void * arg)2188*4882a593Smuzhiyun static int v4l_queryctrl(const struct v4l2_ioctl_ops *ops,
2189*4882a593Smuzhiyun struct file *file, void *fh, void *arg)
2190*4882a593Smuzhiyun {
2191*4882a593Smuzhiyun struct video_device *vfd = video_devdata(file);
2192*4882a593Smuzhiyun struct v4l2_queryctrl *p = arg;
2193*4882a593Smuzhiyun struct v4l2_fh *vfh =
2194*4882a593Smuzhiyun test_bit(V4L2_FL_USES_V4L2_FH, &vfd->flags) ? fh : NULL;
2195*4882a593Smuzhiyun
2196*4882a593Smuzhiyun if (vfh && vfh->ctrl_handler)
2197*4882a593Smuzhiyun return v4l2_queryctrl(vfh->ctrl_handler, p);
2198*4882a593Smuzhiyun if (vfd->ctrl_handler)
2199*4882a593Smuzhiyun return v4l2_queryctrl(vfd->ctrl_handler, p);
2200*4882a593Smuzhiyun if (ops->vidioc_queryctrl)
2201*4882a593Smuzhiyun return ops->vidioc_queryctrl(file, fh, p);
2202*4882a593Smuzhiyun return -ENOTTY;
2203*4882a593Smuzhiyun }
2204*4882a593Smuzhiyun
v4l_query_ext_ctrl(const struct v4l2_ioctl_ops * ops,struct file * file,void * fh,void * arg)2205*4882a593Smuzhiyun static int v4l_query_ext_ctrl(const struct v4l2_ioctl_ops *ops,
2206*4882a593Smuzhiyun struct file *file, void *fh, void *arg)
2207*4882a593Smuzhiyun {
2208*4882a593Smuzhiyun struct video_device *vfd = video_devdata(file);
2209*4882a593Smuzhiyun struct v4l2_query_ext_ctrl *p = arg;
2210*4882a593Smuzhiyun struct v4l2_fh *vfh =
2211*4882a593Smuzhiyun test_bit(V4L2_FL_USES_V4L2_FH, &vfd->flags) ? fh : NULL;
2212*4882a593Smuzhiyun
2213*4882a593Smuzhiyun if (vfh && vfh->ctrl_handler)
2214*4882a593Smuzhiyun return v4l2_query_ext_ctrl(vfh->ctrl_handler, p);
2215*4882a593Smuzhiyun if (vfd->ctrl_handler)
2216*4882a593Smuzhiyun return v4l2_query_ext_ctrl(vfd->ctrl_handler, p);
2217*4882a593Smuzhiyun if (ops->vidioc_query_ext_ctrl)
2218*4882a593Smuzhiyun return ops->vidioc_query_ext_ctrl(file, fh, p);
2219*4882a593Smuzhiyun return -ENOTTY;
2220*4882a593Smuzhiyun }
2221*4882a593Smuzhiyun
v4l_querymenu(const struct v4l2_ioctl_ops * ops,struct file * file,void * fh,void * arg)2222*4882a593Smuzhiyun static int v4l_querymenu(const struct v4l2_ioctl_ops *ops,
2223*4882a593Smuzhiyun struct file *file, void *fh, void *arg)
2224*4882a593Smuzhiyun {
2225*4882a593Smuzhiyun struct video_device *vfd = video_devdata(file);
2226*4882a593Smuzhiyun struct v4l2_querymenu *p = arg;
2227*4882a593Smuzhiyun struct v4l2_fh *vfh =
2228*4882a593Smuzhiyun test_bit(V4L2_FL_USES_V4L2_FH, &vfd->flags) ? fh : NULL;
2229*4882a593Smuzhiyun
2230*4882a593Smuzhiyun if (vfh && vfh->ctrl_handler)
2231*4882a593Smuzhiyun return v4l2_querymenu(vfh->ctrl_handler, p);
2232*4882a593Smuzhiyun if (vfd->ctrl_handler)
2233*4882a593Smuzhiyun return v4l2_querymenu(vfd->ctrl_handler, p);
2234*4882a593Smuzhiyun if (ops->vidioc_querymenu)
2235*4882a593Smuzhiyun return ops->vidioc_querymenu(file, fh, p);
2236*4882a593Smuzhiyun return -ENOTTY;
2237*4882a593Smuzhiyun }
2238*4882a593Smuzhiyun
v4l_g_ctrl(const struct v4l2_ioctl_ops * ops,struct file * file,void * fh,void * arg)2239*4882a593Smuzhiyun static int v4l_g_ctrl(const struct v4l2_ioctl_ops *ops,
2240*4882a593Smuzhiyun struct file *file, void *fh, void *arg)
2241*4882a593Smuzhiyun {
2242*4882a593Smuzhiyun struct video_device *vfd = video_devdata(file);
2243*4882a593Smuzhiyun struct v4l2_control *p = arg;
2244*4882a593Smuzhiyun struct v4l2_fh *vfh =
2245*4882a593Smuzhiyun test_bit(V4L2_FL_USES_V4L2_FH, &vfd->flags) ? fh : NULL;
2246*4882a593Smuzhiyun struct v4l2_ext_controls ctrls;
2247*4882a593Smuzhiyun struct v4l2_ext_control ctrl;
2248*4882a593Smuzhiyun
2249*4882a593Smuzhiyun if (vfh && vfh->ctrl_handler)
2250*4882a593Smuzhiyun return v4l2_g_ctrl(vfh->ctrl_handler, p);
2251*4882a593Smuzhiyun if (vfd->ctrl_handler)
2252*4882a593Smuzhiyun return v4l2_g_ctrl(vfd->ctrl_handler, p);
2253*4882a593Smuzhiyun if (ops->vidioc_g_ctrl)
2254*4882a593Smuzhiyun return ops->vidioc_g_ctrl(file, fh, p);
2255*4882a593Smuzhiyun if (ops->vidioc_g_ext_ctrls == NULL)
2256*4882a593Smuzhiyun return -ENOTTY;
2257*4882a593Smuzhiyun
2258*4882a593Smuzhiyun ctrls.which = V4L2_CTRL_ID2WHICH(p->id);
2259*4882a593Smuzhiyun ctrls.count = 1;
2260*4882a593Smuzhiyun ctrls.controls = &ctrl;
2261*4882a593Smuzhiyun ctrl.id = p->id;
2262*4882a593Smuzhiyun ctrl.value = p->value;
2263*4882a593Smuzhiyun if (check_ext_ctrls(&ctrls, VIDIOC_G_CTRL)) {
2264*4882a593Smuzhiyun int ret = ops->vidioc_g_ext_ctrls(file, fh, &ctrls);
2265*4882a593Smuzhiyun
2266*4882a593Smuzhiyun if (ret == 0)
2267*4882a593Smuzhiyun p->value = ctrl.value;
2268*4882a593Smuzhiyun return ret;
2269*4882a593Smuzhiyun }
2270*4882a593Smuzhiyun return -EINVAL;
2271*4882a593Smuzhiyun }
2272*4882a593Smuzhiyun
v4l_s_ctrl(const struct v4l2_ioctl_ops * ops,struct file * file,void * fh,void * arg)2273*4882a593Smuzhiyun static int v4l_s_ctrl(const struct v4l2_ioctl_ops *ops,
2274*4882a593Smuzhiyun struct file *file, void *fh, void *arg)
2275*4882a593Smuzhiyun {
2276*4882a593Smuzhiyun struct video_device *vfd = video_devdata(file);
2277*4882a593Smuzhiyun struct v4l2_control *p = arg;
2278*4882a593Smuzhiyun struct v4l2_fh *vfh =
2279*4882a593Smuzhiyun test_bit(V4L2_FL_USES_V4L2_FH, &vfd->flags) ? fh : NULL;
2280*4882a593Smuzhiyun struct v4l2_ext_controls ctrls;
2281*4882a593Smuzhiyun struct v4l2_ext_control ctrl;
2282*4882a593Smuzhiyun int ret;
2283*4882a593Smuzhiyun
2284*4882a593Smuzhiyun if (vfh && vfh->ctrl_handler)
2285*4882a593Smuzhiyun return v4l2_s_ctrl(vfh, vfh->ctrl_handler, p);
2286*4882a593Smuzhiyun if (vfd->ctrl_handler)
2287*4882a593Smuzhiyun return v4l2_s_ctrl(NULL, vfd->ctrl_handler, p);
2288*4882a593Smuzhiyun if (ops->vidioc_s_ctrl)
2289*4882a593Smuzhiyun return ops->vidioc_s_ctrl(file, fh, p);
2290*4882a593Smuzhiyun if (ops->vidioc_s_ext_ctrls == NULL)
2291*4882a593Smuzhiyun return -ENOTTY;
2292*4882a593Smuzhiyun
2293*4882a593Smuzhiyun ctrls.which = V4L2_CTRL_ID2WHICH(p->id);
2294*4882a593Smuzhiyun ctrls.count = 1;
2295*4882a593Smuzhiyun ctrls.controls = &ctrl;
2296*4882a593Smuzhiyun ctrl.id = p->id;
2297*4882a593Smuzhiyun ctrl.value = p->value;
2298*4882a593Smuzhiyun if (!check_ext_ctrls(&ctrls, VIDIOC_S_CTRL))
2299*4882a593Smuzhiyun return -EINVAL;
2300*4882a593Smuzhiyun ret = ops->vidioc_s_ext_ctrls(file, fh, &ctrls);
2301*4882a593Smuzhiyun p->value = ctrl.value;
2302*4882a593Smuzhiyun return ret;
2303*4882a593Smuzhiyun }
2304*4882a593Smuzhiyun
v4l_g_ext_ctrls(const struct v4l2_ioctl_ops * ops,struct file * file,void * fh,void * arg)2305*4882a593Smuzhiyun static int v4l_g_ext_ctrls(const struct v4l2_ioctl_ops *ops,
2306*4882a593Smuzhiyun struct file *file, void *fh, void *arg)
2307*4882a593Smuzhiyun {
2308*4882a593Smuzhiyun struct video_device *vfd = video_devdata(file);
2309*4882a593Smuzhiyun struct v4l2_ext_controls *p = arg;
2310*4882a593Smuzhiyun struct v4l2_fh *vfh =
2311*4882a593Smuzhiyun test_bit(V4L2_FL_USES_V4L2_FH, &vfd->flags) ? fh : NULL;
2312*4882a593Smuzhiyun
2313*4882a593Smuzhiyun p->error_idx = p->count;
2314*4882a593Smuzhiyun if (vfh && vfh->ctrl_handler)
2315*4882a593Smuzhiyun return v4l2_g_ext_ctrls(vfh->ctrl_handler,
2316*4882a593Smuzhiyun vfd, vfd->v4l2_dev->mdev, p);
2317*4882a593Smuzhiyun if (vfd->ctrl_handler)
2318*4882a593Smuzhiyun return v4l2_g_ext_ctrls(vfd->ctrl_handler,
2319*4882a593Smuzhiyun vfd, vfd->v4l2_dev->mdev, p);
2320*4882a593Smuzhiyun if (ops->vidioc_g_ext_ctrls == NULL)
2321*4882a593Smuzhiyun return -ENOTTY;
2322*4882a593Smuzhiyun return check_ext_ctrls(p, VIDIOC_G_EXT_CTRLS) ?
2323*4882a593Smuzhiyun ops->vidioc_g_ext_ctrls(file, fh, p) : -EINVAL;
2324*4882a593Smuzhiyun }
2325*4882a593Smuzhiyun
v4l_s_ext_ctrls(const struct v4l2_ioctl_ops * ops,struct file * file,void * fh,void * arg)2326*4882a593Smuzhiyun static int v4l_s_ext_ctrls(const struct v4l2_ioctl_ops *ops,
2327*4882a593Smuzhiyun struct file *file, void *fh, void *arg)
2328*4882a593Smuzhiyun {
2329*4882a593Smuzhiyun struct video_device *vfd = video_devdata(file);
2330*4882a593Smuzhiyun struct v4l2_ext_controls *p = arg;
2331*4882a593Smuzhiyun struct v4l2_fh *vfh =
2332*4882a593Smuzhiyun test_bit(V4L2_FL_USES_V4L2_FH, &vfd->flags) ? fh : NULL;
2333*4882a593Smuzhiyun
2334*4882a593Smuzhiyun p->error_idx = p->count;
2335*4882a593Smuzhiyun if (vfh && vfh->ctrl_handler)
2336*4882a593Smuzhiyun return v4l2_s_ext_ctrls(vfh, vfh->ctrl_handler,
2337*4882a593Smuzhiyun vfd, vfd->v4l2_dev->mdev, p);
2338*4882a593Smuzhiyun if (vfd->ctrl_handler)
2339*4882a593Smuzhiyun return v4l2_s_ext_ctrls(NULL, vfd->ctrl_handler,
2340*4882a593Smuzhiyun vfd, vfd->v4l2_dev->mdev, p);
2341*4882a593Smuzhiyun if (ops->vidioc_s_ext_ctrls == NULL)
2342*4882a593Smuzhiyun return -ENOTTY;
2343*4882a593Smuzhiyun return check_ext_ctrls(p, VIDIOC_S_EXT_CTRLS) ?
2344*4882a593Smuzhiyun ops->vidioc_s_ext_ctrls(file, fh, p) : -EINVAL;
2345*4882a593Smuzhiyun }
2346*4882a593Smuzhiyun
v4l_try_ext_ctrls(const struct v4l2_ioctl_ops * ops,struct file * file,void * fh,void * arg)2347*4882a593Smuzhiyun static int v4l_try_ext_ctrls(const struct v4l2_ioctl_ops *ops,
2348*4882a593Smuzhiyun struct file *file, void *fh, void *arg)
2349*4882a593Smuzhiyun {
2350*4882a593Smuzhiyun struct video_device *vfd = video_devdata(file);
2351*4882a593Smuzhiyun struct v4l2_ext_controls *p = arg;
2352*4882a593Smuzhiyun struct v4l2_fh *vfh =
2353*4882a593Smuzhiyun test_bit(V4L2_FL_USES_V4L2_FH, &vfd->flags) ? fh : NULL;
2354*4882a593Smuzhiyun
2355*4882a593Smuzhiyun p->error_idx = p->count;
2356*4882a593Smuzhiyun if (vfh && vfh->ctrl_handler)
2357*4882a593Smuzhiyun return v4l2_try_ext_ctrls(vfh->ctrl_handler,
2358*4882a593Smuzhiyun vfd, vfd->v4l2_dev->mdev, p);
2359*4882a593Smuzhiyun if (vfd->ctrl_handler)
2360*4882a593Smuzhiyun return v4l2_try_ext_ctrls(vfd->ctrl_handler,
2361*4882a593Smuzhiyun vfd, vfd->v4l2_dev->mdev, p);
2362*4882a593Smuzhiyun if (ops->vidioc_try_ext_ctrls == NULL)
2363*4882a593Smuzhiyun return -ENOTTY;
2364*4882a593Smuzhiyun return check_ext_ctrls(p, VIDIOC_TRY_EXT_CTRLS) ?
2365*4882a593Smuzhiyun ops->vidioc_try_ext_ctrls(file, fh, p) : -EINVAL;
2366*4882a593Smuzhiyun }
2367*4882a593Smuzhiyun
2368*4882a593Smuzhiyun /*
2369*4882a593Smuzhiyun * The selection API specified originally that the _MPLANE buffer types
2370*4882a593Smuzhiyun * shouldn't be used. The reasons for this are lost in the mists of time
2371*4882a593Smuzhiyun * (or just really crappy memories). Regardless, this is really annoying
2372*4882a593Smuzhiyun * for userspace. So to keep things simple we map _MPLANE buffer types
2373*4882a593Smuzhiyun * to their 'regular' counterparts before calling the driver. And we
2374*4882a593Smuzhiyun * restore it afterwards. This way applications can use either buffer
2375*4882a593Smuzhiyun * type and drivers don't need to check for both.
2376*4882a593Smuzhiyun */
v4l_g_selection(const struct v4l2_ioctl_ops * ops,struct file * file,void * fh,void * arg)2377*4882a593Smuzhiyun static int v4l_g_selection(const struct v4l2_ioctl_ops *ops,
2378*4882a593Smuzhiyun struct file *file, void *fh, void *arg)
2379*4882a593Smuzhiyun {
2380*4882a593Smuzhiyun struct v4l2_selection *p = arg;
2381*4882a593Smuzhiyun u32 old_type = p->type;
2382*4882a593Smuzhiyun int ret;
2383*4882a593Smuzhiyun
2384*4882a593Smuzhiyun if (p->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
2385*4882a593Smuzhiyun p->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
2386*4882a593Smuzhiyun else if (p->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)
2387*4882a593Smuzhiyun p->type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
2388*4882a593Smuzhiyun ret = ops->vidioc_g_selection(file, fh, p);
2389*4882a593Smuzhiyun p->type = old_type;
2390*4882a593Smuzhiyun return ret;
2391*4882a593Smuzhiyun }
2392*4882a593Smuzhiyun
v4l_s_selection(const struct v4l2_ioctl_ops * ops,struct file * file,void * fh,void * arg)2393*4882a593Smuzhiyun static int v4l_s_selection(const struct v4l2_ioctl_ops *ops,
2394*4882a593Smuzhiyun struct file *file, void *fh, void *arg)
2395*4882a593Smuzhiyun {
2396*4882a593Smuzhiyun struct v4l2_selection *p = arg;
2397*4882a593Smuzhiyun u32 old_type = p->type;
2398*4882a593Smuzhiyun int ret;
2399*4882a593Smuzhiyun
2400*4882a593Smuzhiyun if (p->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
2401*4882a593Smuzhiyun p->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
2402*4882a593Smuzhiyun else if (p->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)
2403*4882a593Smuzhiyun p->type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
2404*4882a593Smuzhiyun ret = ops->vidioc_s_selection(file, fh, p);
2405*4882a593Smuzhiyun p->type = old_type;
2406*4882a593Smuzhiyun return ret;
2407*4882a593Smuzhiyun }
2408*4882a593Smuzhiyun
v4l_g_crop(const struct v4l2_ioctl_ops * ops,struct file * file,void * fh,void * arg)2409*4882a593Smuzhiyun static int v4l_g_crop(const struct v4l2_ioctl_ops *ops,
2410*4882a593Smuzhiyun struct file *file, void *fh, void *arg)
2411*4882a593Smuzhiyun {
2412*4882a593Smuzhiyun struct video_device *vfd = video_devdata(file);
2413*4882a593Smuzhiyun struct v4l2_crop *p = arg;
2414*4882a593Smuzhiyun struct v4l2_selection s = {
2415*4882a593Smuzhiyun .type = p->type,
2416*4882a593Smuzhiyun };
2417*4882a593Smuzhiyun int ret;
2418*4882a593Smuzhiyun
2419*4882a593Smuzhiyun /* simulate capture crop using selection api */
2420*4882a593Smuzhiyun
2421*4882a593Smuzhiyun /* crop means compose for output devices */
2422*4882a593Smuzhiyun if (V4L2_TYPE_IS_OUTPUT(p->type))
2423*4882a593Smuzhiyun s.target = V4L2_SEL_TGT_COMPOSE;
2424*4882a593Smuzhiyun else
2425*4882a593Smuzhiyun s.target = V4L2_SEL_TGT_CROP;
2426*4882a593Smuzhiyun
2427*4882a593Smuzhiyun if (test_bit(V4L2_FL_QUIRK_INVERTED_CROP, &vfd->flags))
2428*4882a593Smuzhiyun s.target = s.target == V4L2_SEL_TGT_COMPOSE ?
2429*4882a593Smuzhiyun V4L2_SEL_TGT_CROP : V4L2_SEL_TGT_COMPOSE;
2430*4882a593Smuzhiyun
2431*4882a593Smuzhiyun ret = v4l_g_selection(ops, file, fh, &s);
2432*4882a593Smuzhiyun
2433*4882a593Smuzhiyun /* copying results to old structure on success */
2434*4882a593Smuzhiyun if (!ret)
2435*4882a593Smuzhiyun p->c = s.r;
2436*4882a593Smuzhiyun return ret;
2437*4882a593Smuzhiyun }
2438*4882a593Smuzhiyun
v4l_s_crop(const struct v4l2_ioctl_ops * ops,struct file * file,void * fh,void * arg)2439*4882a593Smuzhiyun static int v4l_s_crop(const struct v4l2_ioctl_ops *ops,
2440*4882a593Smuzhiyun struct file *file, void *fh, void *arg)
2441*4882a593Smuzhiyun {
2442*4882a593Smuzhiyun struct video_device *vfd = video_devdata(file);
2443*4882a593Smuzhiyun struct v4l2_crop *p = arg;
2444*4882a593Smuzhiyun struct v4l2_selection s = {
2445*4882a593Smuzhiyun .type = p->type,
2446*4882a593Smuzhiyun .r = p->c,
2447*4882a593Smuzhiyun };
2448*4882a593Smuzhiyun
2449*4882a593Smuzhiyun /* simulate capture crop using selection api */
2450*4882a593Smuzhiyun
2451*4882a593Smuzhiyun /* crop means compose for output devices */
2452*4882a593Smuzhiyun if (V4L2_TYPE_IS_OUTPUT(p->type))
2453*4882a593Smuzhiyun s.target = V4L2_SEL_TGT_COMPOSE;
2454*4882a593Smuzhiyun else
2455*4882a593Smuzhiyun s.target = V4L2_SEL_TGT_CROP;
2456*4882a593Smuzhiyun
2457*4882a593Smuzhiyun if (test_bit(V4L2_FL_QUIRK_INVERTED_CROP, &vfd->flags))
2458*4882a593Smuzhiyun s.target = s.target == V4L2_SEL_TGT_COMPOSE ?
2459*4882a593Smuzhiyun V4L2_SEL_TGT_CROP : V4L2_SEL_TGT_COMPOSE;
2460*4882a593Smuzhiyun
2461*4882a593Smuzhiyun return v4l_s_selection(ops, file, fh, &s);
2462*4882a593Smuzhiyun }
2463*4882a593Smuzhiyun
v4l_cropcap(const struct v4l2_ioctl_ops * ops,struct file * file,void * fh,void * arg)2464*4882a593Smuzhiyun static int v4l_cropcap(const struct v4l2_ioctl_ops *ops,
2465*4882a593Smuzhiyun struct file *file, void *fh, void *arg)
2466*4882a593Smuzhiyun {
2467*4882a593Smuzhiyun struct video_device *vfd = video_devdata(file);
2468*4882a593Smuzhiyun struct v4l2_cropcap *p = arg;
2469*4882a593Smuzhiyun struct v4l2_selection s = { .type = p->type };
2470*4882a593Smuzhiyun int ret = 0;
2471*4882a593Smuzhiyun
2472*4882a593Smuzhiyun /* setting trivial pixelaspect */
2473*4882a593Smuzhiyun p->pixelaspect.numerator = 1;
2474*4882a593Smuzhiyun p->pixelaspect.denominator = 1;
2475*4882a593Smuzhiyun
2476*4882a593Smuzhiyun if (s.type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
2477*4882a593Smuzhiyun s.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
2478*4882a593Smuzhiyun else if (s.type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)
2479*4882a593Smuzhiyun s.type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
2480*4882a593Smuzhiyun
2481*4882a593Smuzhiyun /*
2482*4882a593Smuzhiyun * The determine_valid_ioctls() call already should ensure
2483*4882a593Smuzhiyun * that this can never happen, but just in case...
2484*4882a593Smuzhiyun */
2485*4882a593Smuzhiyun if (WARN_ON(!ops->vidioc_g_selection))
2486*4882a593Smuzhiyun return -ENOTTY;
2487*4882a593Smuzhiyun
2488*4882a593Smuzhiyun if (ops->vidioc_g_pixelaspect)
2489*4882a593Smuzhiyun ret = ops->vidioc_g_pixelaspect(file, fh, s.type,
2490*4882a593Smuzhiyun &p->pixelaspect);
2491*4882a593Smuzhiyun
2492*4882a593Smuzhiyun /*
2493*4882a593Smuzhiyun * Ignore ENOTTY or ENOIOCTLCMD error returns, just use the
2494*4882a593Smuzhiyun * square pixel aspect ratio in that case.
2495*4882a593Smuzhiyun */
2496*4882a593Smuzhiyun if (ret && ret != -ENOTTY && ret != -ENOIOCTLCMD)
2497*4882a593Smuzhiyun return ret;
2498*4882a593Smuzhiyun
2499*4882a593Smuzhiyun /* Use g_selection() to fill in the bounds and defrect rectangles */
2500*4882a593Smuzhiyun
2501*4882a593Smuzhiyun /* obtaining bounds */
2502*4882a593Smuzhiyun if (V4L2_TYPE_IS_OUTPUT(p->type))
2503*4882a593Smuzhiyun s.target = V4L2_SEL_TGT_COMPOSE_BOUNDS;
2504*4882a593Smuzhiyun else
2505*4882a593Smuzhiyun s.target = V4L2_SEL_TGT_CROP_BOUNDS;
2506*4882a593Smuzhiyun
2507*4882a593Smuzhiyun if (test_bit(V4L2_FL_QUIRK_INVERTED_CROP, &vfd->flags))
2508*4882a593Smuzhiyun s.target = s.target == V4L2_SEL_TGT_COMPOSE_BOUNDS ?
2509*4882a593Smuzhiyun V4L2_SEL_TGT_CROP_BOUNDS : V4L2_SEL_TGT_COMPOSE_BOUNDS;
2510*4882a593Smuzhiyun
2511*4882a593Smuzhiyun ret = v4l_g_selection(ops, file, fh, &s);
2512*4882a593Smuzhiyun if (ret)
2513*4882a593Smuzhiyun return ret;
2514*4882a593Smuzhiyun p->bounds = s.r;
2515*4882a593Smuzhiyun
2516*4882a593Smuzhiyun /* obtaining defrect */
2517*4882a593Smuzhiyun if (s.target == V4L2_SEL_TGT_COMPOSE_BOUNDS)
2518*4882a593Smuzhiyun s.target = V4L2_SEL_TGT_COMPOSE_DEFAULT;
2519*4882a593Smuzhiyun else
2520*4882a593Smuzhiyun s.target = V4L2_SEL_TGT_CROP_DEFAULT;
2521*4882a593Smuzhiyun
2522*4882a593Smuzhiyun ret = v4l_g_selection(ops, file, fh, &s);
2523*4882a593Smuzhiyun if (ret)
2524*4882a593Smuzhiyun return ret;
2525*4882a593Smuzhiyun p->defrect = s.r;
2526*4882a593Smuzhiyun
2527*4882a593Smuzhiyun return 0;
2528*4882a593Smuzhiyun }
2529*4882a593Smuzhiyun
v4l_log_status(const struct v4l2_ioctl_ops * ops,struct file * file,void * fh,void * arg)2530*4882a593Smuzhiyun static int v4l_log_status(const struct v4l2_ioctl_ops *ops,
2531*4882a593Smuzhiyun struct file *file, void *fh, void *arg)
2532*4882a593Smuzhiyun {
2533*4882a593Smuzhiyun struct video_device *vfd = video_devdata(file);
2534*4882a593Smuzhiyun int ret;
2535*4882a593Smuzhiyun
2536*4882a593Smuzhiyun if (vfd->v4l2_dev)
2537*4882a593Smuzhiyun pr_info("%s: ================= START STATUS =================\n",
2538*4882a593Smuzhiyun vfd->v4l2_dev->name);
2539*4882a593Smuzhiyun ret = ops->vidioc_log_status(file, fh);
2540*4882a593Smuzhiyun if (vfd->v4l2_dev)
2541*4882a593Smuzhiyun pr_info("%s: ================== END STATUS ==================\n",
2542*4882a593Smuzhiyun vfd->v4l2_dev->name);
2543*4882a593Smuzhiyun return ret;
2544*4882a593Smuzhiyun }
2545*4882a593Smuzhiyun
v4l_dbg_g_register(const struct v4l2_ioctl_ops * ops,struct file * file,void * fh,void * arg)2546*4882a593Smuzhiyun static int v4l_dbg_g_register(const struct v4l2_ioctl_ops *ops,
2547*4882a593Smuzhiyun struct file *file, void *fh, void *arg)
2548*4882a593Smuzhiyun {
2549*4882a593Smuzhiyun #ifdef CONFIG_VIDEO_ADV_DEBUG
2550*4882a593Smuzhiyun struct v4l2_dbg_register *p = arg;
2551*4882a593Smuzhiyun struct video_device *vfd = video_devdata(file);
2552*4882a593Smuzhiyun struct v4l2_subdev *sd;
2553*4882a593Smuzhiyun int idx = 0;
2554*4882a593Smuzhiyun
2555*4882a593Smuzhiyun if (!capable(CAP_SYS_ADMIN))
2556*4882a593Smuzhiyun return -EPERM;
2557*4882a593Smuzhiyun if (p->match.type == V4L2_CHIP_MATCH_SUBDEV) {
2558*4882a593Smuzhiyun if (vfd->v4l2_dev == NULL)
2559*4882a593Smuzhiyun return -EINVAL;
2560*4882a593Smuzhiyun v4l2_device_for_each_subdev(sd, vfd->v4l2_dev)
2561*4882a593Smuzhiyun if (p->match.addr == idx++)
2562*4882a593Smuzhiyun return v4l2_subdev_call(sd, core, g_register, p);
2563*4882a593Smuzhiyun return -EINVAL;
2564*4882a593Smuzhiyun }
2565*4882a593Smuzhiyun if (ops->vidioc_g_register && p->match.type == V4L2_CHIP_MATCH_BRIDGE &&
2566*4882a593Smuzhiyun (ops->vidioc_g_chip_info || p->match.addr == 0))
2567*4882a593Smuzhiyun return ops->vidioc_g_register(file, fh, p);
2568*4882a593Smuzhiyun return -EINVAL;
2569*4882a593Smuzhiyun #else
2570*4882a593Smuzhiyun return -ENOTTY;
2571*4882a593Smuzhiyun #endif
2572*4882a593Smuzhiyun }
2573*4882a593Smuzhiyun
v4l_dbg_s_register(const struct v4l2_ioctl_ops * ops,struct file * file,void * fh,void * arg)2574*4882a593Smuzhiyun static int v4l_dbg_s_register(const struct v4l2_ioctl_ops *ops,
2575*4882a593Smuzhiyun struct file *file, void *fh, void *arg)
2576*4882a593Smuzhiyun {
2577*4882a593Smuzhiyun #ifdef CONFIG_VIDEO_ADV_DEBUG
2578*4882a593Smuzhiyun const struct v4l2_dbg_register *p = arg;
2579*4882a593Smuzhiyun struct video_device *vfd = video_devdata(file);
2580*4882a593Smuzhiyun struct v4l2_subdev *sd;
2581*4882a593Smuzhiyun int idx = 0;
2582*4882a593Smuzhiyun
2583*4882a593Smuzhiyun if (!capable(CAP_SYS_ADMIN))
2584*4882a593Smuzhiyun return -EPERM;
2585*4882a593Smuzhiyun if (p->match.type == V4L2_CHIP_MATCH_SUBDEV) {
2586*4882a593Smuzhiyun if (vfd->v4l2_dev == NULL)
2587*4882a593Smuzhiyun return -EINVAL;
2588*4882a593Smuzhiyun v4l2_device_for_each_subdev(sd, vfd->v4l2_dev)
2589*4882a593Smuzhiyun if (p->match.addr == idx++)
2590*4882a593Smuzhiyun return v4l2_subdev_call(sd, core, s_register, p);
2591*4882a593Smuzhiyun return -EINVAL;
2592*4882a593Smuzhiyun }
2593*4882a593Smuzhiyun if (ops->vidioc_s_register && p->match.type == V4L2_CHIP_MATCH_BRIDGE &&
2594*4882a593Smuzhiyun (ops->vidioc_g_chip_info || p->match.addr == 0))
2595*4882a593Smuzhiyun return ops->vidioc_s_register(file, fh, p);
2596*4882a593Smuzhiyun return -EINVAL;
2597*4882a593Smuzhiyun #else
2598*4882a593Smuzhiyun return -ENOTTY;
2599*4882a593Smuzhiyun #endif
2600*4882a593Smuzhiyun }
2601*4882a593Smuzhiyun
v4l_dbg_g_chip_info(const struct v4l2_ioctl_ops * ops,struct file * file,void * fh,void * arg)2602*4882a593Smuzhiyun static int v4l_dbg_g_chip_info(const struct v4l2_ioctl_ops *ops,
2603*4882a593Smuzhiyun struct file *file, void *fh, void *arg)
2604*4882a593Smuzhiyun {
2605*4882a593Smuzhiyun #ifdef CONFIG_VIDEO_ADV_DEBUG
2606*4882a593Smuzhiyun struct video_device *vfd = video_devdata(file);
2607*4882a593Smuzhiyun struct v4l2_dbg_chip_info *p = arg;
2608*4882a593Smuzhiyun struct v4l2_subdev *sd;
2609*4882a593Smuzhiyun int idx = 0;
2610*4882a593Smuzhiyun
2611*4882a593Smuzhiyun switch (p->match.type) {
2612*4882a593Smuzhiyun case V4L2_CHIP_MATCH_BRIDGE:
2613*4882a593Smuzhiyun if (ops->vidioc_s_register)
2614*4882a593Smuzhiyun p->flags |= V4L2_CHIP_FL_WRITABLE;
2615*4882a593Smuzhiyun if (ops->vidioc_g_register)
2616*4882a593Smuzhiyun p->flags |= V4L2_CHIP_FL_READABLE;
2617*4882a593Smuzhiyun strscpy(p->name, vfd->v4l2_dev->name, sizeof(p->name));
2618*4882a593Smuzhiyun if (ops->vidioc_g_chip_info)
2619*4882a593Smuzhiyun return ops->vidioc_g_chip_info(file, fh, arg);
2620*4882a593Smuzhiyun if (p->match.addr)
2621*4882a593Smuzhiyun return -EINVAL;
2622*4882a593Smuzhiyun return 0;
2623*4882a593Smuzhiyun
2624*4882a593Smuzhiyun case V4L2_CHIP_MATCH_SUBDEV:
2625*4882a593Smuzhiyun if (vfd->v4l2_dev == NULL)
2626*4882a593Smuzhiyun break;
2627*4882a593Smuzhiyun v4l2_device_for_each_subdev(sd, vfd->v4l2_dev) {
2628*4882a593Smuzhiyun if (p->match.addr != idx++)
2629*4882a593Smuzhiyun continue;
2630*4882a593Smuzhiyun if (sd->ops->core && sd->ops->core->s_register)
2631*4882a593Smuzhiyun p->flags |= V4L2_CHIP_FL_WRITABLE;
2632*4882a593Smuzhiyun if (sd->ops->core && sd->ops->core->g_register)
2633*4882a593Smuzhiyun p->flags |= V4L2_CHIP_FL_READABLE;
2634*4882a593Smuzhiyun strscpy(p->name, sd->name, sizeof(p->name));
2635*4882a593Smuzhiyun return 0;
2636*4882a593Smuzhiyun }
2637*4882a593Smuzhiyun break;
2638*4882a593Smuzhiyun }
2639*4882a593Smuzhiyun return -EINVAL;
2640*4882a593Smuzhiyun #else
2641*4882a593Smuzhiyun return -ENOTTY;
2642*4882a593Smuzhiyun #endif
2643*4882a593Smuzhiyun }
2644*4882a593Smuzhiyun
v4l_dqevent(const struct v4l2_ioctl_ops * ops,struct file * file,void * fh,void * arg)2645*4882a593Smuzhiyun static int v4l_dqevent(const struct v4l2_ioctl_ops *ops,
2646*4882a593Smuzhiyun struct file *file, void *fh, void *arg)
2647*4882a593Smuzhiyun {
2648*4882a593Smuzhiyun return v4l2_event_dequeue(fh, arg, file->f_flags & O_NONBLOCK);
2649*4882a593Smuzhiyun }
2650*4882a593Smuzhiyun
v4l_subscribe_event(const struct v4l2_ioctl_ops * ops,struct file * file,void * fh,void * arg)2651*4882a593Smuzhiyun static int v4l_subscribe_event(const struct v4l2_ioctl_ops *ops,
2652*4882a593Smuzhiyun struct file *file, void *fh, void *arg)
2653*4882a593Smuzhiyun {
2654*4882a593Smuzhiyun return ops->vidioc_subscribe_event(fh, arg);
2655*4882a593Smuzhiyun }
2656*4882a593Smuzhiyun
v4l_unsubscribe_event(const struct v4l2_ioctl_ops * ops,struct file * file,void * fh,void * arg)2657*4882a593Smuzhiyun static int v4l_unsubscribe_event(const struct v4l2_ioctl_ops *ops,
2658*4882a593Smuzhiyun struct file *file, void *fh, void *arg)
2659*4882a593Smuzhiyun {
2660*4882a593Smuzhiyun return ops->vidioc_unsubscribe_event(fh, arg);
2661*4882a593Smuzhiyun }
2662*4882a593Smuzhiyun
v4l_g_sliced_vbi_cap(const struct v4l2_ioctl_ops * ops,struct file * file,void * fh,void * arg)2663*4882a593Smuzhiyun static int v4l_g_sliced_vbi_cap(const struct v4l2_ioctl_ops *ops,
2664*4882a593Smuzhiyun struct file *file, void *fh, void *arg)
2665*4882a593Smuzhiyun {
2666*4882a593Smuzhiyun struct v4l2_sliced_vbi_cap *p = arg;
2667*4882a593Smuzhiyun int ret = check_fmt(file, p->type);
2668*4882a593Smuzhiyun
2669*4882a593Smuzhiyun if (ret)
2670*4882a593Smuzhiyun return ret;
2671*4882a593Smuzhiyun
2672*4882a593Smuzhiyun /* Clear up to type, everything after type is zeroed already */
2673*4882a593Smuzhiyun memset(p, 0, offsetof(struct v4l2_sliced_vbi_cap, type));
2674*4882a593Smuzhiyun
2675*4882a593Smuzhiyun return ops->vidioc_g_sliced_vbi_cap(file, fh, p);
2676*4882a593Smuzhiyun }
2677*4882a593Smuzhiyun
v4l_enum_freq_bands(const struct v4l2_ioctl_ops * ops,struct file * file,void * fh,void * arg)2678*4882a593Smuzhiyun static int v4l_enum_freq_bands(const struct v4l2_ioctl_ops *ops,
2679*4882a593Smuzhiyun struct file *file, void *fh, void *arg)
2680*4882a593Smuzhiyun {
2681*4882a593Smuzhiyun struct video_device *vfd = video_devdata(file);
2682*4882a593Smuzhiyun struct v4l2_frequency_band *p = arg;
2683*4882a593Smuzhiyun enum v4l2_tuner_type type;
2684*4882a593Smuzhiyun int err;
2685*4882a593Smuzhiyun
2686*4882a593Smuzhiyun if (vfd->vfl_type == VFL_TYPE_SDR) {
2687*4882a593Smuzhiyun if (p->type != V4L2_TUNER_SDR && p->type != V4L2_TUNER_RF)
2688*4882a593Smuzhiyun return -EINVAL;
2689*4882a593Smuzhiyun type = p->type;
2690*4882a593Smuzhiyun } else {
2691*4882a593Smuzhiyun type = (vfd->vfl_type == VFL_TYPE_RADIO) ?
2692*4882a593Smuzhiyun V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV;
2693*4882a593Smuzhiyun if (type != p->type)
2694*4882a593Smuzhiyun return -EINVAL;
2695*4882a593Smuzhiyun }
2696*4882a593Smuzhiyun if (ops->vidioc_enum_freq_bands) {
2697*4882a593Smuzhiyun err = ops->vidioc_enum_freq_bands(file, fh, p);
2698*4882a593Smuzhiyun if (err != -ENOTTY)
2699*4882a593Smuzhiyun return err;
2700*4882a593Smuzhiyun }
2701*4882a593Smuzhiyun if (is_valid_ioctl(vfd, VIDIOC_G_TUNER)) {
2702*4882a593Smuzhiyun struct v4l2_tuner t = {
2703*4882a593Smuzhiyun .index = p->tuner,
2704*4882a593Smuzhiyun .type = type,
2705*4882a593Smuzhiyun };
2706*4882a593Smuzhiyun
2707*4882a593Smuzhiyun if (p->index)
2708*4882a593Smuzhiyun return -EINVAL;
2709*4882a593Smuzhiyun err = ops->vidioc_g_tuner(file, fh, &t);
2710*4882a593Smuzhiyun if (err)
2711*4882a593Smuzhiyun return err;
2712*4882a593Smuzhiyun p->capability = t.capability | V4L2_TUNER_CAP_FREQ_BANDS;
2713*4882a593Smuzhiyun p->rangelow = t.rangelow;
2714*4882a593Smuzhiyun p->rangehigh = t.rangehigh;
2715*4882a593Smuzhiyun p->modulation = (type == V4L2_TUNER_RADIO) ?
2716*4882a593Smuzhiyun V4L2_BAND_MODULATION_FM : V4L2_BAND_MODULATION_VSB;
2717*4882a593Smuzhiyun return 0;
2718*4882a593Smuzhiyun }
2719*4882a593Smuzhiyun if (is_valid_ioctl(vfd, VIDIOC_G_MODULATOR)) {
2720*4882a593Smuzhiyun struct v4l2_modulator m = {
2721*4882a593Smuzhiyun .index = p->tuner,
2722*4882a593Smuzhiyun };
2723*4882a593Smuzhiyun
2724*4882a593Smuzhiyun if (type != V4L2_TUNER_RADIO)
2725*4882a593Smuzhiyun return -EINVAL;
2726*4882a593Smuzhiyun if (p->index)
2727*4882a593Smuzhiyun return -EINVAL;
2728*4882a593Smuzhiyun err = ops->vidioc_g_modulator(file, fh, &m);
2729*4882a593Smuzhiyun if (err)
2730*4882a593Smuzhiyun return err;
2731*4882a593Smuzhiyun p->capability = m.capability | V4L2_TUNER_CAP_FREQ_BANDS;
2732*4882a593Smuzhiyun p->rangelow = m.rangelow;
2733*4882a593Smuzhiyun p->rangehigh = m.rangehigh;
2734*4882a593Smuzhiyun p->modulation = (type == V4L2_TUNER_RADIO) ?
2735*4882a593Smuzhiyun V4L2_BAND_MODULATION_FM : V4L2_BAND_MODULATION_VSB;
2736*4882a593Smuzhiyun return 0;
2737*4882a593Smuzhiyun }
2738*4882a593Smuzhiyun return -ENOTTY;
2739*4882a593Smuzhiyun }
2740*4882a593Smuzhiyun
2741*4882a593Smuzhiyun struct v4l2_ioctl_info {
2742*4882a593Smuzhiyun unsigned int ioctl;
2743*4882a593Smuzhiyun u32 flags;
2744*4882a593Smuzhiyun const char * const name;
2745*4882a593Smuzhiyun int (*func)(const struct v4l2_ioctl_ops *ops, struct file *file,
2746*4882a593Smuzhiyun void *fh, void *p);
2747*4882a593Smuzhiyun void (*debug)(const void *arg, bool write_only);
2748*4882a593Smuzhiyun };
2749*4882a593Smuzhiyun
2750*4882a593Smuzhiyun /* This control needs a priority check */
2751*4882a593Smuzhiyun #define INFO_FL_PRIO (1 << 0)
2752*4882a593Smuzhiyun /* This control can be valid if the filehandle passes a control handler. */
2753*4882a593Smuzhiyun #define INFO_FL_CTRL (1 << 1)
2754*4882a593Smuzhiyun /* Queuing ioctl */
2755*4882a593Smuzhiyun #define INFO_FL_QUEUE (1 << 2)
2756*4882a593Smuzhiyun /* Always copy back result, even on error */
2757*4882a593Smuzhiyun #define INFO_FL_ALWAYS_COPY (1 << 3)
2758*4882a593Smuzhiyun /* Zero struct from after the field to the end */
2759*4882a593Smuzhiyun #define INFO_FL_CLEAR(v4l2_struct, field) \
2760*4882a593Smuzhiyun ((offsetof(struct v4l2_struct, field) + \
2761*4882a593Smuzhiyun sizeof_field(struct v4l2_struct, field)) << 16)
2762*4882a593Smuzhiyun #define INFO_FL_CLEAR_MASK (_IOC_SIZEMASK << 16)
2763*4882a593Smuzhiyun
2764*4882a593Smuzhiyun #define DEFINE_V4L_STUB_FUNC(_vidioc) \
2765*4882a593Smuzhiyun static int v4l_stub_ ## _vidioc( \
2766*4882a593Smuzhiyun const struct v4l2_ioctl_ops *ops, \
2767*4882a593Smuzhiyun struct file *file, void *fh, void *p) \
2768*4882a593Smuzhiyun { \
2769*4882a593Smuzhiyun return ops->vidioc_ ## _vidioc(file, fh, p); \
2770*4882a593Smuzhiyun }
2771*4882a593Smuzhiyun
2772*4882a593Smuzhiyun #define IOCTL_INFO(_ioctl, _func, _debug, _flags) \
2773*4882a593Smuzhiyun [_IOC_NR(_ioctl)] = { \
2774*4882a593Smuzhiyun .ioctl = _ioctl, \
2775*4882a593Smuzhiyun .flags = _flags, \
2776*4882a593Smuzhiyun .name = #_ioctl, \
2777*4882a593Smuzhiyun .func = _func, \
2778*4882a593Smuzhiyun .debug = _debug, \
2779*4882a593Smuzhiyun }
2780*4882a593Smuzhiyun
2781*4882a593Smuzhiyun DEFINE_V4L_STUB_FUNC(g_fbuf)
2782*4882a593Smuzhiyun DEFINE_V4L_STUB_FUNC(s_fbuf)
2783*4882a593Smuzhiyun DEFINE_V4L_STUB_FUNC(expbuf)
2784*4882a593Smuzhiyun DEFINE_V4L_STUB_FUNC(g_std)
2785*4882a593Smuzhiyun DEFINE_V4L_STUB_FUNC(g_audio)
2786*4882a593Smuzhiyun DEFINE_V4L_STUB_FUNC(s_audio)
2787*4882a593Smuzhiyun DEFINE_V4L_STUB_FUNC(g_edid)
2788*4882a593Smuzhiyun DEFINE_V4L_STUB_FUNC(s_edid)
2789*4882a593Smuzhiyun DEFINE_V4L_STUB_FUNC(g_audout)
2790*4882a593Smuzhiyun DEFINE_V4L_STUB_FUNC(s_audout)
2791*4882a593Smuzhiyun DEFINE_V4L_STUB_FUNC(g_jpegcomp)
2792*4882a593Smuzhiyun DEFINE_V4L_STUB_FUNC(s_jpegcomp)
2793*4882a593Smuzhiyun DEFINE_V4L_STUB_FUNC(enumaudio)
2794*4882a593Smuzhiyun DEFINE_V4L_STUB_FUNC(enumaudout)
2795*4882a593Smuzhiyun DEFINE_V4L_STUB_FUNC(enum_framesizes)
2796*4882a593Smuzhiyun DEFINE_V4L_STUB_FUNC(enum_frameintervals)
2797*4882a593Smuzhiyun DEFINE_V4L_STUB_FUNC(g_enc_index)
2798*4882a593Smuzhiyun DEFINE_V4L_STUB_FUNC(encoder_cmd)
2799*4882a593Smuzhiyun DEFINE_V4L_STUB_FUNC(try_encoder_cmd)
2800*4882a593Smuzhiyun DEFINE_V4L_STUB_FUNC(decoder_cmd)
2801*4882a593Smuzhiyun DEFINE_V4L_STUB_FUNC(try_decoder_cmd)
2802*4882a593Smuzhiyun DEFINE_V4L_STUB_FUNC(s_dv_timings)
2803*4882a593Smuzhiyun DEFINE_V4L_STUB_FUNC(g_dv_timings)
2804*4882a593Smuzhiyun DEFINE_V4L_STUB_FUNC(enum_dv_timings)
2805*4882a593Smuzhiyun DEFINE_V4L_STUB_FUNC(query_dv_timings)
2806*4882a593Smuzhiyun DEFINE_V4L_STUB_FUNC(dv_timings_cap)
2807*4882a593Smuzhiyun
2808*4882a593Smuzhiyun static const struct v4l2_ioctl_info v4l2_ioctls[] = {
2809*4882a593Smuzhiyun IOCTL_INFO(VIDIOC_QUERYCAP, v4l_querycap, v4l_print_querycap, 0),
2810*4882a593Smuzhiyun IOCTL_INFO(VIDIOC_ENUM_FMT, v4l_enum_fmt, v4l_print_fmtdesc, 0),
2811*4882a593Smuzhiyun IOCTL_INFO(VIDIOC_G_FMT, v4l_g_fmt, v4l_print_format, 0),
2812*4882a593Smuzhiyun IOCTL_INFO(VIDIOC_S_FMT, v4l_s_fmt, v4l_print_format, INFO_FL_PRIO),
2813*4882a593Smuzhiyun IOCTL_INFO(VIDIOC_REQBUFS, v4l_reqbufs, v4l_print_requestbuffers, INFO_FL_PRIO | INFO_FL_QUEUE),
2814*4882a593Smuzhiyun IOCTL_INFO(VIDIOC_QUERYBUF, v4l_querybuf, v4l_print_buffer, INFO_FL_QUEUE | INFO_FL_CLEAR(v4l2_buffer, length)),
2815*4882a593Smuzhiyun IOCTL_INFO(VIDIOC_G_FBUF, v4l_stub_g_fbuf, v4l_print_framebuffer, 0),
2816*4882a593Smuzhiyun IOCTL_INFO(VIDIOC_S_FBUF, v4l_stub_s_fbuf, v4l_print_framebuffer, INFO_FL_PRIO),
2817*4882a593Smuzhiyun IOCTL_INFO(VIDIOC_OVERLAY, v4l_overlay, v4l_print_u32, INFO_FL_PRIO),
2818*4882a593Smuzhiyun IOCTL_INFO(VIDIOC_QBUF, v4l_qbuf, v4l_print_buffer, INFO_FL_QUEUE),
2819*4882a593Smuzhiyun IOCTL_INFO(VIDIOC_EXPBUF, v4l_stub_expbuf, v4l_print_exportbuffer, INFO_FL_QUEUE | INFO_FL_CLEAR(v4l2_exportbuffer, flags)),
2820*4882a593Smuzhiyun IOCTL_INFO(VIDIOC_DQBUF, v4l_dqbuf, v4l_print_buffer, INFO_FL_QUEUE),
2821*4882a593Smuzhiyun IOCTL_INFO(VIDIOC_STREAMON, v4l_streamon, v4l_print_buftype, INFO_FL_PRIO | INFO_FL_QUEUE),
2822*4882a593Smuzhiyun IOCTL_INFO(VIDIOC_STREAMOFF, v4l_streamoff, v4l_print_buftype, INFO_FL_PRIO | INFO_FL_QUEUE),
2823*4882a593Smuzhiyun IOCTL_INFO(VIDIOC_G_PARM, v4l_g_parm, v4l_print_streamparm, INFO_FL_CLEAR(v4l2_streamparm, type)),
2824*4882a593Smuzhiyun IOCTL_INFO(VIDIOC_S_PARM, v4l_s_parm, v4l_print_streamparm, INFO_FL_PRIO),
2825*4882a593Smuzhiyun IOCTL_INFO(VIDIOC_G_STD, v4l_stub_g_std, v4l_print_std, 0),
2826*4882a593Smuzhiyun IOCTL_INFO(VIDIOC_S_STD, v4l_s_std, v4l_print_std, INFO_FL_PRIO),
2827*4882a593Smuzhiyun IOCTL_INFO(VIDIOC_ENUMSTD, v4l_enumstd, v4l_print_standard, INFO_FL_CLEAR(v4l2_standard, index)),
2828*4882a593Smuzhiyun IOCTL_INFO(VIDIOC_ENUMINPUT, v4l_enuminput, v4l_print_enuminput, INFO_FL_CLEAR(v4l2_input, index)),
2829*4882a593Smuzhiyun IOCTL_INFO(VIDIOC_G_CTRL, v4l_g_ctrl, v4l_print_control, INFO_FL_CTRL | INFO_FL_CLEAR(v4l2_control, id)),
2830*4882a593Smuzhiyun IOCTL_INFO(VIDIOC_S_CTRL, v4l_s_ctrl, v4l_print_control, INFO_FL_PRIO | INFO_FL_CTRL),
2831*4882a593Smuzhiyun IOCTL_INFO(VIDIOC_G_TUNER, v4l_g_tuner, v4l_print_tuner, INFO_FL_CLEAR(v4l2_tuner, index)),
2832*4882a593Smuzhiyun IOCTL_INFO(VIDIOC_S_TUNER, v4l_s_tuner, v4l_print_tuner, INFO_FL_PRIO),
2833*4882a593Smuzhiyun IOCTL_INFO(VIDIOC_G_AUDIO, v4l_stub_g_audio, v4l_print_audio, 0),
2834*4882a593Smuzhiyun IOCTL_INFO(VIDIOC_S_AUDIO, v4l_stub_s_audio, v4l_print_audio, INFO_FL_PRIO),
2835*4882a593Smuzhiyun IOCTL_INFO(VIDIOC_QUERYCTRL, v4l_queryctrl, v4l_print_queryctrl, INFO_FL_CTRL | INFO_FL_CLEAR(v4l2_queryctrl, id)),
2836*4882a593Smuzhiyun IOCTL_INFO(VIDIOC_QUERYMENU, v4l_querymenu, v4l_print_querymenu, INFO_FL_CTRL | INFO_FL_CLEAR(v4l2_querymenu, index)),
2837*4882a593Smuzhiyun IOCTL_INFO(VIDIOC_G_INPUT, v4l_g_input, v4l_print_u32, 0),
2838*4882a593Smuzhiyun IOCTL_INFO(VIDIOC_S_INPUT, v4l_s_input, v4l_print_u32, INFO_FL_PRIO),
2839*4882a593Smuzhiyun IOCTL_INFO(VIDIOC_G_EDID, v4l_stub_g_edid, v4l_print_edid, INFO_FL_ALWAYS_COPY),
2840*4882a593Smuzhiyun IOCTL_INFO(VIDIOC_S_EDID, v4l_stub_s_edid, v4l_print_edid, INFO_FL_PRIO | INFO_FL_ALWAYS_COPY),
2841*4882a593Smuzhiyun IOCTL_INFO(VIDIOC_G_OUTPUT, v4l_g_output, v4l_print_u32, 0),
2842*4882a593Smuzhiyun IOCTL_INFO(VIDIOC_S_OUTPUT, v4l_s_output, v4l_print_u32, INFO_FL_PRIO),
2843*4882a593Smuzhiyun IOCTL_INFO(VIDIOC_ENUMOUTPUT, v4l_enumoutput, v4l_print_enumoutput, INFO_FL_CLEAR(v4l2_output, index)),
2844*4882a593Smuzhiyun IOCTL_INFO(VIDIOC_G_AUDOUT, v4l_stub_g_audout, v4l_print_audioout, 0),
2845*4882a593Smuzhiyun IOCTL_INFO(VIDIOC_S_AUDOUT, v4l_stub_s_audout, v4l_print_audioout, INFO_FL_PRIO),
2846*4882a593Smuzhiyun IOCTL_INFO(VIDIOC_G_MODULATOR, v4l_g_modulator, v4l_print_modulator, INFO_FL_CLEAR(v4l2_modulator, index)),
2847*4882a593Smuzhiyun IOCTL_INFO(VIDIOC_S_MODULATOR, v4l_s_modulator, v4l_print_modulator, INFO_FL_PRIO),
2848*4882a593Smuzhiyun IOCTL_INFO(VIDIOC_G_FREQUENCY, v4l_g_frequency, v4l_print_frequency, INFO_FL_CLEAR(v4l2_frequency, tuner)),
2849*4882a593Smuzhiyun IOCTL_INFO(VIDIOC_S_FREQUENCY, v4l_s_frequency, v4l_print_frequency, INFO_FL_PRIO),
2850*4882a593Smuzhiyun IOCTL_INFO(VIDIOC_CROPCAP, v4l_cropcap, v4l_print_cropcap, INFO_FL_CLEAR(v4l2_cropcap, type)),
2851*4882a593Smuzhiyun IOCTL_INFO(VIDIOC_G_CROP, v4l_g_crop, v4l_print_crop, INFO_FL_CLEAR(v4l2_crop, type)),
2852*4882a593Smuzhiyun IOCTL_INFO(VIDIOC_S_CROP, v4l_s_crop, v4l_print_crop, INFO_FL_PRIO),
2853*4882a593Smuzhiyun IOCTL_INFO(VIDIOC_G_SELECTION, v4l_g_selection, v4l_print_selection, INFO_FL_CLEAR(v4l2_selection, r)),
2854*4882a593Smuzhiyun IOCTL_INFO(VIDIOC_S_SELECTION, v4l_s_selection, v4l_print_selection, INFO_FL_PRIO | INFO_FL_CLEAR(v4l2_selection, r)),
2855*4882a593Smuzhiyun IOCTL_INFO(VIDIOC_G_JPEGCOMP, v4l_stub_g_jpegcomp, v4l_print_jpegcompression, 0),
2856*4882a593Smuzhiyun IOCTL_INFO(VIDIOC_S_JPEGCOMP, v4l_stub_s_jpegcomp, v4l_print_jpegcompression, INFO_FL_PRIO),
2857*4882a593Smuzhiyun IOCTL_INFO(VIDIOC_QUERYSTD, v4l_querystd, v4l_print_std, 0),
2858*4882a593Smuzhiyun IOCTL_INFO(VIDIOC_TRY_FMT, v4l_try_fmt, v4l_print_format, 0),
2859*4882a593Smuzhiyun IOCTL_INFO(VIDIOC_ENUMAUDIO, v4l_stub_enumaudio, v4l_print_audio, INFO_FL_CLEAR(v4l2_audio, index)),
2860*4882a593Smuzhiyun IOCTL_INFO(VIDIOC_ENUMAUDOUT, v4l_stub_enumaudout, v4l_print_audioout, INFO_FL_CLEAR(v4l2_audioout, index)),
2861*4882a593Smuzhiyun IOCTL_INFO(VIDIOC_G_PRIORITY, v4l_g_priority, v4l_print_u32, 0),
2862*4882a593Smuzhiyun IOCTL_INFO(VIDIOC_S_PRIORITY, v4l_s_priority, v4l_print_u32, INFO_FL_PRIO),
2863*4882a593Smuzhiyun IOCTL_INFO(VIDIOC_G_SLICED_VBI_CAP, v4l_g_sliced_vbi_cap, v4l_print_sliced_vbi_cap, INFO_FL_CLEAR(v4l2_sliced_vbi_cap, type)),
2864*4882a593Smuzhiyun IOCTL_INFO(VIDIOC_LOG_STATUS, v4l_log_status, v4l_print_newline, 0),
2865*4882a593Smuzhiyun IOCTL_INFO(VIDIOC_G_EXT_CTRLS, v4l_g_ext_ctrls, v4l_print_ext_controls, INFO_FL_CTRL),
2866*4882a593Smuzhiyun IOCTL_INFO(VIDIOC_S_EXT_CTRLS, v4l_s_ext_ctrls, v4l_print_ext_controls, INFO_FL_PRIO | INFO_FL_CTRL),
2867*4882a593Smuzhiyun IOCTL_INFO(VIDIOC_TRY_EXT_CTRLS, v4l_try_ext_ctrls, v4l_print_ext_controls, INFO_FL_CTRL),
2868*4882a593Smuzhiyun IOCTL_INFO(VIDIOC_ENUM_FRAMESIZES, v4l_stub_enum_framesizes, v4l_print_frmsizeenum, INFO_FL_CLEAR(v4l2_frmsizeenum, pixel_format)),
2869*4882a593Smuzhiyun IOCTL_INFO(VIDIOC_ENUM_FRAMEINTERVALS, v4l_stub_enum_frameintervals, v4l_print_frmivalenum, INFO_FL_CLEAR(v4l2_frmivalenum, height)),
2870*4882a593Smuzhiyun IOCTL_INFO(VIDIOC_G_ENC_INDEX, v4l_stub_g_enc_index, v4l_print_enc_idx, 0),
2871*4882a593Smuzhiyun IOCTL_INFO(VIDIOC_ENCODER_CMD, v4l_stub_encoder_cmd, v4l_print_encoder_cmd, INFO_FL_PRIO | INFO_FL_CLEAR(v4l2_encoder_cmd, flags)),
2872*4882a593Smuzhiyun IOCTL_INFO(VIDIOC_TRY_ENCODER_CMD, v4l_stub_try_encoder_cmd, v4l_print_encoder_cmd, INFO_FL_CLEAR(v4l2_encoder_cmd, flags)),
2873*4882a593Smuzhiyun IOCTL_INFO(VIDIOC_DECODER_CMD, v4l_stub_decoder_cmd, v4l_print_decoder_cmd, INFO_FL_PRIO),
2874*4882a593Smuzhiyun IOCTL_INFO(VIDIOC_TRY_DECODER_CMD, v4l_stub_try_decoder_cmd, v4l_print_decoder_cmd, 0),
2875*4882a593Smuzhiyun IOCTL_INFO(VIDIOC_DBG_S_REGISTER, v4l_dbg_s_register, v4l_print_dbg_register, 0),
2876*4882a593Smuzhiyun IOCTL_INFO(VIDIOC_DBG_G_REGISTER, v4l_dbg_g_register, v4l_print_dbg_register, 0),
2877*4882a593Smuzhiyun IOCTL_INFO(VIDIOC_S_HW_FREQ_SEEK, v4l_s_hw_freq_seek, v4l_print_hw_freq_seek, INFO_FL_PRIO),
2878*4882a593Smuzhiyun IOCTL_INFO(VIDIOC_S_DV_TIMINGS, v4l_stub_s_dv_timings, v4l_print_dv_timings, INFO_FL_PRIO | INFO_FL_CLEAR(v4l2_dv_timings, bt.flags)),
2879*4882a593Smuzhiyun IOCTL_INFO(VIDIOC_G_DV_TIMINGS, v4l_stub_g_dv_timings, v4l_print_dv_timings, 0),
2880*4882a593Smuzhiyun IOCTL_INFO(VIDIOC_DQEVENT, v4l_dqevent, v4l_print_event, 0),
2881*4882a593Smuzhiyun IOCTL_INFO(VIDIOC_SUBSCRIBE_EVENT, v4l_subscribe_event, v4l_print_event_subscription, 0),
2882*4882a593Smuzhiyun IOCTL_INFO(VIDIOC_UNSUBSCRIBE_EVENT, v4l_unsubscribe_event, v4l_print_event_subscription, 0),
2883*4882a593Smuzhiyun IOCTL_INFO(VIDIOC_CREATE_BUFS, v4l_create_bufs, v4l_print_create_buffers, INFO_FL_PRIO | INFO_FL_QUEUE),
2884*4882a593Smuzhiyun IOCTL_INFO(VIDIOC_PREPARE_BUF, v4l_prepare_buf, v4l_print_buffer, INFO_FL_QUEUE),
2885*4882a593Smuzhiyun IOCTL_INFO(VIDIOC_ENUM_DV_TIMINGS, v4l_stub_enum_dv_timings, v4l_print_enum_dv_timings, INFO_FL_CLEAR(v4l2_enum_dv_timings, pad)),
2886*4882a593Smuzhiyun IOCTL_INFO(VIDIOC_QUERY_DV_TIMINGS, v4l_stub_query_dv_timings, v4l_print_dv_timings, INFO_FL_ALWAYS_COPY),
2887*4882a593Smuzhiyun IOCTL_INFO(VIDIOC_DV_TIMINGS_CAP, v4l_stub_dv_timings_cap, v4l_print_dv_timings_cap, INFO_FL_CLEAR(v4l2_dv_timings_cap, pad)),
2888*4882a593Smuzhiyun IOCTL_INFO(VIDIOC_ENUM_FREQ_BANDS, v4l_enum_freq_bands, v4l_print_freq_band, 0),
2889*4882a593Smuzhiyun IOCTL_INFO(VIDIOC_DBG_G_CHIP_INFO, v4l_dbg_g_chip_info, v4l_print_dbg_chip_info, INFO_FL_CLEAR(v4l2_dbg_chip_info, match)),
2890*4882a593Smuzhiyun IOCTL_INFO(VIDIOC_QUERY_EXT_CTRL, v4l_query_ext_ctrl, v4l_print_query_ext_ctrl, INFO_FL_CTRL | INFO_FL_CLEAR(v4l2_query_ext_ctrl, id)),
2891*4882a593Smuzhiyun };
2892*4882a593Smuzhiyun #define V4L2_IOCTLS ARRAY_SIZE(v4l2_ioctls)
2893*4882a593Smuzhiyun
v4l2_is_known_ioctl(unsigned int cmd)2894*4882a593Smuzhiyun static bool v4l2_is_known_ioctl(unsigned int cmd)
2895*4882a593Smuzhiyun {
2896*4882a593Smuzhiyun if (_IOC_NR(cmd) >= V4L2_IOCTLS)
2897*4882a593Smuzhiyun return false;
2898*4882a593Smuzhiyun return v4l2_ioctls[_IOC_NR(cmd)].ioctl == cmd;
2899*4882a593Smuzhiyun }
2900*4882a593Smuzhiyun
v4l2_ioctl_get_lock(struct video_device * vdev,struct v4l2_fh * vfh,unsigned int cmd,void * arg)2901*4882a593Smuzhiyun static struct mutex *v4l2_ioctl_get_lock(struct video_device *vdev,
2902*4882a593Smuzhiyun struct v4l2_fh *vfh, unsigned int cmd,
2903*4882a593Smuzhiyun void *arg)
2904*4882a593Smuzhiyun {
2905*4882a593Smuzhiyun if (_IOC_NR(cmd) >= V4L2_IOCTLS)
2906*4882a593Smuzhiyun return vdev->lock;
2907*4882a593Smuzhiyun if (vfh && vfh->m2m_ctx &&
2908*4882a593Smuzhiyun (v4l2_ioctls[_IOC_NR(cmd)].flags & INFO_FL_QUEUE)) {
2909*4882a593Smuzhiyun if (vfh->m2m_ctx->q_lock)
2910*4882a593Smuzhiyun return vfh->m2m_ctx->q_lock;
2911*4882a593Smuzhiyun }
2912*4882a593Smuzhiyun if (vdev->queue && vdev->queue->lock &&
2913*4882a593Smuzhiyun (v4l2_ioctls[_IOC_NR(cmd)].flags & INFO_FL_QUEUE))
2914*4882a593Smuzhiyun return vdev->queue->lock;
2915*4882a593Smuzhiyun return vdev->lock;
2916*4882a593Smuzhiyun }
2917*4882a593Smuzhiyun
2918*4882a593Smuzhiyun /* Common ioctl debug function. This function can be used by
2919*4882a593Smuzhiyun external ioctl messages as well as internal V4L ioctl */
v4l_printk_ioctl(const char * prefix,unsigned int cmd)2920*4882a593Smuzhiyun void v4l_printk_ioctl(const char *prefix, unsigned int cmd)
2921*4882a593Smuzhiyun {
2922*4882a593Smuzhiyun const char *dir, *type;
2923*4882a593Smuzhiyun
2924*4882a593Smuzhiyun if (prefix)
2925*4882a593Smuzhiyun printk(KERN_DEBUG "%s: ", prefix);
2926*4882a593Smuzhiyun
2927*4882a593Smuzhiyun switch (_IOC_TYPE(cmd)) {
2928*4882a593Smuzhiyun case 'd':
2929*4882a593Smuzhiyun type = "v4l2_int";
2930*4882a593Smuzhiyun break;
2931*4882a593Smuzhiyun case 'V':
2932*4882a593Smuzhiyun if (_IOC_NR(cmd) >= V4L2_IOCTLS) {
2933*4882a593Smuzhiyun type = "v4l2";
2934*4882a593Smuzhiyun break;
2935*4882a593Smuzhiyun }
2936*4882a593Smuzhiyun pr_cont("%s", v4l2_ioctls[_IOC_NR(cmd)].name);
2937*4882a593Smuzhiyun return;
2938*4882a593Smuzhiyun default:
2939*4882a593Smuzhiyun type = "unknown";
2940*4882a593Smuzhiyun break;
2941*4882a593Smuzhiyun }
2942*4882a593Smuzhiyun
2943*4882a593Smuzhiyun switch (_IOC_DIR(cmd)) {
2944*4882a593Smuzhiyun case _IOC_NONE: dir = "--"; break;
2945*4882a593Smuzhiyun case _IOC_READ: dir = "r-"; break;
2946*4882a593Smuzhiyun case _IOC_WRITE: dir = "-w"; break;
2947*4882a593Smuzhiyun case _IOC_READ | _IOC_WRITE: dir = "rw"; break;
2948*4882a593Smuzhiyun default: dir = "*ERR*"; break;
2949*4882a593Smuzhiyun }
2950*4882a593Smuzhiyun pr_cont("%s ioctl '%c', dir=%s, #%d (0x%08x)",
2951*4882a593Smuzhiyun type, _IOC_TYPE(cmd), dir, _IOC_NR(cmd), cmd);
2952*4882a593Smuzhiyun }
2953*4882a593Smuzhiyun EXPORT_SYMBOL(v4l_printk_ioctl);
2954*4882a593Smuzhiyun
__video_do_ioctl(struct file * file,unsigned int cmd,void * arg)2955*4882a593Smuzhiyun static long __video_do_ioctl(struct file *file,
2956*4882a593Smuzhiyun unsigned int cmd, void *arg)
2957*4882a593Smuzhiyun {
2958*4882a593Smuzhiyun struct video_device *vfd = video_devdata(file);
2959*4882a593Smuzhiyun struct mutex *req_queue_lock = NULL;
2960*4882a593Smuzhiyun struct mutex *lock; /* ioctl serialization mutex */
2961*4882a593Smuzhiyun const struct v4l2_ioctl_ops *ops = vfd->ioctl_ops;
2962*4882a593Smuzhiyun bool write_only = false;
2963*4882a593Smuzhiyun struct v4l2_ioctl_info default_info;
2964*4882a593Smuzhiyun const struct v4l2_ioctl_info *info;
2965*4882a593Smuzhiyun void *fh = file->private_data;
2966*4882a593Smuzhiyun struct v4l2_fh *vfh = NULL;
2967*4882a593Smuzhiyun int dev_debug = vfd->dev_debug;
2968*4882a593Smuzhiyun long ret = -ENOTTY;
2969*4882a593Smuzhiyun
2970*4882a593Smuzhiyun if (ops == NULL) {
2971*4882a593Smuzhiyun pr_warn("%s: has no ioctl_ops.\n",
2972*4882a593Smuzhiyun video_device_node_name(vfd));
2973*4882a593Smuzhiyun return ret;
2974*4882a593Smuzhiyun }
2975*4882a593Smuzhiyun
2976*4882a593Smuzhiyun if (test_bit(V4L2_FL_USES_V4L2_FH, &vfd->flags))
2977*4882a593Smuzhiyun vfh = file->private_data;
2978*4882a593Smuzhiyun
2979*4882a593Smuzhiyun /*
2980*4882a593Smuzhiyun * We need to serialize streamon/off with queueing new requests.
2981*4882a593Smuzhiyun * These ioctls may trigger the cancellation of a streaming
2982*4882a593Smuzhiyun * operation, and that should not be mixed with queueing a new
2983*4882a593Smuzhiyun * request at the same time.
2984*4882a593Smuzhiyun */
2985*4882a593Smuzhiyun if (v4l2_device_supports_requests(vfd->v4l2_dev) &&
2986*4882a593Smuzhiyun (cmd == VIDIOC_STREAMON || cmd == VIDIOC_STREAMOFF)) {
2987*4882a593Smuzhiyun req_queue_lock = &vfd->v4l2_dev->mdev->req_queue_mutex;
2988*4882a593Smuzhiyun
2989*4882a593Smuzhiyun if (mutex_lock_interruptible(req_queue_lock))
2990*4882a593Smuzhiyun return -ERESTARTSYS;
2991*4882a593Smuzhiyun }
2992*4882a593Smuzhiyun
2993*4882a593Smuzhiyun lock = v4l2_ioctl_get_lock(vfd, vfh, cmd, arg);
2994*4882a593Smuzhiyun
2995*4882a593Smuzhiyun if (lock && mutex_lock_interruptible(lock)) {
2996*4882a593Smuzhiyun if (req_queue_lock)
2997*4882a593Smuzhiyun mutex_unlock(req_queue_lock);
2998*4882a593Smuzhiyun return -ERESTARTSYS;
2999*4882a593Smuzhiyun }
3000*4882a593Smuzhiyun
3001*4882a593Smuzhiyun if (!video_is_registered(vfd)) {
3002*4882a593Smuzhiyun ret = -ENODEV;
3003*4882a593Smuzhiyun goto unlock;
3004*4882a593Smuzhiyun }
3005*4882a593Smuzhiyun
3006*4882a593Smuzhiyun if (v4l2_is_known_ioctl(cmd)) {
3007*4882a593Smuzhiyun info = &v4l2_ioctls[_IOC_NR(cmd)];
3008*4882a593Smuzhiyun
3009*4882a593Smuzhiyun if (!test_bit(_IOC_NR(cmd), vfd->valid_ioctls) &&
3010*4882a593Smuzhiyun !((info->flags & INFO_FL_CTRL) && vfh && vfh->ctrl_handler))
3011*4882a593Smuzhiyun goto done;
3012*4882a593Smuzhiyun
3013*4882a593Smuzhiyun if (vfh && (info->flags & INFO_FL_PRIO)) {
3014*4882a593Smuzhiyun ret = v4l2_prio_check(vfd->prio, vfh->prio);
3015*4882a593Smuzhiyun if (ret)
3016*4882a593Smuzhiyun goto done;
3017*4882a593Smuzhiyun }
3018*4882a593Smuzhiyun } else {
3019*4882a593Smuzhiyun default_info.ioctl = cmd;
3020*4882a593Smuzhiyun default_info.flags = 0;
3021*4882a593Smuzhiyun default_info.debug = v4l_print_default;
3022*4882a593Smuzhiyun info = &default_info;
3023*4882a593Smuzhiyun }
3024*4882a593Smuzhiyun
3025*4882a593Smuzhiyun write_only = _IOC_DIR(cmd) == _IOC_WRITE;
3026*4882a593Smuzhiyun if (info != &default_info) {
3027*4882a593Smuzhiyun ret = info->func(ops, file, fh, arg);
3028*4882a593Smuzhiyun } else if (!ops->vidioc_default) {
3029*4882a593Smuzhiyun ret = -ENOTTY;
3030*4882a593Smuzhiyun } else {
3031*4882a593Smuzhiyun ret = ops->vidioc_default(file, fh,
3032*4882a593Smuzhiyun vfh ? v4l2_prio_check(vfd->prio, vfh->prio) >= 0 : 0,
3033*4882a593Smuzhiyun cmd, arg);
3034*4882a593Smuzhiyun }
3035*4882a593Smuzhiyun
3036*4882a593Smuzhiyun done:
3037*4882a593Smuzhiyun if (dev_debug & (V4L2_DEV_DEBUG_IOCTL | V4L2_DEV_DEBUG_IOCTL_ARG)) {
3038*4882a593Smuzhiyun if (!(dev_debug & V4L2_DEV_DEBUG_STREAMING) &&
3039*4882a593Smuzhiyun (cmd == VIDIOC_QBUF || cmd == VIDIOC_DQBUF))
3040*4882a593Smuzhiyun goto unlock;
3041*4882a593Smuzhiyun
3042*4882a593Smuzhiyun v4l_printk_ioctl(video_device_node_name(vfd), cmd);
3043*4882a593Smuzhiyun if (ret < 0)
3044*4882a593Smuzhiyun pr_cont(": error %ld", ret);
3045*4882a593Smuzhiyun if (!(dev_debug & V4L2_DEV_DEBUG_IOCTL_ARG))
3046*4882a593Smuzhiyun pr_cont("\n");
3047*4882a593Smuzhiyun else if (_IOC_DIR(cmd) == _IOC_NONE)
3048*4882a593Smuzhiyun info->debug(arg, write_only);
3049*4882a593Smuzhiyun else {
3050*4882a593Smuzhiyun pr_cont(": ");
3051*4882a593Smuzhiyun info->debug(arg, write_only);
3052*4882a593Smuzhiyun }
3053*4882a593Smuzhiyun }
3054*4882a593Smuzhiyun
3055*4882a593Smuzhiyun unlock:
3056*4882a593Smuzhiyun if (lock)
3057*4882a593Smuzhiyun mutex_unlock(lock);
3058*4882a593Smuzhiyun if (req_queue_lock)
3059*4882a593Smuzhiyun mutex_unlock(req_queue_lock);
3060*4882a593Smuzhiyun return ret;
3061*4882a593Smuzhiyun }
3062*4882a593Smuzhiyun
check_array_args(unsigned int cmd,void * parg,size_t * array_size,void __user ** user_ptr,void *** kernel_ptr)3063*4882a593Smuzhiyun static int check_array_args(unsigned int cmd, void *parg, size_t *array_size,
3064*4882a593Smuzhiyun void __user **user_ptr, void ***kernel_ptr)
3065*4882a593Smuzhiyun {
3066*4882a593Smuzhiyun int ret = 0;
3067*4882a593Smuzhiyun
3068*4882a593Smuzhiyun switch (cmd) {
3069*4882a593Smuzhiyun case VIDIOC_PREPARE_BUF:
3070*4882a593Smuzhiyun case VIDIOC_QUERYBUF:
3071*4882a593Smuzhiyun case VIDIOC_QBUF:
3072*4882a593Smuzhiyun case VIDIOC_DQBUF: {
3073*4882a593Smuzhiyun struct v4l2_buffer *buf = parg;
3074*4882a593Smuzhiyun
3075*4882a593Smuzhiyun if (V4L2_TYPE_IS_MULTIPLANAR(buf->type) && buf->length > 0) {
3076*4882a593Smuzhiyun if (buf->length > VIDEO_MAX_PLANES) {
3077*4882a593Smuzhiyun ret = -EINVAL;
3078*4882a593Smuzhiyun break;
3079*4882a593Smuzhiyun }
3080*4882a593Smuzhiyun *user_ptr = (void __user *)buf->m.planes;
3081*4882a593Smuzhiyun *kernel_ptr = (void **)&buf->m.planes;
3082*4882a593Smuzhiyun *array_size = sizeof(struct v4l2_plane) * buf->length;
3083*4882a593Smuzhiyun ret = 1;
3084*4882a593Smuzhiyun }
3085*4882a593Smuzhiyun break;
3086*4882a593Smuzhiyun }
3087*4882a593Smuzhiyun
3088*4882a593Smuzhiyun case VIDIOC_G_EDID:
3089*4882a593Smuzhiyun case VIDIOC_S_EDID: {
3090*4882a593Smuzhiyun struct v4l2_edid *edid = parg;
3091*4882a593Smuzhiyun
3092*4882a593Smuzhiyun if (edid->blocks) {
3093*4882a593Smuzhiyun if (edid->blocks > 256) {
3094*4882a593Smuzhiyun ret = -EINVAL;
3095*4882a593Smuzhiyun break;
3096*4882a593Smuzhiyun }
3097*4882a593Smuzhiyun *user_ptr = (void __user *)edid->edid;
3098*4882a593Smuzhiyun *kernel_ptr = (void **)&edid->edid;
3099*4882a593Smuzhiyun *array_size = edid->blocks * 128;
3100*4882a593Smuzhiyun ret = 1;
3101*4882a593Smuzhiyun }
3102*4882a593Smuzhiyun break;
3103*4882a593Smuzhiyun }
3104*4882a593Smuzhiyun
3105*4882a593Smuzhiyun case VIDIOC_S_EXT_CTRLS:
3106*4882a593Smuzhiyun case VIDIOC_G_EXT_CTRLS:
3107*4882a593Smuzhiyun case VIDIOC_TRY_EXT_CTRLS: {
3108*4882a593Smuzhiyun struct v4l2_ext_controls *ctrls = parg;
3109*4882a593Smuzhiyun
3110*4882a593Smuzhiyun if (ctrls->count != 0) {
3111*4882a593Smuzhiyun if (ctrls->count > V4L2_CID_MAX_CTRLS) {
3112*4882a593Smuzhiyun ret = -EINVAL;
3113*4882a593Smuzhiyun break;
3114*4882a593Smuzhiyun }
3115*4882a593Smuzhiyun *user_ptr = (void __user *)ctrls->controls;
3116*4882a593Smuzhiyun *kernel_ptr = (void **)&ctrls->controls;
3117*4882a593Smuzhiyun *array_size = sizeof(struct v4l2_ext_control)
3118*4882a593Smuzhiyun * ctrls->count;
3119*4882a593Smuzhiyun ret = 1;
3120*4882a593Smuzhiyun }
3121*4882a593Smuzhiyun break;
3122*4882a593Smuzhiyun }
3123*4882a593Smuzhiyun }
3124*4882a593Smuzhiyun
3125*4882a593Smuzhiyun return ret;
3126*4882a593Smuzhiyun }
3127*4882a593Smuzhiyun
video_translate_cmd(unsigned int cmd)3128*4882a593Smuzhiyun static unsigned int video_translate_cmd(unsigned int cmd)
3129*4882a593Smuzhiyun {
3130*4882a593Smuzhiyun switch (cmd) {
3131*4882a593Smuzhiyun #ifdef CONFIG_COMPAT_32BIT_TIME
3132*4882a593Smuzhiyun case VIDIOC_DQEVENT_TIME32:
3133*4882a593Smuzhiyun return VIDIOC_DQEVENT;
3134*4882a593Smuzhiyun case VIDIOC_QUERYBUF_TIME32:
3135*4882a593Smuzhiyun return VIDIOC_QUERYBUF;
3136*4882a593Smuzhiyun case VIDIOC_QBUF_TIME32:
3137*4882a593Smuzhiyun return VIDIOC_QBUF;
3138*4882a593Smuzhiyun case VIDIOC_DQBUF_TIME32:
3139*4882a593Smuzhiyun return VIDIOC_DQBUF;
3140*4882a593Smuzhiyun case VIDIOC_PREPARE_BUF_TIME32:
3141*4882a593Smuzhiyun return VIDIOC_PREPARE_BUF;
3142*4882a593Smuzhiyun #endif
3143*4882a593Smuzhiyun }
3144*4882a593Smuzhiyun
3145*4882a593Smuzhiyun return cmd;
3146*4882a593Smuzhiyun }
3147*4882a593Smuzhiyun
video_get_user(void __user * arg,void * parg,unsigned int cmd,bool * always_copy)3148*4882a593Smuzhiyun static int video_get_user(void __user *arg, void *parg, unsigned int cmd,
3149*4882a593Smuzhiyun bool *always_copy)
3150*4882a593Smuzhiyun {
3151*4882a593Smuzhiyun unsigned int n = _IOC_SIZE(cmd);
3152*4882a593Smuzhiyun
3153*4882a593Smuzhiyun if (!(_IOC_DIR(cmd) & _IOC_WRITE)) {
3154*4882a593Smuzhiyun /* read-only ioctl */
3155*4882a593Smuzhiyun memset(parg, 0, n);
3156*4882a593Smuzhiyun return 0;
3157*4882a593Smuzhiyun }
3158*4882a593Smuzhiyun
3159*4882a593Smuzhiyun switch (cmd) {
3160*4882a593Smuzhiyun #ifdef CONFIG_COMPAT_32BIT_TIME
3161*4882a593Smuzhiyun case VIDIOC_QUERYBUF_TIME32:
3162*4882a593Smuzhiyun case VIDIOC_QBUF_TIME32:
3163*4882a593Smuzhiyun case VIDIOC_DQBUF_TIME32:
3164*4882a593Smuzhiyun case VIDIOC_PREPARE_BUF_TIME32: {
3165*4882a593Smuzhiyun struct v4l2_buffer_time32 vb32;
3166*4882a593Smuzhiyun struct v4l2_buffer *vb = parg;
3167*4882a593Smuzhiyun
3168*4882a593Smuzhiyun if (copy_from_user(&vb32, arg, sizeof(vb32)))
3169*4882a593Smuzhiyun return -EFAULT;
3170*4882a593Smuzhiyun
3171*4882a593Smuzhiyun *vb = (struct v4l2_buffer) {
3172*4882a593Smuzhiyun .index = vb32.index,
3173*4882a593Smuzhiyun .type = vb32.type,
3174*4882a593Smuzhiyun .bytesused = vb32.bytesused,
3175*4882a593Smuzhiyun .flags = vb32.flags,
3176*4882a593Smuzhiyun .field = vb32.field,
3177*4882a593Smuzhiyun .timestamp.tv_sec = vb32.timestamp.tv_sec,
3178*4882a593Smuzhiyun .timestamp.tv_usec = vb32.timestamp.tv_usec,
3179*4882a593Smuzhiyun .timecode = vb32.timecode,
3180*4882a593Smuzhiyun .sequence = vb32.sequence,
3181*4882a593Smuzhiyun .memory = vb32.memory,
3182*4882a593Smuzhiyun .m.userptr = vb32.m.userptr,
3183*4882a593Smuzhiyun .length = vb32.length,
3184*4882a593Smuzhiyun .request_fd = vb32.request_fd,
3185*4882a593Smuzhiyun #if defined(CONFIG_ARCH_ROCKCHIP) && IS_ENABLED(CONFIG_USB_F_UVC)
3186*4882a593Smuzhiyun .reserved2 = vb32.reserved2,
3187*4882a593Smuzhiyun #endif
3188*4882a593Smuzhiyun };
3189*4882a593Smuzhiyun
3190*4882a593Smuzhiyun if (cmd == VIDIOC_QUERYBUF_TIME32)
3191*4882a593Smuzhiyun vb->request_fd = 0;
3192*4882a593Smuzhiyun
3193*4882a593Smuzhiyun break;
3194*4882a593Smuzhiyun }
3195*4882a593Smuzhiyun #endif
3196*4882a593Smuzhiyun default:
3197*4882a593Smuzhiyun /*
3198*4882a593Smuzhiyun * In some cases, only a few fields are used as input,
3199*4882a593Smuzhiyun * i.e. when the app sets "index" and then the driver
3200*4882a593Smuzhiyun * fills in the rest of the structure for the thing
3201*4882a593Smuzhiyun * with that index. We only need to copy up the first
3202*4882a593Smuzhiyun * non-input field.
3203*4882a593Smuzhiyun */
3204*4882a593Smuzhiyun if (v4l2_is_known_ioctl(cmd)) {
3205*4882a593Smuzhiyun u32 flags = v4l2_ioctls[_IOC_NR(cmd)].flags;
3206*4882a593Smuzhiyun
3207*4882a593Smuzhiyun if (flags & INFO_FL_CLEAR_MASK)
3208*4882a593Smuzhiyun n = (flags & INFO_FL_CLEAR_MASK) >> 16;
3209*4882a593Smuzhiyun *always_copy = flags & INFO_FL_ALWAYS_COPY;
3210*4882a593Smuzhiyun trace_android_vh_clear_mask_adjust(v4l2_ioctls[_IOC_NR(cmd)].ioctl, &n);
3211*4882a593Smuzhiyun }
3212*4882a593Smuzhiyun
3213*4882a593Smuzhiyun if (copy_from_user(parg, (void __user *)arg, n))
3214*4882a593Smuzhiyun return -EFAULT;
3215*4882a593Smuzhiyun
3216*4882a593Smuzhiyun /* zero out anything we don't copy from userspace */
3217*4882a593Smuzhiyun if (n < _IOC_SIZE(cmd))
3218*4882a593Smuzhiyun memset((u8 *)parg + n, 0, _IOC_SIZE(cmd) - n);
3219*4882a593Smuzhiyun break;
3220*4882a593Smuzhiyun }
3221*4882a593Smuzhiyun
3222*4882a593Smuzhiyun return 0;
3223*4882a593Smuzhiyun }
3224*4882a593Smuzhiyun
video_put_user(void __user * arg,void * parg,unsigned int cmd)3225*4882a593Smuzhiyun static int video_put_user(void __user *arg, void *parg, unsigned int cmd)
3226*4882a593Smuzhiyun {
3227*4882a593Smuzhiyun if (!(_IOC_DIR(cmd) & _IOC_READ))
3228*4882a593Smuzhiyun return 0;
3229*4882a593Smuzhiyun
3230*4882a593Smuzhiyun switch (cmd) {
3231*4882a593Smuzhiyun #ifdef CONFIG_COMPAT_32BIT_TIME
3232*4882a593Smuzhiyun case VIDIOC_DQEVENT_TIME32: {
3233*4882a593Smuzhiyun struct v4l2_event *ev = parg;
3234*4882a593Smuzhiyun struct v4l2_event_time32 ev32;
3235*4882a593Smuzhiyun
3236*4882a593Smuzhiyun memset(&ev32, 0, sizeof(ev32));
3237*4882a593Smuzhiyun
3238*4882a593Smuzhiyun ev32.type = ev->type;
3239*4882a593Smuzhiyun ev32.pending = ev->pending;
3240*4882a593Smuzhiyun ev32.sequence = ev->sequence;
3241*4882a593Smuzhiyun ev32.timestamp.tv_sec = ev->timestamp.tv_sec;
3242*4882a593Smuzhiyun ev32.timestamp.tv_nsec = ev->timestamp.tv_nsec;
3243*4882a593Smuzhiyun ev32.id = ev->id;
3244*4882a593Smuzhiyun
3245*4882a593Smuzhiyun memcpy(&ev32.u, &ev->u, sizeof(ev->u));
3246*4882a593Smuzhiyun memcpy(&ev32.reserved, &ev->reserved, sizeof(ev->reserved));
3247*4882a593Smuzhiyun
3248*4882a593Smuzhiyun if (copy_to_user(arg, &ev32, sizeof(ev32)))
3249*4882a593Smuzhiyun return -EFAULT;
3250*4882a593Smuzhiyun break;
3251*4882a593Smuzhiyun }
3252*4882a593Smuzhiyun case VIDIOC_QUERYBUF_TIME32:
3253*4882a593Smuzhiyun case VIDIOC_QBUF_TIME32:
3254*4882a593Smuzhiyun case VIDIOC_DQBUF_TIME32:
3255*4882a593Smuzhiyun case VIDIOC_PREPARE_BUF_TIME32: {
3256*4882a593Smuzhiyun struct v4l2_buffer *vb = parg;
3257*4882a593Smuzhiyun struct v4l2_buffer_time32 vb32;
3258*4882a593Smuzhiyun
3259*4882a593Smuzhiyun memset(&vb32, 0, sizeof(vb32));
3260*4882a593Smuzhiyun
3261*4882a593Smuzhiyun vb32.index = vb->index;
3262*4882a593Smuzhiyun vb32.type = vb->type;
3263*4882a593Smuzhiyun vb32.bytesused = vb->bytesused;
3264*4882a593Smuzhiyun vb32.flags = vb->flags;
3265*4882a593Smuzhiyun vb32.field = vb->field;
3266*4882a593Smuzhiyun vb32.timestamp.tv_sec = vb->timestamp.tv_sec;
3267*4882a593Smuzhiyun vb32.timestamp.tv_usec = vb->timestamp.tv_usec;
3268*4882a593Smuzhiyun vb32.timecode = vb->timecode;
3269*4882a593Smuzhiyun vb32.sequence = vb->sequence;
3270*4882a593Smuzhiyun vb32.memory = vb->memory;
3271*4882a593Smuzhiyun vb32.m.userptr = vb->m.userptr;
3272*4882a593Smuzhiyun vb32.length = vb->length;
3273*4882a593Smuzhiyun vb32.request_fd = vb->request_fd;
3274*4882a593Smuzhiyun
3275*4882a593Smuzhiyun if (copy_to_user(arg, &vb32, sizeof(vb32)))
3276*4882a593Smuzhiyun return -EFAULT;
3277*4882a593Smuzhiyun break;
3278*4882a593Smuzhiyun }
3279*4882a593Smuzhiyun #endif
3280*4882a593Smuzhiyun default:
3281*4882a593Smuzhiyun /* Copy results into user buffer */
3282*4882a593Smuzhiyun if (copy_to_user(arg, parg, _IOC_SIZE(cmd)))
3283*4882a593Smuzhiyun return -EFAULT;
3284*4882a593Smuzhiyun break;
3285*4882a593Smuzhiyun }
3286*4882a593Smuzhiyun
3287*4882a593Smuzhiyun return 0;
3288*4882a593Smuzhiyun }
3289*4882a593Smuzhiyun
3290*4882a593Smuzhiyun long
video_usercopy(struct file * file,unsigned int orig_cmd,unsigned long arg,v4l2_kioctl func)3291*4882a593Smuzhiyun video_usercopy(struct file *file, unsigned int orig_cmd, unsigned long arg,
3292*4882a593Smuzhiyun v4l2_kioctl func)
3293*4882a593Smuzhiyun {
3294*4882a593Smuzhiyun char sbuf[128];
3295*4882a593Smuzhiyun void *mbuf = NULL, *array_buf = NULL;
3296*4882a593Smuzhiyun void *parg = (void *)arg;
3297*4882a593Smuzhiyun long err = -EINVAL;
3298*4882a593Smuzhiyun bool has_array_args;
3299*4882a593Smuzhiyun bool always_copy = false;
3300*4882a593Smuzhiyun size_t array_size = 0;
3301*4882a593Smuzhiyun void __user *user_ptr = NULL;
3302*4882a593Smuzhiyun void **kernel_ptr = NULL;
3303*4882a593Smuzhiyun unsigned int cmd = video_translate_cmd(orig_cmd);
3304*4882a593Smuzhiyun const size_t ioc_size = _IOC_SIZE(cmd);
3305*4882a593Smuzhiyun
3306*4882a593Smuzhiyun /* Copy arguments into temp kernel buffer */
3307*4882a593Smuzhiyun if (_IOC_DIR(cmd) != _IOC_NONE) {
3308*4882a593Smuzhiyun if (ioc_size <= sizeof(sbuf)) {
3309*4882a593Smuzhiyun parg = sbuf;
3310*4882a593Smuzhiyun } else {
3311*4882a593Smuzhiyun /* too big to allocate from stack */
3312*4882a593Smuzhiyun mbuf = kvmalloc(ioc_size, GFP_KERNEL);
3313*4882a593Smuzhiyun if (NULL == mbuf)
3314*4882a593Smuzhiyun return -ENOMEM;
3315*4882a593Smuzhiyun parg = mbuf;
3316*4882a593Smuzhiyun }
3317*4882a593Smuzhiyun
3318*4882a593Smuzhiyun err = video_get_user((void __user *)arg, parg, orig_cmd,
3319*4882a593Smuzhiyun &always_copy);
3320*4882a593Smuzhiyun if (err)
3321*4882a593Smuzhiyun goto out;
3322*4882a593Smuzhiyun }
3323*4882a593Smuzhiyun
3324*4882a593Smuzhiyun err = check_array_args(cmd, parg, &array_size, &user_ptr, &kernel_ptr);
3325*4882a593Smuzhiyun if (err < 0)
3326*4882a593Smuzhiyun goto out;
3327*4882a593Smuzhiyun has_array_args = err;
3328*4882a593Smuzhiyun
3329*4882a593Smuzhiyun if (has_array_args) {
3330*4882a593Smuzhiyun array_buf = kvmalloc(array_size, GFP_KERNEL);
3331*4882a593Smuzhiyun err = -ENOMEM;
3332*4882a593Smuzhiyun if (array_buf == NULL)
3333*4882a593Smuzhiyun goto out_array_args;
3334*4882a593Smuzhiyun err = -EFAULT;
3335*4882a593Smuzhiyun if (copy_from_user(array_buf, user_ptr, array_size))
3336*4882a593Smuzhiyun goto out_array_args;
3337*4882a593Smuzhiyun *kernel_ptr = array_buf;
3338*4882a593Smuzhiyun }
3339*4882a593Smuzhiyun
3340*4882a593Smuzhiyun /* Handles IOCTL */
3341*4882a593Smuzhiyun err = func(file, cmd, parg);
3342*4882a593Smuzhiyun if (err == -ENOTTY || err == -ENOIOCTLCMD) {
3343*4882a593Smuzhiyun err = -ENOTTY;
3344*4882a593Smuzhiyun goto out;
3345*4882a593Smuzhiyun }
3346*4882a593Smuzhiyun
3347*4882a593Smuzhiyun if (err == 0) {
3348*4882a593Smuzhiyun if (cmd == VIDIOC_DQBUF)
3349*4882a593Smuzhiyun trace_v4l2_dqbuf(video_devdata(file)->minor, parg);
3350*4882a593Smuzhiyun else if (cmd == VIDIOC_QBUF)
3351*4882a593Smuzhiyun trace_v4l2_qbuf(video_devdata(file)->minor, parg);
3352*4882a593Smuzhiyun }
3353*4882a593Smuzhiyun
3354*4882a593Smuzhiyun if (has_array_args) {
3355*4882a593Smuzhiyun *kernel_ptr = (void __force *)user_ptr;
3356*4882a593Smuzhiyun if (copy_to_user(user_ptr, array_buf, array_size))
3357*4882a593Smuzhiyun err = -EFAULT;
3358*4882a593Smuzhiyun goto out_array_args;
3359*4882a593Smuzhiyun }
3360*4882a593Smuzhiyun /*
3361*4882a593Smuzhiyun * Some ioctls can return an error, but still have valid
3362*4882a593Smuzhiyun * results that must be returned.
3363*4882a593Smuzhiyun */
3364*4882a593Smuzhiyun if (err < 0 && !always_copy)
3365*4882a593Smuzhiyun goto out;
3366*4882a593Smuzhiyun
3367*4882a593Smuzhiyun out_array_args:
3368*4882a593Smuzhiyun if (video_put_user((void __user *)arg, parg, orig_cmd))
3369*4882a593Smuzhiyun err = -EFAULT;
3370*4882a593Smuzhiyun out:
3371*4882a593Smuzhiyun kvfree(array_buf);
3372*4882a593Smuzhiyun kvfree(mbuf);
3373*4882a593Smuzhiyun return err;
3374*4882a593Smuzhiyun }
3375*4882a593Smuzhiyun
video_ioctl2(struct file * file,unsigned int cmd,unsigned long arg)3376*4882a593Smuzhiyun long video_ioctl2(struct file *file,
3377*4882a593Smuzhiyun unsigned int cmd, unsigned long arg)
3378*4882a593Smuzhiyun {
3379*4882a593Smuzhiyun return video_usercopy(file, cmd, arg, __video_do_ioctl);
3380*4882a593Smuzhiyun }
3381*4882a593Smuzhiyun EXPORT_SYMBOL(video_ioctl2);
3382