12874c5fdSThomas Gleixner // SPDX-License-Identifier: GPL-2.0-or-later 25bc3cb74SMauro Carvalho Chehab /* 35bc3cb74SMauro Carvalho Chehab * Video capture interface for Linux version 2 45bc3cb74SMauro Carvalho Chehab * 55bc3cb74SMauro Carvalho Chehab * A generic framework to process V4L2 ioctl commands. 65bc3cb74SMauro Carvalho Chehab * 75bc3cb74SMauro Carvalho Chehab * Authors: Alan Cox, <alan@lxorguk.ukuu.org.uk> (version 1) 832590819SMauro Carvalho Chehab * Mauro Carvalho Chehab <mchehab@kernel.org> (version 2) 95bc3cb74SMauro Carvalho Chehab */ 105bc3cb74SMauro Carvalho Chehab 118dbcc3faSArnd Bergmann #include <linux/compat.h> 12758d90e1STomasz Figa #include <linux/mm.h> 135bc3cb74SMauro Carvalho Chehab #include <linux/module.h> 145bc3cb74SMauro Carvalho Chehab #include <linux/slab.h> 155bc3cb74SMauro Carvalho Chehab #include <linux/types.h> 165bc3cb74SMauro Carvalho Chehab #include <linux/kernel.h> 175bc3cb74SMauro Carvalho Chehab #include <linux/version.h> 185bc3cb74SMauro Carvalho Chehab 19a418bb3fSLaurent Pinchart #include <linux/v4l2-subdev.h> 205bc3cb74SMauro Carvalho Chehab #include <linux/videodev2.h> 215bc3cb74SMauro Carvalho Chehab 22f2d8b691SSakari Ailus #include <media/media-device.h> /* for media_set_bus_info() */ 235bc3cb74SMauro Carvalho Chehab #include <media/v4l2-common.h> 245bc3cb74SMauro Carvalho Chehab #include <media/v4l2-ioctl.h> 255bc3cb74SMauro Carvalho Chehab #include <media/v4l2-ctrls.h> 265bc3cb74SMauro Carvalho Chehab #include <media/v4l2-fh.h> 275bc3cb74SMauro Carvalho Chehab #include <media/v4l2-event.h> 285bc3cb74SMauro Carvalho Chehab #include <media/v4l2-device.h> 29c139990eSJunghak Sung #include <media/videobuf2-v4l2.h> 3077fa4e07SShuah Khan #include <media/v4l2-mc.h> 31d862bc08SHans Verkuil #include <media/v4l2-mem2mem.h> 325bc3cb74SMauro Carvalho Chehab 33aa32f4c0SHans Verkuil #include <trace/events/v4l2.h> 34aa32f4c0SHans Verkuil 3573f35418SHans Verkuil #define is_valid_ioctl(vfd, cmd) test_bit(_IOC_NR(cmd), (vfd)->valid_ioctls) 3673f35418SHans Verkuil 375bc3cb74SMauro Carvalho Chehab struct std_descr { 385bc3cb74SMauro Carvalho Chehab v4l2_std_id std; 395bc3cb74SMauro Carvalho Chehab const char *descr; 405bc3cb74SMauro Carvalho Chehab }; 415bc3cb74SMauro Carvalho Chehab 425bc3cb74SMauro Carvalho Chehab static const struct std_descr standards[] = { 435bc3cb74SMauro Carvalho Chehab { V4L2_STD_NTSC, "NTSC" }, 445bc3cb74SMauro Carvalho Chehab { V4L2_STD_NTSC_M, "NTSC-M" }, 455bc3cb74SMauro Carvalho Chehab { V4L2_STD_NTSC_M_JP, "NTSC-M-JP" }, 465bc3cb74SMauro Carvalho Chehab { V4L2_STD_NTSC_M_KR, "NTSC-M-KR" }, 475bc3cb74SMauro Carvalho Chehab { V4L2_STD_NTSC_443, "NTSC-443" }, 485bc3cb74SMauro Carvalho Chehab { V4L2_STD_PAL, "PAL" }, 495bc3cb74SMauro Carvalho Chehab { V4L2_STD_PAL_BG, "PAL-BG" }, 505bc3cb74SMauro Carvalho Chehab { V4L2_STD_PAL_B, "PAL-B" }, 515bc3cb74SMauro Carvalho Chehab { V4L2_STD_PAL_B1, "PAL-B1" }, 525bc3cb74SMauro Carvalho Chehab { V4L2_STD_PAL_G, "PAL-G" }, 535bc3cb74SMauro Carvalho Chehab { V4L2_STD_PAL_H, "PAL-H" }, 545bc3cb74SMauro Carvalho Chehab { V4L2_STD_PAL_I, "PAL-I" }, 555bc3cb74SMauro Carvalho Chehab { V4L2_STD_PAL_DK, "PAL-DK" }, 565bc3cb74SMauro Carvalho Chehab { V4L2_STD_PAL_D, "PAL-D" }, 575bc3cb74SMauro Carvalho Chehab { V4L2_STD_PAL_D1, "PAL-D1" }, 585bc3cb74SMauro Carvalho Chehab { V4L2_STD_PAL_K, "PAL-K" }, 595bc3cb74SMauro Carvalho Chehab { V4L2_STD_PAL_M, "PAL-M" }, 605bc3cb74SMauro Carvalho Chehab { V4L2_STD_PAL_N, "PAL-N" }, 615bc3cb74SMauro Carvalho Chehab { V4L2_STD_PAL_Nc, "PAL-Nc" }, 625bc3cb74SMauro Carvalho Chehab { V4L2_STD_PAL_60, "PAL-60" }, 635bc3cb74SMauro Carvalho Chehab { V4L2_STD_SECAM, "SECAM" }, 645bc3cb74SMauro Carvalho Chehab { V4L2_STD_SECAM_B, "SECAM-B" }, 655bc3cb74SMauro Carvalho Chehab { V4L2_STD_SECAM_G, "SECAM-G" }, 665bc3cb74SMauro Carvalho Chehab { V4L2_STD_SECAM_H, "SECAM-H" }, 675bc3cb74SMauro Carvalho Chehab { V4L2_STD_SECAM_DK, "SECAM-DK" }, 685bc3cb74SMauro Carvalho Chehab { V4L2_STD_SECAM_D, "SECAM-D" }, 695bc3cb74SMauro Carvalho Chehab { V4L2_STD_SECAM_K, "SECAM-K" }, 705bc3cb74SMauro Carvalho Chehab { V4L2_STD_SECAM_K1, "SECAM-K1" }, 715bc3cb74SMauro Carvalho Chehab { V4L2_STD_SECAM_L, "SECAM-L" }, 725bc3cb74SMauro Carvalho Chehab { V4L2_STD_SECAM_LC, "SECAM-Lc" }, 735bc3cb74SMauro Carvalho Chehab { 0, "Unknown" } 745bc3cb74SMauro Carvalho Chehab }; 755bc3cb74SMauro Carvalho Chehab 765bc3cb74SMauro Carvalho Chehab /* video4linux standard ID conversion to standard name 775bc3cb74SMauro Carvalho Chehab */ 785bc3cb74SMauro Carvalho Chehab const char *v4l2_norm_to_name(v4l2_std_id id) 795bc3cb74SMauro Carvalho Chehab { 805bc3cb74SMauro Carvalho Chehab u32 myid = id; 815bc3cb74SMauro Carvalho Chehab int i; 825bc3cb74SMauro Carvalho Chehab 835bc3cb74SMauro Carvalho Chehab /* HACK: ppc32 architecture doesn't have __ucmpdi2 function to handle 844faf7066SMauro Carvalho Chehab 64 bit comparisons. So, on that architecture, with some gcc 855bc3cb74SMauro Carvalho Chehab variants, compilation fails. Currently, the max value is 30bit wide. 865bc3cb74SMauro Carvalho Chehab */ 875bc3cb74SMauro Carvalho Chehab BUG_ON(myid != id); 885bc3cb74SMauro Carvalho Chehab 895bc3cb74SMauro Carvalho Chehab for (i = 0; standards[i].std; i++) 905bc3cb74SMauro Carvalho Chehab if (myid == standards[i].std) 915bc3cb74SMauro Carvalho Chehab break; 925bc3cb74SMauro Carvalho Chehab return standards[i].descr; 935bc3cb74SMauro Carvalho Chehab } 945bc3cb74SMauro Carvalho Chehab EXPORT_SYMBOL(v4l2_norm_to_name); 955bc3cb74SMauro Carvalho Chehab 965bc3cb74SMauro Carvalho Chehab /* Returns frame period for the given standard */ 975bc3cb74SMauro Carvalho Chehab void v4l2_video_std_frame_period(int id, struct v4l2_fract *frameperiod) 985bc3cb74SMauro Carvalho Chehab { 995bc3cb74SMauro Carvalho Chehab if (id & V4L2_STD_525_60) { 1005bc3cb74SMauro Carvalho Chehab frameperiod->numerator = 1001; 1015bc3cb74SMauro Carvalho Chehab frameperiod->denominator = 30000; 1025bc3cb74SMauro Carvalho Chehab } else { 1035bc3cb74SMauro Carvalho Chehab frameperiod->numerator = 1; 1045bc3cb74SMauro Carvalho Chehab frameperiod->denominator = 25; 1055bc3cb74SMauro Carvalho Chehab } 1065bc3cb74SMauro Carvalho Chehab } 1075bc3cb74SMauro Carvalho Chehab EXPORT_SYMBOL(v4l2_video_std_frame_period); 1085bc3cb74SMauro Carvalho Chehab 1095bc3cb74SMauro Carvalho Chehab /* Fill in the fields of a v4l2_standard structure according to the 1105bc3cb74SMauro Carvalho Chehab 'id' and 'transmission' parameters. Returns negative on error. */ 1115bc3cb74SMauro Carvalho Chehab int v4l2_video_std_construct(struct v4l2_standard *vs, 1125bc3cb74SMauro Carvalho Chehab int id, const char *name) 1135bc3cb74SMauro Carvalho Chehab { 1145bc3cb74SMauro Carvalho Chehab vs->id = id; 1155bc3cb74SMauro Carvalho Chehab v4l2_video_std_frame_period(id, &vs->frameperiod); 1165bc3cb74SMauro Carvalho Chehab vs->framelines = (id & V4L2_STD_525_60) ? 525 : 625; 117c0decac1SMauro Carvalho Chehab strscpy(vs->name, name, sizeof(vs->name)); 1185bc3cb74SMauro Carvalho Chehab return 0; 1195bc3cb74SMauro Carvalho Chehab } 1205bc3cb74SMauro Carvalho Chehab EXPORT_SYMBOL(v4l2_video_std_construct); 1215bc3cb74SMauro Carvalho Chehab 122aa2f8871SNiklas Söderlund /* Fill in the fields of a v4l2_standard structure according to the 123aa2f8871SNiklas Söderlund * 'id' and 'vs->index' parameters. Returns negative on error. */ 124aa2f8871SNiklas Söderlund int v4l_video_std_enumstd(struct v4l2_standard *vs, v4l2_std_id id) 125aa2f8871SNiklas Söderlund { 126aa2f8871SNiklas Söderlund v4l2_std_id curr_id = 0; 127aa2f8871SNiklas Söderlund unsigned int index = vs->index, i, j = 0; 128aa2f8871SNiklas Söderlund const char *descr = ""; 129aa2f8871SNiklas Söderlund 130aa2f8871SNiklas Söderlund /* Return -ENODATA if the id for the current input 131aa2f8871SNiklas Söderlund or output is 0, meaning that it doesn't support this API. */ 132aa2f8871SNiklas Söderlund if (id == 0) 133aa2f8871SNiklas Söderlund return -ENODATA; 134aa2f8871SNiklas Söderlund 135aa2f8871SNiklas Söderlund /* Return norm array in a canonical way */ 136aa2f8871SNiklas Söderlund for (i = 0; i <= index && id; i++) { 137aa2f8871SNiklas Söderlund /* last std value in the standards array is 0, so this 138aa2f8871SNiklas Söderlund while always ends there since (id & 0) == 0. */ 139aa2f8871SNiklas Söderlund while ((id & standards[j].std) != standards[j].std) 140aa2f8871SNiklas Söderlund j++; 141aa2f8871SNiklas Söderlund curr_id = standards[j].std; 142aa2f8871SNiklas Söderlund descr = standards[j].descr; 143aa2f8871SNiklas Söderlund j++; 144aa2f8871SNiklas Söderlund if (curr_id == 0) 145aa2f8871SNiklas Söderlund break; 146aa2f8871SNiklas Söderlund if (curr_id != V4L2_STD_PAL && 147aa2f8871SNiklas Söderlund curr_id != V4L2_STD_SECAM && 148aa2f8871SNiklas Söderlund curr_id != V4L2_STD_NTSC) 149aa2f8871SNiklas Söderlund id &= ~curr_id; 150aa2f8871SNiklas Söderlund } 151aa2f8871SNiklas Söderlund if (i <= index) 152aa2f8871SNiklas Söderlund return -EINVAL; 153aa2f8871SNiklas Söderlund 154aa2f8871SNiklas Söderlund v4l2_video_std_construct(vs, curr_id, descr); 155aa2f8871SNiklas Söderlund return 0; 156aa2f8871SNiklas Söderlund } 157aa2f8871SNiklas Söderlund 1585bc3cb74SMauro Carvalho Chehab /* ----------------------------------------------------------------- */ 1595bc3cb74SMauro Carvalho Chehab /* some arrays for pretty-printing debug messages of enum types */ 1605bc3cb74SMauro Carvalho Chehab 1615bc3cb74SMauro Carvalho Chehab const char *v4l2_field_names[] = { 1625bc3cb74SMauro Carvalho Chehab [V4L2_FIELD_ANY] = "any", 1635bc3cb74SMauro Carvalho Chehab [V4L2_FIELD_NONE] = "none", 1645bc3cb74SMauro Carvalho Chehab [V4L2_FIELD_TOP] = "top", 1655bc3cb74SMauro Carvalho Chehab [V4L2_FIELD_BOTTOM] = "bottom", 1665bc3cb74SMauro Carvalho Chehab [V4L2_FIELD_INTERLACED] = "interlaced", 1675bc3cb74SMauro Carvalho Chehab [V4L2_FIELD_SEQ_TB] = "seq-tb", 1685bc3cb74SMauro Carvalho Chehab [V4L2_FIELD_SEQ_BT] = "seq-bt", 1695bc3cb74SMauro Carvalho Chehab [V4L2_FIELD_ALTERNATE] = "alternate", 1705bc3cb74SMauro Carvalho Chehab [V4L2_FIELD_INTERLACED_TB] = "interlaced-tb", 1715bc3cb74SMauro Carvalho Chehab [V4L2_FIELD_INTERLACED_BT] = "interlaced-bt", 1725bc3cb74SMauro Carvalho Chehab }; 1735bc3cb74SMauro Carvalho Chehab EXPORT_SYMBOL(v4l2_field_names); 1745bc3cb74SMauro Carvalho Chehab 1755bc3cb74SMauro Carvalho Chehab const char *v4l2_type_names[] = { 176839aa56dSHans Verkuil [0] = "0", 1775bc3cb74SMauro Carvalho Chehab [V4L2_BUF_TYPE_VIDEO_CAPTURE] = "vid-cap", 1785bc3cb74SMauro Carvalho Chehab [V4L2_BUF_TYPE_VIDEO_OVERLAY] = "vid-overlay", 1795bc3cb74SMauro Carvalho Chehab [V4L2_BUF_TYPE_VIDEO_OUTPUT] = "vid-out", 1805bc3cb74SMauro Carvalho Chehab [V4L2_BUF_TYPE_VBI_CAPTURE] = "vbi-cap", 1815bc3cb74SMauro Carvalho Chehab [V4L2_BUF_TYPE_VBI_OUTPUT] = "vbi-out", 1825bc3cb74SMauro Carvalho Chehab [V4L2_BUF_TYPE_SLICED_VBI_CAPTURE] = "sliced-vbi-cap", 1835bc3cb74SMauro Carvalho Chehab [V4L2_BUF_TYPE_SLICED_VBI_OUTPUT] = "sliced-vbi-out", 1845bc3cb74SMauro Carvalho Chehab [V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY] = "vid-out-overlay", 1855bc3cb74SMauro Carvalho Chehab [V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE] = "vid-cap-mplane", 1865bc3cb74SMauro Carvalho Chehab [V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE] = "vid-out-mplane", 1876f3073b8SAntti Palosaari [V4L2_BUF_TYPE_SDR_CAPTURE] = "sdr-cap", 1889effc72fSAntti Palosaari [V4L2_BUF_TYPE_SDR_OUTPUT] = "sdr-out", 189fb9ffa6aSLaurent Pinchart [V4L2_BUF_TYPE_META_CAPTURE] = "meta-cap", 19072148d1aSSakari Ailus [V4L2_BUF_TYPE_META_OUTPUT] = "meta-out", 1915bc3cb74SMauro Carvalho Chehab }; 1925bc3cb74SMauro Carvalho Chehab EXPORT_SYMBOL(v4l2_type_names); 1935bc3cb74SMauro Carvalho Chehab 1945bc3cb74SMauro Carvalho Chehab static const char *v4l2_memory_names[] = { 1955bc3cb74SMauro Carvalho Chehab [V4L2_MEMORY_MMAP] = "mmap", 1965bc3cb74SMauro Carvalho Chehab [V4L2_MEMORY_USERPTR] = "userptr", 1975bc3cb74SMauro Carvalho Chehab [V4L2_MEMORY_OVERLAY] = "overlay", 198051c7788SSumit Semwal [V4L2_MEMORY_DMABUF] = "dmabuf", 1995bc3cb74SMauro Carvalho Chehab }; 2005bc3cb74SMauro Carvalho Chehab 201d9246240SHans Verkuil #define prt_names(a, arr) (((unsigned)(a)) < ARRAY_SIZE(arr) ? arr[a] : "unknown") 2025bc3cb74SMauro Carvalho Chehab 2035bc3cb74SMauro Carvalho Chehab /* ------------------------------------------------------------------ */ 2045bc3cb74SMauro Carvalho Chehab /* debug help functions */ 2055bc3cb74SMauro Carvalho Chehab 2065bc3cb74SMauro Carvalho Chehab static void v4l_print_querycap(const void *arg, bool write_only) 2075bc3cb74SMauro Carvalho Chehab { 2085bc3cb74SMauro Carvalho Chehab const struct v4l2_capability *p = arg; 2095bc3cb74SMauro Carvalho Chehab 2108720427cSMauro Carvalho Chehab pr_cont("driver=%.*s, card=%.*s, bus=%.*s, version=0x%08x, capabilities=0x%08x, device_caps=0x%08x\n", 21127d5a87cSHans Verkuil (int)sizeof(p->driver), p->driver, 21227d5a87cSHans Verkuil (int)sizeof(p->card), p->card, 21327d5a87cSHans Verkuil (int)sizeof(p->bus_info), p->bus_info, 2145bc3cb74SMauro Carvalho Chehab p->version, p->capabilities, p->device_caps); 2155bc3cb74SMauro Carvalho Chehab } 2165bc3cb74SMauro Carvalho Chehab 2175bc3cb74SMauro Carvalho Chehab static void v4l_print_enuminput(const void *arg, bool write_only) 2185bc3cb74SMauro Carvalho Chehab { 2195bc3cb74SMauro Carvalho Chehab const struct v4l2_input *p = arg; 2205bc3cb74SMauro Carvalho Chehab 2218720427cSMauro Carvalho Chehab pr_cont("index=%u, name=%.*s, type=%u, audioset=0x%x, tuner=%u, std=0x%08Lx, status=0x%x, capabilities=0x%x\n", 22227d5a87cSHans Verkuil p->index, (int)sizeof(p->name), p->name, p->type, p->audioset, 22327d5a87cSHans Verkuil p->tuner, (unsigned long long)p->std, p->status, 22427d5a87cSHans Verkuil p->capabilities); 2255bc3cb74SMauro Carvalho Chehab } 2265bc3cb74SMauro Carvalho Chehab 2275bc3cb74SMauro Carvalho Chehab static void v4l_print_enumoutput(const void *arg, bool write_only) 2285bc3cb74SMauro Carvalho Chehab { 2295bc3cb74SMauro Carvalho Chehab const struct v4l2_output *p = arg; 2305bc3cb74SMauro Carvalho Chehab 2318720427cSMauro Carvalho Chehab pr_cont("index=%u, name=%.*s, type=%u, audioset=0x%x, modulator=%u, std=0x%08Lx, capabilities=0x%x\n", 23227d5a87cSHans Verkuil p->index, (int)sizeof(p->name), p->name, p->type, p->audioset, 23327d5a87cSHans Verkuil p->modulator, (unsigned long long)p->std, p->capabilities); 2345bc3cb74SMauro Carvalho Chehab } 2355bc3cb74SMauro Carvalho Chehab 2365bc3cb74SMauro Carvalho Chehab static void v4l_print_audio(const void *arg, bool write_only) 2375bc3cb74SMauro Carvalho Chehab { 2385bc3cb74SMauro Carvalho Chehab const struct v4l2_audio *p = arg; 2395bc3cb74SMauro Carvalho Chehab 2405bc3cb74SMauro Carvalho Chehab if (write_only) 2415bc3cb74SMauro Carvalho Chehab pr_cont("index=%u, mode=0x%x\n", p->index, p->mode); 2425bc3cb74SMauro Carvalho Chehab else 24327d5a87cSHans Verkuil pr_cont("index=%u, name=%.*s, capability=0x%x, mode=0x%x\n", 24427d5a87cSHans Verkuil p->index, (int)sizeof(p->name), p->name, 24527d5a87cSHans Verkuil p->capability, p->mode); 2465bc3cb74SMauro Carvalho Chehab } 2475bc3cb74SMauro Carvalho Chehab 2485bc3cb74SMauro Carvalho Chehab static void v4l_print_audioout(const void *arg, bool write_only) 2495bc3cb74SMauro Carvalho Chehab { 2505bc3cb74SMauro Carvalho Chehab const struct v4l2_audioout *p = arg; 2515bc3cb74SMauro Carvalho Chehab 2525bc3cb74SMauro Carvalho Chehab if (write_only) 2535bc3cb74SMauro Carvalho Chehab pr_cont("index=%u\n", p->index); 2545bc3cb74SMauro Carvalho Chehab else 25527d5a87cSHans Verkuil pr_cont("index=%u, name=%.*s, capability=0x%x, mode=0x%x\n", 25627d5a87cSHans Verkuil p->index, (int)sizeof(p->name), p->name, 25727d5a87cSHans Verkuil p->capability, p->mode); 2585bc3cb74SMauro Carvalho Chehab } 2595bc3cb74SMauro Carvalho Chehab 2605bc3cb74SMauro Carvalho Chehab static void v4l_print_fmtdesc(const void *arg, bool write_only) 2615bc3cb74SMauro Carvalho Chehab { 2625bc3cb74SMauro Carvalho Chehab const struct v4l2_fmtdesc *p = arg; 2635bc3cb74SMauro Carvalho Chehab 264e927e1e0SSakari Ailus pr_cont("index=%u, type=%s, flags=0x%x, pixelformat=%p4cc, mbus_code=0x%04x, description='%.*s'\n", 2655bc3cb74SMauro Carvalho Chehab p->index, prt_names(p->type, v4l2_type_names), 266e927e1e0SSakari Ailus p->flags, &p->pixelformat, p->mbus_code, 26727d5a87cSHans Verkuil (int)sizeof(p->description), p->description); 2685bc3cb74SMauro Carvalho Chehab } 2695bc3cb74SMauro Carvalho Chehab 2705bc3cb74SMauro Carvalho Chehab static void v4l_print_format(const void *arg, bool write_only) 2715bc3cb74SMauro Carvalho Chehab { 2725bc3cb74SMauro Carvalho Chehab const struct v4l2_format *p = arg; 2735bc3cb74SMauro Carvalho Chehab const struct v4l2_pix_format *pix; 2745bc3cb74SMauro Carvalho Chehab const struct v4l2_pix_format_mplane *mp; 2755bc3cb74SMauro Carvalho Chehab const struct v4l2_vbi_format *vbi; 2765bc3cb74SMauro Carvalho Chehab const struct v4l2_sliced_vbi_format *sliced; 2775bc3cb74SMauro Carvalho Chehab const struct v4l2_window *win; 278fb9ffa6aSLaurent Pinchart const struct v4l2_meta_format *meta; 27924bb30c8SSakari Ailus u32 pixelformat; 2807fe9f01cSSakari Ailus u32 planes; 2815bc3cb74SMauro Carvalho Chehab unsigned i; 2825bc3cb74SMauro Carvalho Chehab 2835bc3cb74SMauro Carvalho Chehab pr_cont("type=%s", prt_names(p->type, v4l2_type_names)); 2845bc3cb74SMauro Carvalho Chehab switch (p->type) { 2855bc3cb74SMauro Carvalho Chehab case V4L2_BUF_TYPE_VIDEO_CAPTURE: 2865bc3cb74SMauro Carvalho Chehab case V4L2_BUF_TYPE_VIDEO_OUTPUT: 2875bc3cb74SMauro Carvalho Chehab pix = &p->fmt.pix; 288e927e1e0SSakari Ailus pr_cont(", width=%u, height=%u, pixelformat=%p4cc, field=%s, bytesperline=%u, sizeimage=%u, colorspace=%d, flags=0x%x, ycbcr_enc=%u, quantization=%u, xfer_func=%u\n", 289e927e1e0SSakari Ailus pix->width, pix->height, &pix->pixelformat, 2905bc3cb74SMauro Carvalho Chehab prt_names(pix->field, v4l2_field_names), 2915bc3cb74SMauro Carvalho Chehab pix->bytesperline, pix->sizeimage, 292736d96b5SHans Verkuil pix->colorspace, pix->flags, pix->ycbcr_enc, 29374fdcb2eSHans Verkuil pix->quantization, pix->xfer_func); 2945bc3cb74SMauro Carvalho Chehab break; 2955bc3cb74SMauro Carvalho Chehab case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE: 2965bc3cb74SMauro Carvalho Chehab case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE: 2975bc3cb74SMauro Carvalho Chehab mp = &p->fmt.pix_mp; 29824bb30c8SSakari Ailus pixelformat = mp->pixelformat; 299e927e1e0SSakari Ailus pr_cont(", width=%u, height=%u, format=%p4cc, field=%s, colorspace=%d, num_planes=%u, flags=0x%x, ycbcr_enc=%u, quantization=%u, xfer_func=%u\n", 30024bb30c8SSakari Ailus mp->width, mp->height, &pixelformat, 3015bc3cb74SMauro Carvalho Chehab prt_names(mp->field, v4l2_field_names), 302736d96b5SHans Verkuil mp->colorspace, mp->num_planes, mp->flags, 30374fdcb2eSHans Verkuil mp->ycbcr_enc, mp->quantization, mp->xfer_func); 3047fe9f01cSSakari Ailus planes = min_t(u32, mp->num_planes, VIDEO_MAX_PLANES); 3057fe9f01cSSakari Ailus for (i = 0; i < planes; i++) 3065bc3cb74SMauro Carvalho Chehab printk(KERN_DEBUG "plane %u: bytesperline=%u sizeimage=%u\n", i, 3075bc3cb74SMauro Carvalho Chehab mp->plane_fmt[i].bytesperline, 3085bc3cb74SMauro Carvalho Chehab mp->plane_fmt[i].sizeimage); 3095bc3cb74SMauro Carvalho Chehab break; 3105bc3cb74SMauro Carvalho Chehab case V4L2_BUF_TYPE_VIDEO_OVERLAY: 3115bc3cb74SMauro Carvalho Chehab case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY: 3125bc3cb74SMauro Carvalho Chehab win = &p->fmt.win; 31399ba0703SHans Verkuil pr_cont(", wxh=%dx%d, x,y=%d,%d, field=%s, chromakey=0x%08x, global_alpha=0x%02x\n", 314560dde24SHans Verkuil win->w.width, win->w.height, win->w.left, win->w.top, 3155bc3cb74SMauro Carvalho Chehab prt_names(win->field, v4l2_field_names), 31699ba0703SHans Verkuil win->chromakey, win->global_alpha); 3175bc3cb74SMauro Carvalho Chehab break; 3185bc3cb74SMauro Carvalho Chehab case V4L2_BUF_TYPE_VBI_CAPTURE: 3195bc3cb74SMauro Carvalho Chehab case V4L2_BUF_TYPE_VBI_OUTPUT: 3205bc3cb74SMauro Carvalho Chehab vbi = &p->fmt.vbi; 321e927e1e0SSakari Ailus pr_cont(", sampling_rate=%u, offset=%u, samples_per_line=%u, sample_format=%p4cc, start=%u,%u, count=%u,%u\n", 3225bc3cb74SMauro Carvalho Chehab vbi->sampling_rate, vbi->offset, 323e927e1e0SSakari Ailus vbi->samples_per_line, &vbi->sample_format, 3245bc3cb74SMauro Carvalho Chehab vbi->start[0], vbi->start[1], 3255bc3cb74SMauro Carvalho Chehab vbi->count[0], vbi->count[1]); 3265bc3cb74SMauro Carvalho Chehab break; 3275bc3cb74SMauro Carvalho Chehab case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE: 3285bc3cb74SMauro Carvalho Chehab case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT: 3295bc3cb74SMauro Carvalho Chehab sliced = &p->fmt.sliced; 3305bc3cb74SMauro Carvalho Chehab pr_cont(", service_set=0x%08x, io_size=%d\n", 3315bc3cb74SMauro Carvalho Chehab sliced->service_set, sliced->io_size); 3325bc3cb74SMauro Carvalho Chehab for (i = 0; i < 24; i++) 3335bc3cb74SMauro Carvalho Chehab printk(KERN_DEBUG "line[%02u]=0x%04x, 0x%04x\n", i, 3345bc3cb74SMauro Carvalho Chehab sliced->service_lines[0][i], 3355bc3cb74SMauro Carvalho Chehab sliced->service_lines[1][i]); 3365bc3cb74SMauro Carvalho Chehab break; 337582c52cbSAntti Palosaari case V4L2_BUF_TYPE_SDR_CAPTURE: 3389effc72fSAntti Palosaari case V4L2_BUF_TYPE_SDR_OUTPUT: 33924bb30c8SSakari Ailus pixelformat = p->fmt.sdr.pixelformat; 34024bb30c8SSakari Ailus pr_cont(", pixelformat=%p4cc\n", &pixelformat); 341582c52cbSAntti Palosaari break; 342fb9ffa6aSLaurent Pinchart case V4L2_BUF_TYPE_META_CAPTURE: 34372148d1aSSakari Ailus case V4L2_BUF_TYPE_META_OUTPUT: 344fb9ffa6aSLaurent Pinchart meta = &p->fmt.meta; 34524bb30c8SSakari Ailus pixelformat = meta->dataformat; 346e927e1e0SSakari Ailus pr_cont(", dataformat=%p4cc, buffersize=%u\n", 34724bb30c8SSakari Ailus &pixelformat, meta->buffersize); 348fb9ffa6aSLaurent Pinchart break; 3495bc3cb74SMauro Carvalho Chehab } 3505bc3cb74SMauro Carvalho Chehab } 3515bc3cb74SMauro Carvalho Chehab 3525bc3cb74SMauro Carvalho Chehab static void v4l_print_framebuffer(const void *arg, bool write_only) 3535bc3cb74SMauro Carvalho Chehab { 3545bc3cb74SMauro Carvalho Chehab const struct v4l2_framebuffer *p = arg; 3555bc3cb74SMauro Carvalho Chehab 356e927e1e0SSakari Ailus pr_cont("capability=0x%x, flags=0x%x, base=0x%p, width=%u, height=%u, pixelformat=%p4cc, bytesperline=%u, sizeimage=%u, colorspace=%d\n", 357e927e1e0SSakari Ailus p->capability, p->flags, p->base, p->fmt.width, p->fmt.height, 358e927e1e0SSakari Ailus &p->fmt.pixelformat, p->fmt.bytesperline, p->fmt.sizeimage, 3595bc3cb74SMauro Carvalho Chehab p->fmt.colorspace); 3605bc3cb74SMauro Carvalho Chehab } 3615bc3cb74SMauro Carvalho Chehab 3625bc3cb74SMauro Carvalho Chehab static void v4l_print_buftype(const void *arg, bool write_only) 3635bc3cb74SMauro Carvalho Chehab { 3645bc3cb74SMauro Carvalho Chehab pr_cont("type=%s\n", prt_names(*(u32 *)arg, v4l2_type_names)); 3655bc3cb74SMauro Carvalho Chehab } 3665bc3cb74SMauro Carvalho Chehab 3675bc3cb74SMauro Carvalho Chehab static void v4l_print_modulator(const void *arg, bool write_only) 3685bc3cb74SMauro Carvalho Chehab { 3695bc3cb74SMauro Carvalho Chehab const struct v4l2_modulator *p = arg; 3705bc3cb74SMauro Carvalho Chehab 3715bc3cb74SMauro Carvalho Chehab if (write_only) 372560dde24SHans Verkuil pr_cont("index=%u, txsubchans=0x%x\n", p->index, p->txsubchans); 3735bc3cb74SMauro Carvalho Chehab else 3748720427cSMauro Carvalho Chehab pr_cont("index=%u, name=%.*s, capability=0x%x, rangelow=%u, rangehigh=%u, txsubchans=0x%x\n", 37527d5a87cSHans Verkuil p->index, (int)sizeof(p->name), p->name, p->capability, 3765bc3cb74SMauro Carvalho Chehab p->rangelow, p->rangehigh, p->txsubchans); 3775bc3cb74SMauro Carvalho Chehab } 3785bc3cb74SMauro Carvalho Chehab 3795bc3cb74SMauro Carvalho Chehab static void v4l_print_tuner(const void *arg, bool write_only) 3805bc3cb74SMauro Carvalho Chehab { 3815bc3cb74SMauro Carvalho Chehab const struct v4l2_tuner *p = arg; 3825bc3cb74SMauro Carvalho Chehab 3835bc3cb74SMauro Carvalho Chehab if (write_only) 3845bc3cb74SMauro Carvalho Chehab pr_cont("index=%u, audmode=%u\n", p->index, p->audmode); 3855bc3cb74SMauro Carvalho Chehab else 3868720427cSMauro Carvalho Chehab pr_cont("index=%u, name=%.*s, type=%u, capability=0x%x, rangelow=%u, rangehigh=%u, signal=%u, afc=%d, rxsubchans=0x%x, audmode=%u\n", 38727d5a87cSHans Verkuil p->index, (int)sizeof(p->name), p->name, p->type, 3885bc3cb74SMauro Carvalho Chehab p->capability, p->rangelow, 3895bc3cb74SMauro Carvalho Chehab p->rangehigh, p->signal, p->afc, 3905bc3cb74SMauro Carvalho Chehab p->rxsubchans, p->audmode); 3915bc3cb74SMauro Carvalho Chehab } 3925bc3cb74SMauro Carvalho Chehab 3935bc3cb74SMauro Carvalho Chehab static void v4l_print_frequency(const void *arg, bool write_only) 3945bc3cb74SMauro Carvalho Chehab { 3955bc3cb74SMauro Carvalho Chehab const struct v4l2_frequency *p = arg; 3965bc3cb74SMauro Carvalho Chehab 3975bc3cb74SMauro Carvalho Chehab pr_cont("tuner=%u, type=%u, frequency=%u\n", 3985bc3cb74SMauro Carvalho Chehab p->tuner, p->type, p->frequency); 3995bc3cb74SMauro Carvalho Chehab } 4005bc3cb74SMauro Carvalho Chehab 4015bc3cb74SMauro Carvalho Chehab static void v4l_print_standard(const void *arg, bool write_only) 4025bc3cb74SMauro Carvalho Chehab { 4035bc3cb74SMauro Carvalho Chehab const struct v4l2_standard *p = arg; 4045bc3cb74SMauro Carvalho Chehab 4058720427cSMauro Carvalho Chehab pr_cont("index=%u, id=0x%Lx, name=%.*s, fps=%u/%u, framelines=%u\n", 4068720427cSMauro Carvalho Chehab p->index, 40727d5a87cSHans Verkuil (unsigned long long)p->id, (int)sizeof(p->name), p->name, 4085bc3cb74SMauro Carvalho Chehab p->frameperiod.numerator, 4095bc3cb74SMauro Carvalho Chehab p->frameperiod.denominator, 4105bc3cb74SMauro Carvalho Chehab p->framelines); 4115bc3cb74SMauro Carvalho Chehab } 4125bc3cb74SMauro Carvalho Chehab 4135bc3cb74SMauro Carvalho Chehab static void v4l_print_std(const void *arg, bool write_only) 4145bc3cb74SMauro Carvalho Chehab { 4155bc3cb74SMauro Carvalho Chehab pr_cont("std=0x%08Lx\n", *(const long long unsigned *)arg); 4165bc3cb74SMauro Carvalho Chehab } 4175bc3cb74SMauro Carvalho Chehab 4185bc3cb74SMauro Carvalho Chehab static void v4l_print_hw_freq_seek(const void *arg, bool write_only) 4195bc3cb74SMauro Carvalho Chehab { 4205bc3cb74SMauro Carvalho Chehab const struct v4l2_hw_freq_seek *p = arg; 4215bc3cb74SMauro Carvalho Chehab 4228720427cSMauro Carvalho Chehab pr_cont("tuner=%u, type=%u, seek_upward=%u, wrap_around=%u, spacing=%u, rangelow=%u, rangehigh=%u\n", 42379e8c7beSMauro Carvalho Chehab p->tuner, p->type, p->seek_upward, p->wrap_around, p->spacing, 42479e8c7beSMauro Carvalho Chehab p->rangelow, p->rangehigh); 4255bc3cb74SMauro Carvalho Chehab } 4265bc3cb74SMauro Carvalho Chehab 4275bc3cb74SMauro Carvalho Chehab static void v4l_print_requestbuffers(const void *arg, bool write_only) 4285bc3cb74SMauro Carvalho Chehab { 4295bc3cb74SMauro Carvalho Chehab const struct v4l2_requestbuffers *p = arg; 4305bc3cb74SMauro Carvalho Chehab 4315bc3cb74SMauro Carvalho Chehab pr_cont("count=%d, type=%s, memory=%s\n", 4325bc3cb74SMauro Carvalho Chehab p->count, 4335bc3cb74SMauro Carvalho Chehab prt_names(p->type, v4l2_type_names), 4345bc3cb74SMauro Carvalho Chehab prt_names(p->memory, v4l2_memory_names)); 4355bc3cb74SMauro Carvalho Chehab } 4365bc3cb74SMauro Carvalho Chehab 4375bc3cb74SMauro Carvalho Chehab static void v4l_print_buffer(const void *arg, bool write_only) 4385bc3cb74SMauro Carvalho Chehab { 4395bc3cb74SMauro Carvalho Chehab const struct v4l2_buffer *p = arg; 4405bc3cb74SMauro Carvalho Chehab const struct v4l2_timecode *tc = &p->timecode; 4415bc3cb74SMauro Carvalho Chehab const struct v4l2_plane *plane; 4425bc3cb74SMauro Carvalho Chehab int i; 4435bc3cb74SMauro Carvalho Chehab 44448e15418SHans Verkuil pr_cont("%02d:%02d:%02d.%06ld index=%d, type=%s, request_fd=%d, flags=0x%08x, field=%s, sequence=%d, memory=%s", 445577c89b0SArnd Bergmann (int)p->timestamp.tv_sec / 3600, 446577c89b0SArnd Bergmann ((int)p->timestamp.tv_sec / 60) % 60, 447577c89b0SArnd Bergmann ((int)p->timestamp.tv_sec % 60), 4485bc3cb74SMauro Carvalho Chehab (long)p->timestamp.tv_usec, 4495bc3cb74SMauro Carvalho Chehab p->index, 45062fed26fSHans Verkuil prt_names(p->type, v4l2_type_names), p->request_fd, 4515bc3cb74SMauro Carvalho Chehab p->flags, prt_names(p->field, v4l2_field_names), 4525bc3cb74SMauro Carvalho Chehab p->sequence, prt_names(p->memory, v4l2_memory_names)); 4535bc3cb74SMauro Carvalho Chehab 4545bc3cb74SMauro Carvalho Chehab if (V4L2_TYPE_IS_MULTIPLANAR(p->type) && p->m.planes) { 4555bc3cb74SMauro Carvalho Chehab pr_cont("\n"); 4565bc3cb74SMauro Carvalho Chehab for (i = 0; i < p->length; ++i) { 4575bc3cb74SMauro Carvalho Chehab plane = &p->m.planes[i]; 4585bc3cb74SMauro Carvalho Chehab printk(KERN_DEBUG 4598720427cSMauro Carvalho Chehab "plane %d: bytesused=%d, data_offset=0x%08x, offset/userptr=0x%lx, length=%d\n", 4605bc3cb74SMauro Carvalho Chehab i, plane->bytesused, plane->data_offset, 4615bc3cb74SMauro Carvalho Chehab plane->m.userptr, plane->length); 4625bc3cb74SMauro Carvalho Chehab } 4635bc3cb74SMauro Carvalho Chehab } else { 464560dde24SHans Verkuil pr_cont(", bytesused=%d, offset/userptr=0x%lx, length=%d\n", 4655bc3cb74SMauro Carvalho Chehab p->bytesused, p->m.userptr, p->length); 4665bc3cb74SMauro Carvalho Chehab } 4675bc3cb74SMauro Carvalho Chehab 4688720427cSMauro Carvalho Chehab printk(KERN_DEBUG "timecode=%02d:%02d:%02d type=%d, flags=0x%08x, frames=%d, userbits=0x%08x\n", 4695bc3cb74SMauro Carvalho Chehab tc->hours, tc->minutes, tc->seconds, 4705bc3cb74SMauro Carvalho Chehab tc->type, tc->flags, tc->frames, *(__u32 *)tc->userbits); 4715bc3cb74SMauro Carvalho Chehab } 4725bc3cb74SMauro Carvalho Chehab 473b799d09aSTomasz Stanislawski static void v4l_print_exportbuffer(const void *arg, bool write_only) 474b799d09aSTomasz Stanislawski { 475b799d09aSTomasz Stanislawski const struct v4l2_exportbuffer *p = arg; 476b799d09aSTomasz Stanislawski 477b799d09aSTomasz Stanislawski pr_cont("fd=%d, type=%s, index=%u, plane=%u, flags=0x%08x\n", 478b799d09aSTomasz Stanislawski p->fd, prt_names(p->type, v4l2_type_names), 479b799d09aSTomasz Stanislawski p->index, p->plane, p->flags); 480b799d09aSTomasz Stanislawski } 481b799d09aSTomasz Stanislawski 4825bc3cb74SMauro Carvalho Chehab static void v4l_print_create_buffers(const void *arg, bool write_only) 4835bc3cb74SMauro Carvalho Chehab { 4845bc3cb74SMauro Carvalho Chehab const struct v4l2_create_buffers *p = arg; 4855bc3cb74SMauro Carvalho Chehab 486319c4bd4SHelen Koike pr_cont("index=%d, count=%d, memory=%s, capabilities=0x%08x, ", 487319c4bd4SHelen Koike p->index, p->count, prt_names(p->memory, v4l2_memory_names), 488319c4bd4SHelen Koike p->capabilities); 4895bc3cb74SMauro Carvalho Chehab v4l_print_format(&p->format, write_only); 4905bc3cb74SMauro Carvalho Chehab } 4915bc3cb74SMauro Carvalho Chehab 4925bc3cb74SMauro Carvalho Chehab static void v4l_print_streamparm(const void *arg, bool write_only) 4935bc3cb74SMauro Carvalho Chehab { 4945bc3cb74SMauro Carvalho Chehab const struct v4l2_streamparm *p = arg; 4955bc3cb74SMauro Carvalho Chehab 4965bc3cb74SMauro Carvalho Chehab pr_cont("type=%s", prt_names(p->type, v4l2_type_names)); 4975bc3cb74SMauro Carvalho Chehab 4985bc3cb74SMauro Carvalho Chehab if (p->type == V4L2_BUF_TYPE_VIDEO_CAPTURE || 4995bc3cb74SMauro Carvalho Chehab p->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) { 5005bc3cb74SMauro Carvalho Chehab const struct v4l2_captureparm *c = &p->parm.capture; 5015bc3cb74SMauro Carvalho Chehab 5028720427cSMauro Carvalho Chehab pr_cont(", capability=0x%x, capturemode=0x%x, timeperframe=%d/%d, extendedmode=%d, readbuffers=%d\n", 5035bc3cb74SMauro Carvalho Chehab c->capability, c->capturemode, 5045bc3cb74SMauro Carvalho Chehab c->timeperframe.numerator, c->timeperframe.denominator, 5055bc3cb74SMauro Carvalho Chehab c->extendedmode, c->readbuffers); 5065bc3cb74SMauro Carvalho Chehab } else if (p->type == V4L2_BUF_TYPE_VIDEO_OUTPUT || 5075bc3cb74SMauro Carvalho Chehab p->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) { 5085bc3cb74SMauro Carvalho Chehab const struct v4l2_outputparm *c = &p->parm.output; 5095bc3cb74SMauro Carvalho Chehab 5108720427cSMauro Carvalho Chehab pr_cont(", capability=0x%x, outputmode=0x%x, timeperframe=%d/%d, extendedmode=%d, writebuffers=%d\n", 5115bc3cb74SMauro Carvalho Chehab c->capability, c->outputmode, 5125bc3cb74SMauro Carvalho Chehab c->timeperframe.numerator, c->timeperframe.denominator, 5135bc3cb74SMauro Carvalho Chehab c->extendedmode, c->writebuffers); 514560dde24SHans Verkuil } else { 515560dde24SHans Verkuil pr_cont("\n"); 5165bc3cb74SMauro Carvalho Chehab } 5175bc3cb74SMauro Carvalho Chehab } 5185bc3cb74SMauro Carvalho Chehab 5195bc3cb74SMauro Carvalho Chehab static void v4l_print_queryctrl(const void *arg, bool write_only) 5205bc3cb74SMauro Carvalho Chehab { 5215bc3cb74SMauro Carvalho Chehab const struct v4l2_queryctrl *p = arg; 5225bc3cb74SMauro Carvalho Chehab 5238720427cSMauro Carvalho Chehab pr_cont("id=0x%x, type=%d, name=%.*s, min/max=%d/%d, step=%d, default=%d, flags=0x%08x\n", 52427d5a87cSHans Verkuil p->id, p->type, (int)sizeof(p->name), p->name, 5255bc3cb74SMauro Carvalho Chehab p->minimum, p->maximum, 5265bc3cb74SMauro Carvalho Chehab p->step, p->default_value, p->flags); 5275bc3cb74SMauro Carvalho Chehab } 5285bc3cb74SMauro Carvalho Chehab 529e6bee368SHans Verkuil static void v4l_print_query_ext_ctrl(const void *arg, bool write_only) 530e6bee368SHans Verkuil { 531e6bee368SHans Verkuil const struct v4l2_query_ext_ctrl *p = arg; 532e6bee368SHans Verkuil 5338720427cSMauro Carvalho Chehab pr_cont("id=0x%x, type=%d, name=%.*s, min/max=%lld/%lld, step=%lld, default=%lld, flags=0x%08x, elem_size=%u, elems=%u, nr_of_dims=%u, dims=%u,%u,%u,%u\n", 534e6bee368SHans Verkuil p->id, p->type, (int)sizeof(p->name), p->name, 535e6bee368SHans Verkuil p->minimum, p->maximum, 536e6bee368SHans Verkuil p->step, p->default_value, p->flags, 537e6bee368SHans Verkuil p->elem_size, p->elems, p->nr_of_dims, 5380176077aSHans Verkuil p->dims[0], p->dims[1], p->dims[2], p->dims[3]); 539e6bee368SHans Verkuil } 540e6bee368SHans Verkuil 5415bc3cb74SMauro Carvalho Chehab static void v4l_print_querymenu(const void *arg, bool write_only) 5425bc3cb74SMauro Carvalho Chehab { 5435bc3cb74SMauro Carvalho Chehab const struct v4l2_querymenu *p = arg; 5445bc3cb74SMauro Carvalho Chehab 5455bc3cb74SMauro Carvalho Chehab pr_cont("id=0x%x, index=%d\n", p->id, p->index); 5465bc3cb74SMauro Carvalho Chehab } 5475bc3cb74SMauro Carvalho Chehab 5485bc3cb74SMauro Carvalho Chehab static void v4l_print_control(const void *arg, bool write_only) 5495bc3cb74SMauro Carvalho Chehab { 5505bc3cb74SMauro Carvalho Chehab const struct v4l2_control *p = arg; 551a69a7a33SEzequiel Garcia const char *name = v4l2_ctrl_get_name(p->id); 5525bc3cb74SMauro Carvalho Chehab 553a69a7a33SEzequiel Garcia if (name) 554a69a7a33SEzequiel Garcia pr_cont("name=%s, ", name); 5555bc3cb74SMauro Carvalho Chehab pr_cont("id=0x%x, value=%d\n", p->id, p->value); 5565bc3cb74SMauro Carvalho Chehab } 5575bc3cb74SMauro Carvalho Chehab 5585bc3cb74SMauro Carvalho Chehab static void v4l_print_ext_controls(const void *arg, bool write_only) 5595bc3cb74SMauro Carvalho Chehab { 5605bc3cb74SMauro Carvalho Chehab const struct v4l2_ext_controls *p = arg; 5615bc3cb74SMauro Carvalho Chehab int i; 5625bc3cb74SMauro Carvalho Chehab 563f23317adSAlexandre Courbot pr_cont("which=0x%x, count=%d, error_idx=%d, request_fd=%d", 564f23317adSAlexandre Courbot p->which, p->count, p->error_idx, p->request_fd); 5655bc3cb74SMauro Carvalho Chehab for (i = 0; i < p->count; i++) { 566a69a7a33SEzequiel Garcia unsigned int id = p->controls[i].id; 567a69a7a33SEzequiel Garcia const char *name = v4l2_ctrl_get_name(id); 568a69a7a33SEzequiel Garcia 569a69a7a33SEzequiel Garcia if (name) 570a69a7a33SEzequiel Garcia pr_cont(", name=%s", name); 571017ab36aSHans Verkuil if (!p->controls[i].size) 572a69a7a33SEzequiel Garcia pr_cont(", id/val=0x%x/0x%x", id, p->controls[i].value); 5735bc3cb74SMauro Carvalho Chehab else 574a69a7a33SEzequiel Garcia pr_cont(", id/size=0x%x/%u", id, p->controls[i].size); 5755bc3cb74SMauro Carvalho Chehab } 5765bc3cb74SMauro Carvalho Chehab pr_cont("\n"); 5775bc3cb74SMauro Carvalho Chehab } 5785bc3cb74SMauro Carvalho Chehab 5795bc3cb74SMauro Carvalho Chehab static void v4l_print_cropcap(const void *arg, bool write_only) 5805bc3cb74SMauro Carvalho Chehab { 5815bc3cb74SMauro Carvalho Chehab const struct v4l2_cropcap *p = arg; 5825bc3cb74SMauro Carvalho Chehab 5838720427cSMauro Carvalho Chehab pr_cont("type=%s, bounds wxh=%dx%d, x,y=%d,%d, defrect wxh=%dx%d, x,y=%d,%d, pixelaspect %d/%d\n", 5845bc3cb74SMauro Carvalho Chehab prt_names(p->type, v4l2_type_names), 5855bc3cb74SMauro Carvalho Chehab p->bounds.width, p->bounds.height, 5865bc3cb74SMauro Carvalho Chehab p->bounds.left, p->bounds.top, 5875bc3cb74SMauro Carvalho Chehab p->defrect.width, p->defrect.height, 5885bc3cb74SMauro Carvalho Chehab p->defrect.left, p->defrect.top, 5895bc3cb74SMauro Carvalho Chehab p->pixelaspect.numerator, p->pixelaspect.denominator); 5905bc3cb74SMauro Carvalho Chehab } 5915bc3cb74SMauro Carvalho Chehab 5925bc3cb74SMauro Carvalho Chehab static void v4l_print_crop(const void *arg, bool write_only) 5935bc3cb74SMauro Carvalho Chehab { 5945bc3cb74SMauro Carvalho Chehab const struct v4l2_crop *p = arg; 5955bc3cb74SMauro Carvalho Chehab 5965bc3cb74SMauro Carvalho Chehab pr_cont("type=%s, wxh=%dx%d, x,y=%d,%d\n", 5975bc3cb74SMauro Carvalho Chehab prt_names(p->type, v4l2_type_names), 5985bc3cb74SMauro Carvalho Chehab p->c.width, p->c.height, 5995bc3cb74SMauro Carvalho Chehab p->c.left, p->c.top); 6005bc3cb74SMauro Carvalho Chehab } 6015bc3cb74SMauro Carvalho Chehab 6025bc3cb74SMauro Carvalho Chehab static void v4l_print_selection(const void *arg, bool write_only) 6035bc3cb74SMauro Carvalho Chehab { 6045bc3cb74SMauro Carvalho Chehab const struct v4l2_selection *p = arg; 6055bc3cb74SMauro Carvalho Chehab 6065bc3cb74SMauro Carvalho Chehab pr_cont("type=%s, target=%d, flags=0x%x, wxh=%dx%d, x,y=%d,%d\n", 6075bc3cb74SMauro Carvalho Chehab prt_names(p->type, v4l2_type_names), 6085bc3cb74SMauro Carvalho Chehab p->target, p->flags, 6095bc3cb74SMauro Carvalho Chehab p->r.width, p->r.height, p->r.left, p->r.top); 6105bc3cb74SMauro Carvalho Chehab } 6115bc3cb74SMauro Carvalho Chehab 6125bc3cb74SMauro Carvalho Chehab static void v4l_print_jpegcompression(const void *arg, bool write_only) 6135bc3cb74SMauro Carvalho Chehab { 6145bc3cb74SMauro Carvalho Chehab const struct v4l2_jpegcompression *p = arg; 6155bc3cb74SMauro Carvalho Chehab 6168720427cSMauro Carvalho Chehab pr_cont("quality=%d, APPn=%d, APP_len=%d, COM_len=%d, jpeg_markers=0x%x\n", 6175bc3cb74SMauro Carvalho Chehab p->quality, p->APPn, p->APP_len, 6185bc3cb74SMauro Carvalho Chehab p->COM_len, p->jpeg_markers); 6195bc3cb74SMauro Carvalho Chehab } 6205bc3cb74SMauro Carvalho Chehab 6215bc3cb74SMauro Carvalho Chehab static void v4l_print_enc_idx(const void *arg, bool write_only) 6225bc3cb74SMauro Carvalho Chehab { 6235bc3cb74SMauro Carvalho Chehab const struct v4l2_enc_idx *p = arg; 6245bc3cb74SMauro Carvalho Chehab 6255bc3cb74SMauro Carvalho Chehab pr_cont("entries=%d, entries_cap=%d\n", 6265bc3cb74SMauro Carvalho Chehab p->entries, p->entries_cap); 6275bc3cb74SMauro Carvalho Chehab } 6285bc3cb74SMauro Carvalho Chehab 6295bc3cb74SMauro Carvalho Chehab static void v4l_print_encoder_cmd(const void *arg, bool write_only) 6305bc3cb74SMauro Carvalho Chehab { 6315bc3cb74SMauro Carvalho Chehab const struct v4l2_encoder_cmd *p = arg; 6325bc3cb74SMauro Carvalho Chehab 6335bc3cb74SMauro Carvalho Chehab pr_cont("cmd=%d, flags=0x%x\n", 6345bc3cb74SMauro Carvalho Chehab p->cmd, p->flags); 6355bc3cb74SMauro Carvalho Chehab } 6365bc3cb74SMauro Carvalho Chehab 6375bc3cb74SMauro Carvalho Chehab static void v4l_print_decoder_cmd(const void *arg, bool write_only) 6385bc3cb74SMauro Carvalho Chehab { 6395bc3cb74SMauro Carvalho Chehab const struct v4l2_decoder_cmd *p = arg; 6405bc3cb74SMauro Carvalho Chehab 6415bc3cb74SMauro Carvalho Chehab pr_cont("cmd=%d, flags=0x%x\n", p->cmd, p->flags); 6425bc3cb74SMauro Carvalho Chehab 6435bc3cb74SMauro Carvalho Chehab if (p->cmd == V4L2_DEC_CMD_START) 6445bc3cb74SMauro Carvalho Chehab pr_info("speed=%d, format=%u\n", 6455bc3cb74SMauro Carvalho Chehab p->start.speed, p->start.format); 6465bc3cb74SMauro Carvalho Chehab else if (p->cmd == V4L2_DEC_CMD_STOP) 6475bc3cb74SMauro Carvalho Chehab pr_info("pts=%llu\n", p->stop.pts); 6485bc3cb74SMauro Carvalho Chehab } 6495bc3cb74SMauro Carvalho Chehab 65096b03d2aSHans Verkuil static void v4l_print_dbg_chip_info(const void *arg, bool write_only) 65179b0c640SHans Verkuil { 65296b03d2aSHans Verkuil const struct v4l2_dbg_chip_info *p = arg; 65379b0c640SHans Verkuil 65479b0c640SHans Verkuil pr_cont("type=%u, ", p->match.type); 6553eef2510SHans Verkuil if (p->match.type == V4L2_CHIP_MATCH_I2C_DRIVER) 65679b0c640SHans Verkuil pr_cont("name=%.*s, ", 65779b0c640SHans Verkuil (int)sizeof(p->match.name), p->match.name); 65879b0c640SHans Verkuil else 65979b0c640SHans Verkuil pr_cont("addr=%u, ", p->match.addr); 66079b0c640SHans Verkuil pr_cont("name=%.*s\n", (int)sizeof(p->name), p->name); 66179b0c640SHans Verkuil } 66279b0c640SHans Verkuil 6635bc3cb74SMauro Carvalho Chehab static void v4l_print_dbg_register(const void *arg, bool write_only) 6645bc3cb74SMauro Carvalho Chehab { 6655bc3cb74SMauro Carvalho Chehab const struct v4l2_dbg_register *p = arg; 6665bc3cb74SMauro Carvalho Chehab 6675bc3cb74SMauro Carvalho Chehab pr_cont("type=%u, ", p->match.type); 6683eef2510SHans Verkuil if (p->match.type == V4L2_CHIP_MATCH_I2C_DRIVER) 66927d5a87cSHans Verkuil pr_cont("name=%.*s, ", 67027d5a87cSHans Verkuil (int)sizeof(p->match.name), p->match.name); 6715bc3cb74SMauro Carvalho Chehab else 6725bc3cb74SMauro Carvalho Chehab pr_cont("addr=%u, ", p->match.addr); 6735bc3cb74SMauro Carvalho Chehab pr_cont("reg=0x%llx, val=0x%llx\n", 6745bc3cb74SMauro Carvalho Chehab p->reg, p->val); 6755bc3cb74SMauro Carvalho Chehab } 6765bc3cb74SMauro Carvalho Chehab 6775bc3cb74SMauro Carvalho Chehab static void v4l_print_dv_timings(const void *arg, bool write_only) 6785bc3cb74SMauro Carvalho Chehab { 6795bc3cb74SMauro Carvalho Chehab const struct v4l2_dv_timings *p = arg; 6805bc3cb74SMauro Carvalho Chehab 6815bc3cb74SMauro Carvalho Chehab switch (p->type) { 6825bc3cb74SMauro Carvalho Chehab case V4L2_DV_BT_656_1120: 6838720427cSMauro Carvalho Chehab pr_cont("type=bt-656/1120, interlaced=%u, pixelclock=%llu, width=%u, height=%u, polarities=0x%x, hfrontporch=%u, hsync=%u, hbackporch=%u, vfrontporch=%u, vsync=%u, vbackporch=%u, il_vfrontporch=%u, il_vsync=%u, il_vbackporch=%u, standards=0x%x, flags=0x%x\n", 6845bc3cb74SMauro Carvalho Chehab p->bt.interlaced, p->bt.pixelclock, 6855bc3cb74SMauro Carvalho Chehab p->bt.width, p->bt.height, 6865bc3cb74SMauro Carvalho Chehab p->bt.polarities, p->bt.hfrontporch, 6875bc3cb74SMauro Carvalho Chehab p->bt.hsync, p->bt.hbackporch, 6885bc3cb74SMauro Carvalho Chehab p->bt.vfrontporch, p->bt.vsync, 6895bc3cb74SMauro Carvalho Chehab p->bt.vbackporch, p->bt.il_vfrontporch, 6905bc3cb74SMauro Carvalho Chehab p->bt.il_vsync, p->bt.il_vbackporch, 6915bc3cb74SMauro Carvalho Chehab p->bt.standards, p->bt.flags); 6925bc3cb74SMauro Carvalho Chehab break; 6935bc3cb74SMauro Carvalho Chehab default: 6945bc3cb74SMauro Carvalho Chehab pr_cont("type=%d\n", p->type); 6955bc3cb74SMauro Carvalho Chehab break; 6965bc3cb74SMauro Carvalho Chehab } 6975bc3cb74SMauro Carvalho Chehab } 6985bc3cb74SMauro Carvalho Chehab 6995bc3cb74SMauro Carvalho Chehab static void v4l_print_enum_dv_timings(const void *arg, bool write_only) 7005bc3cb74SMauro Carvalho Chehab { 7015bc3cb74SMauro Carvalho Chehab const struct v4l2_enum_dv_timings *p = arg; 7025bc3cb74SMauro Carvalho Chehab 7035bc3cb74SMauro Carvalho Chehab pr_cont("index=%u, ", p->index); 7045bc3cb74SMauro Carvalho Chehab v4l_print_dv_timings(&p->timings, write_only); 7055bc3cb74SMauro Carvalho Chehab } 7065bc3cb74SMauro Carvalho Chehab 7075bc3cb74SMauro Carvalho Chehab static void v4l_print_dv_timings_cap(const void *arg, bool write_only) 7085bc3cb74SMauro Carvalho Chehab { 7095bc3cb74SMauro Carvalho Chehab const struct v4l2_dv_timings_cap *p = arg; 7105bc3cb74SMauro Carvalho Chehab 7115bc3cb74SMauro Carvalho Chehab switch (p->type) { 7125bc3cb74SMauro Carvalho Chehab case V4L2_DV_BT_656_1120: 7138720427cSMauro Carvalho Chehab pr_cont("type=bt-656/1120, width=%u-%u, height=%u-%u, pixelclock=%llu-%llu, standards=0x%x, capabilities=0x%x\n", 7145bc3cb74SMauro Carvalho Chehab p->bt.min_width, p->bt.max_width, 7155bc3cb74SMauro Carvalho Chehab p->bt.min_height, p->bt.max_height, 7165bc3cb74SMauro Carvalho Chehab p->bt.min_pixelclock, p->bt.max_pixelclock, 7175bc3cb74SMauro Carvalho Chehab p->bt.standards, p->bt.capabilities); 7185bc3cb74SMauro Carvalho Chehab break; 7195bc3cb74SMauro Carvalho Chehab default: 7205bc3cb74SMauro Carvalho Chehab pr_cont("type=%u\n", p->type); 7215bc3cb74SMauro Carvalho Chehab break; 7225bc3cb74SMauro Carvalho Chehab } 7235bc3cb74SMauro Carvalho Chehab } 7245bc3cb74SMauro Carvalho Chehab 7255bc3cb74SMauro Carvalho Chehab static void v4l_print_frmsizeenum(const void *arg, bool write_only) 7265bc3cb74SMauro Carvalho Chehab { 7275bc3cb74SMauro Carvalho Chehab const struct v4l2_frmsizeenum *p = arg; 7285bc3cb74SMauro Carvalho Chehab 729e927e1e0SSakari Ailus pr_cont("index=%u, pixelformat=%p4cc, type=%u", 730e927e1e0SSakari Ailus p->index, &p->pixel_format, p->type); 7315bc3cb74SMauro Carvalho Chehab switch (p->type) { 7325bc3cb74SMauro Carvalho Chehab case V4L2_FRMSIZE_TYPE_DISCRETE: 733560dde24SHans Verkuil pr_cont(", wxh=%ux%u\n", 7345bc3cb74SMauro Carvalho Chehab p->discrete.width, p->discrete.height); 7355bc3cb74SMauro Carvalho Chehab break; 7365bc3cb74SMauro Carvalho Chehab case V4L2_FRMSIZE_TYPE_STEPWISE: 737560dde24SHans Verkuil pr_cont(", min=%ux%u, max=%ux%u, step=%ux%u\n", 7382489477eSRicardo Ribalda p->stepwise.min_width, 7392489477eSRicardo Ribalda p->stepwise.min_height, 7402489477eSRicardo Ribalda p->stepwise.max_width, 7412489477eSRicardo Ribalda p->stepwise.max_height, 7422489477eSRicardo Ribalda p->stepwise.step_width, 7432489477eSRicardo Ribalda p->stepwise.step_height); 7445bc3cb74SMauro Carvalho Chehab break; 7455bc3cb74SMauro Carvalho Chehab case V4L2_FRMSIZE_TYPE_CONTINUOUS: 7465bc3cb74SMauro Carvalho Chehab default: 7475bc3cb74SMauro Carvalho Chehab pr_cont("\n"); 7485bc3cb74SMauro Carvalho Chehab break; 7495bc3cb74SMauro Carvalho Chehab } 7505bc3cb74SMauro Carvalho Chehab } 7515bc3cb74SMauro Carvalho Chehab 7525bc3cb74SMauro Carvalho Chehab static void v4l_print_frmivalenum(const void *arg, bool write_only) 7535bc3cb74SMauro Carvalho Chehab { 7545bc3cb74SMauro Carvalho Chehab const struct v4l2_frmivalenum *p = arg; 7555bc3cb74SMauro Carvalho Chehab 756e927e1e0SSakari Ailus pr_cont("index=%u, pixelformat=%p4cc, wxh=%ux%u, type=%u", 757e927e1e0SSakari Ailus p->index, &p->pixel_format, p->width, p->height, p->type); 7585bc3cb74SMauro Carvalho Chehab switch (p->type) { 7595bc3cb74SMauro Carvalho Chehab case V4L2_FRMIVAL_TYPE_DISCRETE: 760560dde24SHans Verkuil pr_cont(", fps=%d/%d\n", 7615bc3cb74SMauro Carvalho Chehab p->discrete.numerator, 7625bc3cb74SMauro Carvalho Chehab p->discrete.denominator); 7635bc3cb74SMauro Carvalho Chehab break; 7645bc3cb74SMauro Carvalho Chehab case V4L2_FRMIVAL_TYPE_STEPWISE: 765560dde24SHans Verkuil pr_cont(", min=%d/%d, max=%d/%d, step=%d/%d\n", 7665bc3cb74SMauro Carvalho Chehab p->stepwise.min.numerator, 7675bc3cb74SMauro Carvalho Chehab p->stepwise.min.denominator, 7685bc3cb74SMauro Carvalho Chehab p->stepwise.max.numerator, 7695bc3cb74SMauro Carvalho Chehab p->stepwise.max.denominator, 7705bc3cb74SMauro Carvalho Chehab p->stepwise.step.numerator, 7715bc3cb74SMauro Carvalho Chehab p->stepwise.step.denominator); 7725bc3cb74SMauro Carvalho Chehab break; 7735bc3cb74SMauro Carvalho Chehab case V4L2_FRMIVAL_TYPE_CONTINUOUS: 7745bc3cb74SMauro Carvalho Chehab default: 7755bc3cb74SMauro Carvalho Chehab pr_cont("\n"); 7765bc3cb74SMauro Carvalho Chehab break; 7775bc3cb74SMauro Carvalho Chehab } 7785bc3cb74SMauro Carvalho Chehab } 7795bc3cb74SMauro Carvalho Chehab 7805bc3cb74SMauro Carvalho Chehab static void v4l_print_event(const void *arg, bool write_only) 7815bc3cb74SMauro Carvalho Chehab { 7825bc3cb74SMauro Carvalho Chehab const struct v4l2_event *p = arg; 7835bc3cb74SMauro Carvalho Chehab const struct v4l2_event_ctrl *c; 7845bc3cb74SMauro Carvalho Chehab 7851a6c0b36SArnd Bergmann pr_cont("type=0x%x, pending=%u, sequence=%u, id=%u, timestamp=%llu.%9.9llu\n", 7865bc3cb74SMauro Carvalho Chehab p->type, p->pending, p->sequence, p->id, 7875bc3cb74SMauro Carvalho Chehab p->timestamp.tv_sec, p->timestamp.tv_nsec); 7885bc3cb74SMauro Carvalho Chehab switch (p->type) { 7895bc3cb74SMauro Carvalho Chehab case V4L2_EVENT_VSYNC: 7905bc3cb74SMauro Carvalho Chehab printk(KERN_DEBUG "field=%s\n", 7915bc3cb74SMauro Carvalho Chehab prt_names(p->u.vsync.field, v4l2_field_names)); 7925bc3cb74SMauro Carvalho Chehab break; 7935bc3cb74SMauro Carvalho Chehab case V4L2_EVENT_CTRL: 7945bc3cb74SMauro Carvalho Chehab c = &p->u.ctrl; 7955bc3cb74SMauro Carvalho Chehab printk(KERN_DEBUG "changes=0x%x, type=%u, ", 7965bc3cb74SMauro Carvalho Chehab c->changes, c->type); 7975bc3cb74SMauro Carvalho Chehab if (c->type == V4L2_CTRL_TYPE_INTEGER64) 7985bc3cb74SMauro Carvalho Chehab pr_cont("value64=%lld, ", c->value64); 7995bc3cb74SMauro Carvalho Chehab else 8005bc3cb74SMauro Carvalho Chehab pr_cont("value=%d, ", c->value); 8018720427cSMauro Carvalho Chehab pr_cont("flags=0x%x, minimum=%d, maximum=%d, step=%d, default_value=%d\n", 8025bc3cb74SMauro Carvalho Chehab c->flags, c->minimum, c->maximum, 8035bc3cb74SMauro Carvalho Chehab c->step, c->default_value); 8045bc3cb74SMauro Carvalho Chehab break; 8055bc3cb74SMauro Carvalho Chehab case V4L2_EVENT_FRAME_SYNC: 8065bc3cb74SMauro Carvalho Chehab pr_cont("frame_sequence=%u\n", 8075bc3cb74SMauro Carvalho Chehab p->u.frame_sync.frame_sequence); 8085bc3cb74SMauro Carvalho Chehab break; 8095bc3cb74SMauro Carvalho Chehab } 8105bc3cb74SMauro Carvalho Chehab } 8115bc3cb74SMauro Carvalho Chehab 8125bc3cb74SMauro Carvalho Chehab static void v4l_print_event_subscription(const void *arg, bool write_only) 8135bc3cb74SMauro Carvalho Chehab { 8145bc3cb74SMauro Carvalho Chehab const struct v4l2_event_subscription *p = arg; 8155bc3cb74SMauro Carvalho Chehab 8165bc3cb74SMauro Carvalho Chehab pr_cont("type=0x%x, id=0x%x, flags=0x%x\n", 8175bc3cb74SMauro Carvalho Chehab p->type, p->id, p->flags); 8185bc3cb74SMauro Carvalho Chehab } 8195bc3cb74SMauro Carvalho Chehab 8205bc3cb74SMauro Carvalho Chehab static void v4l_print_sliced_vbi_cap(const void *arg, bool write_only) 8215bc3cb74SMauro Carvalho Chehab { 8225bc3cb74SMauro Carvalho Chehab const struct v4l2_sliced_vbi_cap *p = arg; 8235bc3cb74SMauro Carvalho Chehab int i; 8245bc3cb74SMauro Carvalho Chehab 8255bc3cb74SMauro Carvalho Chehab pr_cont("type=%s, service_set=0x%08x\n", 8265bc3cb74SMauro Carvalho Chehab prt_names(p->type, v4l2_type_names), p->service_set); 8275bc3cb74SMauro Carvalho Chehab for (i = 0; i < 24; i++) 8285bc3cb74SMauro Carvalho Chehab printk(KERN_DEBUG "line[%02u]=0x%04x, 0x%04x\n", i, 8295bc3cb74SMauro Carvalho Chehab p->service_lines[0][i], 8305bc3cb74SMauro Carvalho Chehab p->service_lines[1][i]); 8315bc3cb74SMauro Carvalho Chehab } 8325bc3cb74SMauro Carvalho Chehab 8335bc3cb74SMauro Carvalho Chehab static void v4l_print_freq_band(const void *arg, bool write_only) 8345bc3cb74SMauro Carvalho Chehab { 8355bc3cb74SMauro Carvalho Chehab const struct v4l2_frequency_band *p = arg; 8365bc3cb74SMauro Carvalho Chehab 8378720427cSMauro Carvalho Chehab pr_cont("tuner=%u, type=%u, index=%u, capability=0x%x, rangelow=%u, rangehigh=%u, modulation=0x%x\n", 8385bc3cb74SMauro Carvalho Chehab p->tuner, p->type, p->index, 8395bc3cb74SMauro Carvalho Chehab p->capability, p->rangelow, 8405bc3cb74SMauro Carvalho Chehab p->rangehigh, p->modulation); 8415bc3cb74SMauro Carvalho Chehab } 8425bc3cb74SMauro Carvalho Chehab 843dd519bb3SHans Verkuil static void v4l_print_edid(const void *arg, bool write_only) 844dd519bb3SHans Verkuil { 845dd519bb3SHans Verkuil const struct v4l2_edid *p = arg; 846dd519bb3SHans Verkuil 847dd519bb3SHans Verkuil pr_cont("pad=%u, start_block=%u, blocks=%u\n", 848dd519bb3SHans Verkuil p->pad, p->start_block, p->blocks); 849dd519bb3SHans Verkuil } 850dd519bb3SHans Verkuil 8515bc3cb74SMauro Carvalho Chehab static void v4l_print_u32(const void *arg, bool write_only) 8525bc3cb74SMauro Carvalho Chehab { 8535bc3cb74SMauro Carvalho Chehab pr_cont("value=%u\n", *(const u32 *)arg); 8545bc3cb74SMauro Carvalho Chehab } 8555bc3cb74SMauro Carvalho Chehab 8565bc3cb74SMauro Carvalho Chehab static void v4l_print_newline(const void *arg, bool write_only) 8575bc3cb74SMauro Carvalho Chehab { 8585bc3cb74SMauro Carvalho Chehab pr_cont("\n"); 8595bc3cb74SMauro Carvalho Chehab } 8605bc3cb74SMauro Carvalho Chehab 8615bc3cb74SMauro Carvalho Chehab static void v4l_print_default(const void *arg, bool write_only) 8625bc3cb74SMauro Carvalho Chehab { 8635bc3cb74SMauro Carvalho Chehab pr_cont("driver-specific ioctl\n"); 8645bc3cb74SMauro Carvalho Chehab } 8655bc3cb74SMauro Carvalho Chehab 866861f92cbSRicardo Ribalda static bool check_ext_ctrls(struct v4l2_ext_controls *c, unsigned long ioctl) 8675bc3cb74SMauro Carvalho Chehab { 8685bc3cb74SMauro Carvalho Chehab __u32 i; 8695bc3cb74SMauro Carvalho Chehab 8705bc3cb74SMauro Carvalho Chehab /* zero the reserved fields */ 871f23317adSAlexandre Courbot c->reserved[0] = 0; 8725bc3cb74SMauro Carvalho Chehab for (i = 0; i < c->count; i++) 8735bc3cb74SMauro Carvalho Chehab c->controls[i].reserved2[0] = 0; 8745bc3cb74SMauro Carvalho Chehab 875861f92cbSRicardo Ribalda switch (c->which) { 876861f92cbSRicardo Ribalda case V4L2_CID_PRIVATE_BASE: 877861f92cbSRicardo Ribalda /* 878861f92cbSRicardo Ribalda * V4L2_CID_PRIVATE_BASE cannot be used as control class 879861f92cbSRicardo Ribalda * when using extended controls. 880861f92cbSRicardo Ribalda * Only when passed in through VIDIOC_G_CTRL and VIDIOC_S_CTRL 881861f92cbSRicardo Ribalda * is it allowed for backwards compatibility. 8825bc3cb74SMauro Carvalho Chehab */ 883861f92cbSRicardo Ribalda if (ioctl == VIDIOC_G_CTRL || ioctl == VIDIOC_S_CTRL) 884861f92cbSRicardo Ribalda return false; 885861f92cbSRicardo Ribalda break; 886861f92cbSRicardo Ribalda case V4L2_CTRL_WHICH_DEF_VAL: 887861f92cbSRicardo Ribalda /* Default value cannot be changed */ 888861f92cbSRicardo Ribalda if (ioctl == VIDIOC_S_EXT_CTRLS || 889861f92cbSRicardo Ribalda ioctl == VIDIOC_TRY_EXT_CTRLS) { 890861f92cbSRicardo Ribalda c->error_idx = c->count; 891861f92cbSRicardo Ribalda return false; 892861f92cbSRicardo Ribalda } 893861f92cbSRicardo Ribalda return true; 894861f92cbSRicardo Ribalda case V4L2_CTRL_WHICH_CUR_VAL: 895861f92cbSRicardo Ribalda return true; 896861f92cbSRicardo Ribalda case V4L2_CTRL_WHICH_REQUEST_VAL: 897861f92cbSRicardo Ribalda c->error_idx = c->count; 898861f92cbSRicardo Ribalda return false; 899861f92cbSRicardo Ribalda } 900861f92cbSRicardo Ribalda 9015bc3cb74SMauro Carvalho Chehab /* Check that all controls are from the same control class. */ 9025bc3cb74SMauro Carvalho Chehab for (i = 0; i < c->count; i++) { 9030f8017beSRicardo Ribalda if (V4L2_CTRL_ID2WHICH(c->controls[i].id) != c->which) { 904861f92cbSRicardo Ribalda c->error_idx = ioctl == VIDIOC_TRY_EXT_CTRLS ? i : 905861f92cbSRicardo Ribalda c->count; 906861f92cbSRicardo Ribalda return false; 9075bc3cb74SMauro Carvalho Chehab } 9085bc3cb74SMauro Carvalho Chehab } 909861f92cbSRicardo Ribalda return true; 9105bc3cb74SMauro Carvalho Chehab } 9115bc3cb74SMauro Carvalho Chehab 9124b20259fSHans Verkuil static int check_fmt(struct file *file, enum v4l2_buf_type type) 9135bc3cb74SMauro Carvalho Chehab { 91496f49c1aSVandana BN const u32 vid_caps = V4L2_CAP_VIDEO_CAPTURE | 91596f49c1aSVandana BN V4L2_CAP_VIDEO_CAPTURE_MPLANE | 91696f49c1aSVandana BN V4L2_CAP_VIDEO_OUTPUT | 91796f49c1aSVandana BN V4L2_CAP_VIDEO_OUTPUT_MPLANE | 91896f49c1aSVandana BN V4L2_CAP_VIDEO_M2M | V4L2_CAP_VIDEO_M2M_MPLANE; 91996f49c1aSVandana BN const u32 meta_caps = V4L2_CAP_META_CAPTURE | 92096f49c1aSVandana BN V4L2_CAP_META_OUTPUT; 9214b20259fSHans Verkuil struct video_device *vfd = video_devdata(file); 9224b20259fSHans Verkuil const struct v4l2_ioctl_ops *ops = vfd->ioctl_ops; 923238e4a5bSHans Verkuil bool is_vid = vfd->vfl_type == VFL_TYPE_VIDEO && 92496f49c1aSVandana BN (vfd->device_caps & vid_caps); 9254b20259fSHans Verkuil bool is_vbi = vfd->vfl_type == VFL_TYPE_VBI; 926582c52cbSAntti Palosaari bool is_sdr = vfd->vfl_type == VFL_TYPE_SDR; 927b2fe22d0SNick Dyer bool is_tch = vfd->vfl_type == VFL_TYPE_TOUCH; 928238e4a5bSHans Verkuil bool is_meta = vfd->vfl_type == VFL_TYPE_VIDEO && 92996f49c1aSVandana BN (vfd->device_caps & meta_caps); 9304b20259fSHans Verkuil bool is_rx = vfd->vfl_dir != VFL_DIR_TX; 9314b20259fSHans Verkuil bool is_tx = vfd->vfl_dir != VFL_DIR_RX; 9324b20259fSHans Verkuil 9335bc3cb74SMauro Carvalho Chehab if (ops == NULL) 9345bc3cb74SMauro Carvalho Chehab return -EINVAL; 9355bc3cb74SMauro Carvalho Chehab 9365bc3cb74SMauro Carvalho Chehab switch (type) { 9375bc3cb74SMauro Carvalho Chehab case V4L2_BUF_TYPE_VIDEO_CAPTURE: 938b2fe22d0SNick Dyer if ((is_vid || is_tch) && is_rx && 9394b20259fSHans Verkuil (ops->vidioc_g_fmt_vid_cap || ops->vidioc_g_fmt_vid_cap_mplane)) 9405bc3cb74SMauro Carvalho Chehab return 0; 9415bc3cb74SMauro Carvalho Chehab break; 9425bc3cb74SMauro Carvalho Chehab case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE: 943095c21d3SHans Verkuil if ((is_vid || is_tch) && is_rx && ops->vidioc_g_fmt_vid_cap_mplane) 9445bc3cb74SMauro Carvalho Chehab return 0; 9455bc3cb74SMauro Carvalho Chehab break; 9465bc3cb74SMauro Carvalho Chehab case V4L2_BUF_TYPE_VIDEO_OVERLAY: 9474b20259fSHans Verkuil if (is_vid && is_rx && ops->vidioc_g_fmt_vid_overlay) 9485bc3cb74SMauro Carvalho Chehab return 0; 9495bc3cb74SMauro Carvalho Chehab break; 9505bc3cb74SMauro Carvalho Chehab case V4L2_BUF_TYPE_VIDEO_OUTPUT: 9514b20259fSHans Verkuil if (is_vid && is_tx && 9524b20259fSHans Verkuil (ops->vidioc_g_fmt_vid_out || ops->vidioc_g_fmt_vid_out_mplane)) 9535bc3cb74SMauro Carvalho Chehab return 0; 9545bc3cb74SMauro Carvalho Chehab break; 9555bc3cb74SMauro Carvalho Chehab case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE: 9564b20259fSHans Verkuil if (is_vid && is_tx && ops->vidioc_g_fmt_vid_out_mplane) 9575bc3cb74SMauro Carvalho Chehab return 0; 9585bc3cb74SMauro Carvalho Chehab break; 9595bc3cb74SMauro Carvalho Chehab case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY: 9604b20259fSHans Verkuil if (is_vid && is_tx && ops->vidioc_g_fmt_vid_out_overlay) 9615bc3cb74SMauro Carvalho Chehab return 0; 9625bc3cb74SMauro Carvalho Chehab break; 9635bc3cb74SMauro Carvalho Chehab case V4L2_BUF_TYPE_VBI_CAPTURE: 9644b20259fSHans Verkuil if (is_vbi && is_rx && ops->vidioc_g_fmt_vbi_cap) 9655bc3cb74SMauro Carvalho Chehab return 0; 9665bc3cb74SMauro Carvalho Chehab break; 9675bc3cb74SMauro Carvalho Chehab case V4L2_BUF_TYPE_VBI_OUTPUT: 9684b20259fSHans Verkuil if (is_vbi && is_tx && ops->vidioc_g_fmt_vbi_out) 9695bc3cb74SMauro Carvalho Chehab return 0; 9705bc3cb74SMauro Carvalho Chehab break; 9715bc3cb74SMauro Carvalho Chehab case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE: 9724b20259fSHans Verkuil if (is_vbi && is_rx && ops->vidioc_g_fmt_sliced_vbi_cap) 9735bc3cb74SMauro Carvalho Chehab return 0; 9745bc3cb74SMauro Carvalho Chehab break; 9755bc3cb74SMauro Carvalho Chehab case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT: 9764b20259fSHans Verkuil if (is_vbi && is_tx && ops->vidioc_g_fmt_sliced_vbi_out) 9775bc3cb74SMauro Carvalho Chehab return 0; 9785bc3cb74SMauro Carvalho Chehab break; 979582c52cbSAntti Palosaari case V4L2_BUF_TYPE_SDR_CAPTURE: 980582c52cbSAntti Palosaari if (is_sdr && is_rx && ops->vidioc_g_fmt_sdr_cap) 981582c52cbSAntti Palosaari return 0; 982582c52cbSAntti Palosaari break; 9839effc72fSAntti Palosaari case V4L2_BUF_TYPE_SDR_OUTPUT: 9849effc72fSAntti Palosaari if (is_sdr && is_tx && ops->vidioc_g_fmt_sdr_out) 9859effc72fSAntti Palosaari return 0; 9869effc72fSAntti Palosaari break; 987fb9ffa6aSLaurent Pinchart case V4L2_BUF_TYPE_META_CAPTURE: 98896f49c1aSVandana BN if (is_meta && is_rx && ops->vidioc_g_fmt_meta_cap) 989fb9ffa6aSLaurent Pinchart return 0; 990fb9ffa6aSLaurent Pinchart break; 99172148d1aSSakari Ailus case V4L2_BUF_TYPE_META_OUTPUT: 99296f49c1aSVandana BN if (is_meta && is_tx && ops->vidioc_g_fmt_meta_out) 99372148d1aSSakari Ailus return 0; 99472148d1aSSakari Ailus break; 995633c98e5SHans Verkuil default: 9965bc3cb74SMauro Carvalho Chehab break; 9975bc3cb74SMauro Carvalho Chehab } 9985bc3cb74SMauro Carvalho Chehab return -EINVAL; 9995bc3cb74SMauro Carvalho Chehab } 10005bc3cb74SMauro Carvalho Chehab 100148e93b0cSLaurent Pinchart static void v4l_sanitize_colorspace(u32 pixelformat, u32 *colorspace, 100248e93b0cSLaurent Pinchart u32 *encoding, u32 *quantization, 100348e93b0cSLaurent Pinchart u32 *xfer_func) 100448e93b0cSLaurent Pinchart { 100548e93b0cSLaurent Pinchart bool is_hsv = pixelformat == V4L2_PIX_FMT_HSV24 || 100648e93b0cSLaurent Pinchart pixelformat == V4L2_PIX_FMT_HSV32; 100748e93b0cSLaurent Pinchart 100848e93b0cSLaurent Pinchart if (!v4l2_is_colorspace_valid(*colorspace)) { 100948e93b0cSLaurent Pinchart *colorspace = V4L2_COLORSPACE_DEFAULT; 101048e93b0cSLaurent Pinchart *encoding = V4L2_YCBCR_ENC_DEFAULT; 101148e93b0cSLaurent Pinchart *quantization = V4L2_QUANTIZATION_DEFAULT; 101248e93b0cSLaurent Pinchart *xfer_func = V4L2_XFER_FUNC_DEFAULT; 101348e93b0cSLaurent Pinchart } 101448e93b0cSLaurent Pinchart 101548e93b0cSLaurent Pinchart if ((!is_hsv && !v4l2_is_ycbcr_enc_valid(*encoding)) || 101648e93b0cSLaurent Pinchart (is_hsv && !v4l2_is_hsv_enc_valid(*encoding))) 101748e93b0cSLaurent Pinchart *encoding = V4L2_YCBCR_ENC_DEFAULT; 101848e93b0cSLaurent Pinchart 101948e93b0cSLaurent Pinchart if (!v4l2_is_quant_valid(*quantization)) 102048e93b0cSLaurent Pinchart *quantization = V4L2_QUANTIZATION_DEFAULT; 102148e93b0cSLaurent Pinchart 102248e93b0cSLaurent Pinchart if (!v4l2_is_xfer_func_valid(*xfer_func)) 102348e93b0cSLaurent Pinchart *xfer_func = V4L2_XFER_FUNC_DEFAULT; 102448e93b0cSLaurent Pinchart } 102548e93b0cSLaurent Pinchart 1026d52e2381SLaurent Pinchart static void v4l_sanitize_format(struct v4l2_format *fmt) 1027d52e2381SLaurent Pinchart { 1028d52e2381SLaurent Pinchart unsigned int offset; 1029d52e2381SLaurent Pinchart 103014c8e80eSEzequiel Garcia /* Make sure num_planes is not bogus */ 103114c8e80eSEzequiel Garcia if (fmt->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE || 103214c8e80eSEzequiel Garcia fmt->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) 103314c8e80eSEzequiel Garcia fmt->fmt.pix_mp.num_planes = min_t(u32, fmt->fmt.pix_mp.num_planes, 103414c8e80eSEzequiel Garcia VIDEO_MAX_PLANES); 103514c8e80eSEzequiel Garcia 1036d52e2381SLaurent Pinchart /* 1037d52e2381SLaurent Pinchart * The v4l2_pix_format structure has been extended with fields that were 1038d52e2381SLaurent Pinchart * not previously required to be set to zero by applications. The priv 1039fd3ed970SSlark Xiao * field, when set to a magic value, indicates that the extended fields 1040d52e2381SLaurent Pinchart * are valid. Otherwise they will contain undefined values. To simplify 1041d52e2381SLaurent Pinchart * the API towards drivers zero the extended fields and set the priv 1042d52e2381SLaurent Pinchart * field to the magic value when the extended pixel format structure 1043d52e2381SLaurent Pinchart * isn't used by applications. 1044d52e2381SLaurent Pinchart */ 104548e93b0cSLaurent Pinchart if (fmt->type == V4L2_BUF_TYPE_VIDEO_CAPTURE || 104648e93b0cSLaurent Pinchart fmt->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) { 104748e93b0cSLaurent Pinchart if (fmt->fmt.pix.priv != V4L2_PIX_FMT_PRIV_MAGIC) { 1048d52e2381SLaurent Pinchart fmt->fmt.pix.priv = V4L2_PIX_FMT_PRIV_MAGIC; 1049d52e2381SLaurent Pinchart 1050d52e2381SLaurent Pinchart offset = offsetof(struct v4l2_pix_format, priv) 1051d52e2381SLaurent Pinchart + sizeof(fmt->fmt.pix.priv); 1052d52e2381SLaurent Pinchart memset(((void *)&fmt->fmt.pix) + offset, 0, 1053d52e2381SLaurent Pinchart sizeof(fmt->fmt.pix) - offset); 1054d52e2381SLaurent Pinchart } 105548e93b0cSLaurent Pinchart } 105648e93b0cSLaurent Pinchart 105748e93b0cSLaurent Pinchart /* Replace invalid colorspace values with defaults. */ 105848e93b0cSLaurent Pinchart if (fmt->type == V4L2_BUF_TYPE_VIDEO_CAPTURE || 105948e93b0cSLaurent Pinchart fmt->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) { 106048e93b0cSLaurent Pinchart v4l_sanitize_colorspace(fmt->fmt.pix.pixelformat, 106148e93b0cSLaurent Pinchart &fmt->fmt.pix.colorspace, 106248e93b0cSLaurent Pinchart &fmt->fmt.pix.ycbcr_enc, 106348e93b0cSLaurent Pinchart &fmt->fmt.pix.quantization, 106448e93b0cSLaurent Pinchart &fmt->fmt.pix.xfer_func); 106548e93b0cSLaurent Pinchart } else if (fmt->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE || 106648e93b0cSLaurent Pinchart fmt->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) { 106748e93b0cSLaurent Pinchart u32 ycbcr_enc = fmt->fmt.pix_mp.ycbcr_enc; 106848e93b0cSLaurent Pinchart u32 quantization = fmt->fmt.pix_mp.quantization; 106948e93b0cSLaurent Pinchart u32 xfer_func = fmt->fmt.pix_mp.xfer_func; 107048e93b0cSLaurent Pinchart 107148e93b0cSLaurent Pinchart v4l_sanitize_colorspace(fmt->fmt.pix_mp.pixelformat, 107248e93b0cSLaurent Pinchart &fmt->fmt.pix_mp.colorspace, &ycbcr_enc, 107348e93b0cSLaurent Pinchart &quantization, &xfer_func); 107448e93b0cSLaurent Pinchart 107548e93b0cSLaurent Pinchart fmt->fmt.pix_mp.ycbcr_enc = ycbcr_enc; 107648e93b0cSLaurent Pinchart fmt->fmt.pix_mp.quantization = quantization; 107748e93b0cSLaurent Pinchart fmt->fmt.pix_mp.xfer_func = xfer_func; 107848e93b0cSLaurent Pinchart } 107948e93b0cSLaurent Pinchart } 1080d52e2381SLaurent Pinchart 10815bc3cb74SMauro Carvalho Chehab static int v4l_querycap(const struct v4l2_ioctl_ops *ops, 10825bc3cb74SMauro Carvalho Chehab struct file *file, void *fh, void *arg) 10835bc3cb74SMauro Carvalho Chehab { 10845bc3cb74SMauro Carvalho Chehab struct v4l2_capability *cap = (struct v4l2_capability *)arg; 10857bbe7813SHans Verkuil struct video_device *vfd = video_devdata(file); 1086d52e2381SLaurent Pinchart int ret; 10875bc3cb74SMauro Carvalho Chehab 10885bc3cb74SMauro Carvalho Chehab cap->version = LINUX_VERSION_CODE; 10897bbe7813SHans Verkuil cap->device_caps = vfd->device_caps; 10907bbe7813SHans Verkuil cap->capabilities = vfd->device_caps | V4L2_CAP_DEVICE_CAPS; 1091d52e2381SLaurent Pinchart 1092f2d8b691SSakari Ailus media_set_bus_info(cap->bus_info, sizeof(cap->bus_info), 1093f2d8b691SSakari Ailus vfd->dev_parent); 1094f2d8b691SSakari Ailus 1095d52e2381SLaurent Pinchart ret = ops->vidioc_querycap(file, fh, cap); 1096d52e2381SLaurent Pinchart 1097454a4e72SHans Verkuil /* 10983c135050SHans Verkuil * Drivers must not change device_caps, so check for this and 10993c135050SHans Verkuil * warn if this happened. 1100454a4e72SHans Verkuil */ 11013c135050SHans Verkuil WARN_ON(cap->device_caps != vfd->device_caps); 11023c135050SHans Verkuil /* 11033c135050SHans Verkuil * Check that capabilities is a superset of 11043c135050SHans Verkuil * vfd->device_caps | V4L2_CAP_DEVICE_CAPS 11053c135050SHans Verkuil */ 11063c135050SHans Verkuil WARN_ON((cap->capabilities & 11073c135050SHans Verkuil (vfd->device_caps | V4L2_CAP_DEVICE_CAPS)) != 11083c135050SHans Verkuil (vfd->device_caps | V4L2_CAP_DEVICE_CAPS)); 11093c135050SHans Verkuil cap->capabilities |= V4L2_CAP_EXT_PIX_FORMAT; 1110796a2bd2SHans Verkuil cap->device_caps |= V4L2_CAP_EXT_PIX_FORMAT; 1111d52e2381SLaurent Pinchart 1112d52e2381SLaurent Pinchart return ret; 11135bc3cb74SMauro Carvalho Chehab } 11145bc3cb74SMauro Carvalho Chehab 1115f645e625SNiklas Söderlund static int v4l_g_input(const struct v4l2_ioctl_ops *ops, 1116f645e625SNiklas Söderlund struct file *file, void *fh, void *arg) 1117f645e625SNiklas Söderlund { 1118f645e625SNiklas Söderlund struct video_device *vfd = video_devdata(file); 1119f645e625SNiklas Söderlund 1120f645e625SNiklas Söderlund if (vfd->device_caps & V4L2_CAP_IO_MC) { 1121f645e625SNiklas Söderlund *(int *)arg = 0; 1122f645e625SNiklas Söderlund return 0; 1123f645e625SNiklas Söderlund } 1124f645e625SNiklas Söderlund 1125f645e625SNiklas Söderlund return ops->vidioc_g_input(file, fh, arg); 1126f645e625SNiklas Söderlund } 1127f645e625SNiklas Söderlund 1128f645e625SNiklas Söderlund static int v4l_g_output(const struct v4l2_ioctl_ops *ops, 1129f645e625SNiklas Söderlund struct file *file, void *fh, void *arg) 1130f645e625SNiklas Söderlund { 1131f645e625SNiklas Söderlund struct video_device *vfd = video_devdata(file); 1132f645e625SNiklas Söderlund 1133f645e625SNiklas Söderlund if (vfd->device_caps & V4L2_CAP_IO_MC) { 1134f645e625SNiklas Söderlund *(int *)arg = 0; 1135f645e625SNiklas Söderlund return 0; 1136f645e625SNiklas Söderlund } 1137f645e625SNiklas Söderlund 1138f645e625SNiklas Söderlund return ops->vidioc_g_output(file, fh, arg); 1139f645e625SNiklas Söderlund } 1140f645e625SNiklas Söderlund 11415bc3cb74SMauro Carvalho Chehab static int v4l_s_input(const struct v4l2_ioctl_ops *ops, 11425bc3cb74SMauro Carvalho Chehab struct file *file, void *fh, void *arg) 11435bc3cb74SMauro Carvalho Chehab { 114477fa4e07SShuah Khan struct video_device *vfd = video_devdata(file); 114577fa4e07SShuah Khan int ret; 114677fa4e07SShuah Khan 114777fa4e07SShuah Khan ret = v4l_enable_media_source(vfd); 114877fa4e07SShuah Khan if (ret) 114977fa4e07SShuah Khan return ret; 1150f645e625SNiklas Söderlund 1151f645e625SNiklas Söderlund if (vfd->device_caps & V4L2_CAP_IO_MC) 1152f645e625SNiklas Söderlund return *(int *)arg ? -EINVAL : 0; 1153f645e625SNiklas Söderlund 11545bc3cb74SMauro Carvalho Chehab return ops->vidioc_s_input(file, fh, *(unsigned int *)arg); 11555bc3cb74SMauro Carvalho Chehab } 11565bc3cb74SMauro Carvalho Chehab 11575bc3cb74SMauro Carvalho Chehab static int v4l_s_output(const struct v4l2_ioctl_ops *ops, 11585bc3cb74SMauro Carvalho Chehab struct file *file, void *fh, void *arg) 11595bc3cb74SMauro Carvalho Chehab { 1160f645e625SNiklas Söderlund struct video_device *vfd = video_devdata(file); 1161f645e625SNiklas Söderlund 1162f645e625SNiklas Söderlund if (vfd->device_caps & V4L2_CAP_IO_MC) 1163f645e625SNiklas Söderlund return *(int *)arg ? -EINVAL : 0; 1164f645e625SNiklas Söderlund 11655bc3cb74SMauro Carvalho Chehab return ops->vidioc_s_output(file, fh, *(unsigned int *)arg); 11665bc3cb74SMauro Carvalho Chehab } 11675bc3cb74SMauro Carvalho Chehab 11685bc3cb74SMauro Carvalho Chehab static int v4l_g_priority(const struct v4l2_ioctl_ops *ops, 11695bc3cb74SMauro Carvalho Chehab struct file *file, void *fh, void *arg) 11705bc3cb74SMauro Carvalho Chehab { 11715bc3cb74SMauro Carvalho Chehab struct video_device *vfd; 11725bc3cb74SMauro Carvalho Chehab u32 *p = arg; 11735bc3cb74SMauro Carvalho Chehab 11745bc3cb74SMauro Carvalho Chehab vfd = video_devdata(file); 117559b702eaSLaurent Pinchart *p = v4l2_prio_max(vfd->prio); 11765bc3cb74SMauro Carvalho Chehab return 0; 11775bc3cb74SMauro Carvalho Chehab } 11785bc3cb74SMauro Carvalho Chehab 11795bc3cb74SMauro Carvalho Chehab static int v4l_s_priority(const struct v4l2_ioctl_ops *ops, 11805bc3cb74SMauro Carvalho Chehab struct file *file, void *fh, void *arg) 11815bc3cb74SMauro Carvalho Chehab { 11825bc3cb74SMauro Carvalho Chehab struct video_device *vfd; 11835bc3cb74SMauro Carvalho Chehab struct v4l2_fh *vfh; 11845bc3cb74SMauro Carvalho Chehab u32 *p = arg; 11855bc3cb74SMauro Carvalho Chehab 11865bc3cb74SMauro Carvalho Chehab vfd = video_devdata(file); 11872438e78aSHans Verkuil if (!test_bit(V4L2_FL_USES_V4L2_FH, &vfd->flags)) 11882438e78aSHans Verkuil return -ENOTTY; 11895bc3cb74SMauro Carvalho Chehab vfh = file->private_data; 119059b702eaSLaurent Pinchart return v4l2_prio_change(vfd->prio, &vfh->prio, *p); 11915bc3cb74SMauro Carvalho Chehab } 11925bc3cb74SMauro Carvalho Chehab 11935bc3cb74SMauro Carvalho Chehab static int v4l_enuminput(const struct v4l2_ioctl_ops *ops, 11945bc3cb74SMauro Carvalho Chehab struct file *file, void *fh, void *arg) 11955bc3cb74SMauro Carvalho Chehab { 119673f35418SHans Verkuil struct video_device *vfd = video_devdata(file); 11975bc3cb74SMauro Carvalho Chehab struct v4l2_input *p = arg; 11985bc3cb74SMauro Carvalho Chehab 11995bc3cb74SMauro Carvalho Chehab /* 120002fa6282SHans Verkuil * We set the flags for CAP_DV_TIMINGS & 12015bc3cb74SMauro Carvalho Chehab * CAP_STD here based on ioctl handler provided by the 12025bc3cb74SMauro Carvalho Chehab * driver. If the driver doesn't support these 12035bc3cb74SMauro Carvalho Chehab * for a specific input, it must override these flags. 12045bc3cb74SMauro Carvalho Chehab */ 120573f35418SHans Verkuil if (is_valid_ioctl(vfd, VIDIOC_S_STD)) 12065bc3cb74SMauro Carvalho Chehab p->capabilities |= V4L2_IN_CAP_STD; 12075bc3cb74SMauro Carvalho Chehab 1208f645e625SNiklas Söderlund if (vfd->device_caps & V4L2_CAP_IO_MC) { 1209f645e625SNiklas Söderlund if (p->index) 1210f645e625SNiklas Söderlund return -EINVAL; 1211f645e625SNiklas Söderlund strscpy(p->name, vfd->name, sizeof(p->name)); 1212f645e625SNiklas Söderlund p->type = V4L2_INPUT_TYPE_CAMERA; 1213f645e625SNiklas Söderlund return 0; 1214f645e625SNiklas Söderlund } 1215f645e625SNiklas Söderlund 12165bc3cb74SMauro Carvalho Chehab return ops->vidioc_enum_input(file, fh, p); 12175bc3cb74SMauro Carvalho Chehab } 12185bc3cb74SMauro Carvalho Chehab 12195bc3cb74SMauro Carvalho Chehab static int v4l_enumoutput(const struct v4l2_ioctl_ops *ops, 12205bc3cb74SMauro Carvalho Chehab struct file *file, void *fh, void *arg) 12215bc3cb74SMauro Carvalho Chehab { 122273f35418SHans Verkuil struct video_device *vfd = video_devdata(file); 12235bc3cb74SMauro Carvalho Chehab struct v4l2_output *p = arg; 12245bc3cb74SMauro Carvalho Chehab 12255bc3cb74SMauro Carvalho Chehab /* 122602fa6282SHans Verkuil * We set the flags for CAP_DV_TIMINGS & 12275bc3cb74SMauro Carvalho Chehab * CAP_STD here based on ioctl handler provided by the 12285bc3cb74SMauro Carvalho Chehab * driver. If the driver doesn't support these 12295bc3cb74SMauro Carvalho Chehab * for a specific output, it must override these flags. 12305bc3cb74SMauro Carvalho Chehab */ 123173f35418SHans Verkuil if (is_valid_ioctl(vfd, VIDIOC_S_STD)) 12325bc3cb74SMauro Carvalho Chehab p->capabilities |= V4L2_OUT_CAP_STD; 12335bc3cb74SMauro Carvalho Chehab 1234f645e625SNiklas Söderlund if (vfd->device_caps & V4L2_CAP_IO_MC) { 1235f645e625SNiklas Söderlund if (p->index) 1236f645e625SNiklas Söderlund return -EINVAL; 1237f645e625SNiklas Söderlund strscpy(p->name, vfd->name, sizeof(p->name)); 1238f645e625SNiklas Söderlund p->type = V4L2_OUTPUT_TYPE_ANALOG; 1239f645e625SNiklas Söderlund return 0; 1240f645e625SNiklas Söderlund } 1241f645e625SNiklas Söderlund 12425bc3cb74SMauro Carvalho Chehab return ops->vidioc_enum_output(file, fh, p); 12435bc3cb74SMauro Carvalho Chehab } 12445bc3cb74SMauro Carvalho Chehab 1245ba300204SHans Verkuil static void v4l_fill_fmtdesc(struct v4l2_fmtdesc *fmt) 1246ba300204SHans Verkuil { 1247ba300204SHans Verkuil const unsigned sz = sizeof(fmt->description); 1248ba300204SHans Verkuil const char *descr = NULL; 1249ba300204SHans Verkuil u32 flags = 0; 1250ba300204SHans Verkuil 1251ba300204SHans Verkuil /* 1252ba300204SHans Verkuil * We depart from the normal coding style here since the descriptions 1253ba300204SHans Verkuil * should be aligned so it is easy to see which descriptions will be 1254ba300204SHans Verkuil * longer than 31 characters (the max length for a description). 1255ba300204SHans Verkuil * And frankly, this is easier to read anyway. 1256ba300204SHans Verkuil * 1257ba300204SHans Verkuil * Note that gcc will use O(log N) comparisons to find the right case. 1258ba300204SHans Verkuil */ 1259ba300204SHans Verkuil switch (fmt->pixelformat) { 1260ba300204SHans Verkuil /* Max description length mask: descr = "0123456789012345678901234567890" */ 1261ba300204SHans Verkuil case V4L2_PIX_FMT_RGB332: descr = "8-bit RGB 3-3-2"; break; 1262ba300204SHans Verkuil case V4L2_PIX_FMT_RGB444: descr = "16-bit A/XRGB 4-4-4-4"; break; 1263ba300204SHans Verkuil case V4L2_PIX_FMT_ARGB444: descr = "16-bit ARGB 4-4-4-4"; break; 1264ba300204SHans Verkuil case V4L2_PIX_FMT_XRGB444: descr = "16-bit XRGB 4-4-4-4"; break; 12654747bd0fSHans Verkuil case V4L2_PIX_FMT_RGBA444: descr = "16-bit RGBA 4-4-4-4"; break; 12664747bd0fSHans Verkuil case V4L2_PIX_FMT_RGBX444: descr = "16-bit RGBX 4-4-4-4"; break; 12674747bd0fSHans Verkuil case V4L2_PIX_FMT_ABGR444: descr = "16-bit ABGR 4-4-4-4"; break; 12684747bd0fSHans Verkuil case V4L2_PIX_FMT_XBGR444: descr = "16-bit XBGR 4-4-4-4"; break; 12694747bd0fSHans Verkuil case V4L2_PIX_FMT_BGRA444: descr = "16-bit BGRA 4-4-4-4"; break; 12704747bd0fSHans Verkuil case V4L2_PIX_FMT_BGRX444: descr = "16-bit BGRX 4-4-4-4"; break; 1271ba300204SHans Verkuil case V4L2_PIX_FMT_RGB555: descr = "16-bit A/XRGB 1-5-5-5"; break; 1272ba300204SHans Verkuil case V4L2_PIX_FMT_ARGB555: descr = "16-bit ARGB 1-5-5-5"; break; 1273ba300204SHans Verkuil case V4L2_PIX_FMT_XRGB555: descr = "16-bit XRGB 1-5-5-5"; break; 12744747bd0fSHans Verkuil case V4L2_PIX_FMT_ABGR555: descr = "16-bit ABGR 1-5-5-5"; break; 12754747bd0fSHans Verkuil case V4L2_PIX_FMT_XBGR555: descr = "16-bit XBGR 1-5-5-5"; break; 12764747bd0fSHans Verkuil case V4L2_PIX_FMT_RGBA555: descr = "16-bit RGBA 5-5-5-1"; break; 12774747bd0fSHans Verkuil case V4L2_PIX_FMT_RGBX555: descr = "16-bit RGBX 5-5-5-1"; break; 12784747bd0fSHans Verkuil case V4L2_PIX_FMT_BGRA555: descr = "16-bit BGRA 5-5-5-1"; break; 12794747bd0fSHans Verkuil case V4L2_PIX_FMT_BGRX555: descr = "16-bit BGRX 5-5-5-1"; break; 1280ba300204SHans Verkuil case V4L2_PIX_FMT_RGB565: descr = "16-bit RGB 5-6-5"; break; 1281ba300204SHans Verkuil case V4L2_PIX_FMT_RGB555X: descr = "16-bit A/XRGB 1-5-5-5 BE"; break; 1282ba300204SHans Verkuil case V4L2_PIX_FMT_ARGB555X: descr = "16-bit ARGB 1-5-5-5 BE"; break; 1283ba300204SHans Verkuil case V4L2_PIX_FMT_XRGB555X: descr = "16-bit XRGB 1-5-5-5 BE"; break; 1284ba300204SHans Verkuil case V4L2_PIX_FMT_RGB565X: descr = "16-bit RGB 5-6-5 BE"; break; 1285ba300204SHans Verkuil case V4L2_PIX_FMT_BGR666: descr = "18-bit BGRX 6-6-6-14"; break; 1286ba300204SHans Verkuil case V4L2_PIX_FMT_BGR24: descr = "24-bit BGR 8-8-8"; break; 1287ba300204SHans Verkuil case V4L2_PIX_FMT_RGB24: descr = "24-bit RGB 8-8-8"; break; 1288ba300204SHans Verkuil case V4L2_PIX_FMT_BGR32: descr = "32-bit BGRA/X 8-8-8-8"; break; 1289ba300204SHans Verkuil case V4L2_PIX_FMT_ABGR32: descr = "32-bit BGRA 8-8-8-8"; break; 1290ba300204SHans Verkuil case V4L2_PIX_FMT_XBGR32: descr = "32-bit BGRX 8-8-8-8"; break; 1291ba300204SHans Verkuil case V4L2_PIX_FMT_RGB32: descr = "32-bit A/XRGB 8-8-8-8"; break; 1292ba300204SHans Verkuil case V4L2_PIX_FMT_ARGB32: descr = "32-bit ARGB 8-8-8-8"; break; 1293ba300204SHans Verkuil case V4L2_PIX_FMT_XRGB32: descr = "32-bit XRGB 8-8-8-8"; break; 12944747bd0fSHans Verkuil case V4L2_PIX_FMT_BGRA32: descr = "32-bit ABGR 8-8-8-8"; break; 12954747bd0fSHans Verkuil case V4L2_PIX_FMT_BGRX32: descr = "32-bit XBGR 8-8-8-8"; break; 12964747bd0fSHans Verkuil case V4L2_PIX_FMT_RGBA32: descr = "32-bit RGBA 8-8-8-8"; break; 12974747bd0fSHans Verkuil case V4L2_PIX_FMT_RGBX32: descr = "32-bit RGBX 8-8-8-8"; break; 12988d0e3fc6STomi Valkeinen case V4L2_PIX_FMT_RGBX1010102: descr = "32-bit RGBX 10-10-10-2"; break; 12998d0e3fc6STomi Valkeinen case V4L2_PIX_FMT_RGBA1010102: descr = "32-bit RGBA 10-10-10-2"; break; 13008d0e3fc6STomi Valkeinen case V4L2_PIX_FMT_ARGB2101010: descr = "32-bit ARGB 2-10-10-10"; break; 1301*da0b7a40SMing Qian case V4L2_PIX_FMT_BGR48_12: descr = "12-bit Depth BGR"; break; 1302ba300204SHans Verkuil case V4L2_PIX_FMT_GREY: descr = "8-bit Greyscale"; break; 1303ba300204SHans Verkuil case V4L2_PIX_FMT_Y4: descr = "4-bit Greyscale"; break; 1304ba300204SHans Verkuil case V4L2_PIX_FMT_Y6: descr = "6-bit Greyscale"; break; 1305ba300204SHans Verkuil case V4L2_PIX_FMT_Y10: descr = "10-bit Greyscale"; break; 1306ba300204SHans Verkuil case V4L2_PIX_FMT_Y12: descr = "12-bit Greyscale"; break; 1307a490ea68SMing Qian case V4L2_PIX_FMT_Y012: descr = "12-bit Greyscale (bits 15-4)"; break; 1308ae9753a0SDaniel Glöckner case V4L2_PIX_FMT_Y14: descr = "14-bit Greyscale"; break; 1309ba300204SHans Verkuil case V4L2_PIX_FMT_Y16: descr = "16-bit Greyscale"; break; 13102e5e435fSRicardo Ribalda case V4L2_PIX_FMT_Y16_BE: descr = "16-bit Greyscale BE"; break; 1311ba300204SHans Verkuil case V4L2_PIX_FMT_Y10BPACK: descr = "10-bit Greyscale (Packed)"; break; 13126e15bec4STodor Tomov case V4L2_PIX_FMT_Y10P: descr = "10-bit Greyscale (MIPI Packed)"; break; 1313b87f5e25SDaniel Scally case V4L2_PIX_FMT_IPU3_Y10: descr = "10-bit greyscale (IPU3 Packed)"; break; 13145b382290SLaurent Pinchart case V4L2_PIX_FMT_Y8I: descr = "Interleaved 8-bit Greyscale"; break; 13155b382290SLaurent Pinchart case V4L2_PIX_FMT_Y12I: descr = "Interleaved 12-bit Greyscale"; break; 13165b382290SLaurent Pinchart case V4L2_PIX_FMT_Z16: descr = "16-bit Depth"; break; 13175df082e2SEvgeni Raikhel case V4L2_PIX_FMT_INZI: descr = "Planar 10:16 Greyscale Depth"; break; 131892799ef7SSergey Dorodnicov case V4L2_PIX_FMT_CNF4: descr = "4-bit Depth Confidence (Packed)"; break; 1319ba300204SHans Verkuil case V4L2_PIX_FMT_PAL8: descr = "8-bit Palette"; break; 1320ba300204SHans Verkuil case V4L2_PIX_FMT_UV8: descr = "8-bit Chrominance UV 4-4"; break; 1321ba300204SHans Verkuil case V4L2_PIX_FMT_YVU410: descr = "Planar YVU 4:1:0"; break; 1322ba300204SHans Verkuil case V4L2_PIX_FMT_YVU420: descr = "Planar YVU 4:2:0"; break; 1323ba300204SHans Verkuil case V4L2_PIX_FMT_YUYV: descr = "YUYV 4:2:2"; break; 1324ba300204SHans Verkuil case V4L2_PIX_FMT_YYUV: descr = "YYUV 4:2:2"; break; 1325ba300204SHans Verkuil case V4L2_PIX_FMT_YVYU: descr = "YVYU 4:2:2"; break; 1326ba300204SHans Verkuil case V4L2_PIX_FMT_UYVY: descr = "UYVY 4:2:2"; break; 1327ba300204SHans Verkuil case V4L2_PIX_FMT_VYUY: descr = "VYUY 4:2:2"; break; 1328fcbafafbSPhilipp Zabel case V4L2_PIX_FMT_YUV422P: descr = "Planar YUV 4:2:2"; break; 1329ba300204SHans Verkuil case V4L2_PIX_FMT_YUV411P: descr = "Planar YUV 4:1:1"; break; 1330ba300204SHans Verkuil case V4L2_PIX_FMT_Y41P: descr = "YUV 4:1:1 (Packed)"; break; 1331ba300204SHans Verkuil case V4L2_PIX_FMT_YUV444: descr = "16-bit A/XYUV 4-4-4-4"; break; 1332ba300204SHans Verkuil case V4L2_PIX_FMT_YUV555: descr = "16-bit A/XYUV 1-5-5-5"; break; 1333ba300204SHans Verkuil case V4L2_PIX_FMT_YUV565: descr = "16-bit YUV 5-6-5"; break; 13340376a51fSMirela Rabulea case V4L2_PIX_FMT_YUV24: descr = "24-bit YUV 4:4:4 8-8-8"; break; 1335ba300204SHans Verkuil case V4L2_PIX_FMT_YUV32: descr = "32-bit A/XYUV 8-8-8-8"; break; 1336a7fe4ca7SVivek Kasireddy case V4L2_PIX_FMT_AYUV32: descr = "32-bit AYUV 8-8-8-8"; break; 1337a7fe4ca7SVivek Kasireddy case V4L2_PIX_FMT_XYUV32: descr = "32-bit XYUV 8-8-8-8"; break; 1338a7fe4ca7SVivek Kasireddy case V4L2_PIX_FMT_VUYA32: descr = "32-bit VUYA 8-8-8-8"; break; 1339a7fe4ca7SVivek Kasireddy case V4L2_PIX_FMT_VUYX32: descr = "32-bit VUYX 8-8-8-8"; break; 134000f6842eSLaurent Pinchart case V4L2_PIX_FMT_YUVA32: descr = "32-bit YUVA 8-8-8-8"; break; 134100f6842eSLaurent Pinchart case V4L2_PIX_FMT_YUVX32: descr = "32-bit YUVX 8-8-8-8"; break; 1342ba300204SHans Verkuil case V4L2_PIX_FMT_YUV410: descr = "Planar YUV 4:1:0"; break; 1343ba300204SHans Verkuil case V4L2_PIX_FMT_YUV420: descr = "Planar YUV 4:2:0"; break; 1344ba300204SHans Verkuil case V4L2_PIX_FMT_HI240: descr = "8-bit Dithered RGB (BTTV)"; break; 1345ba300204SHans Verkuil case V4L2_PIX_FMT_M420: descr = "YUV 4:2:0 (M420)"; break; 134699c95496SMing Qian case V4L2_PIX_FMT_YUV48_12: descr = "12-bit YUV 4:4:4 Packed"; break; 13476a394d56SJernej Skrabec case V4L2_PIX_FMT_NV12: descr = "Y/UV 4:2:0"; break; 13486a394d56SJernej Skrabec case V4L2_PIX_FMT_NV21: descr = "Y/VU 4:2:0"; break; 13496a394d56SJernej Skrabec case V4L2_PIX_FMT_NV16: descr = "Y/UV 4:2:2"; break; 13506a394d56SJernej Skrabec case V4L2_PIX_FMT_NV61: descr = "Y/VU 4:2:2"; break; 13516a394d56SJernej Skrabec case V4L2_PIX_FMT_NV24: descr = "Y/UV 4:4:4"; break; 13526a394d56SJernej Skrabec case V4L2_PIX_FMT_NV42: descr = "Y/VU 4:4:4"; break; 13536a394d56SJernej Skrabec case V4L2_PIX_FMT_P010: descr = "10-bit Y/UV 4:2:0"; break; 1354aa108040SMing Qian case V4L2_PIX_FMT_P012: descr = "12-bit Y/UV 4:2:0"; break; 13556a394d56SJernej Skrabec case V4L2_PIX_FMT_NV12_4L4: descr = "Y/UV 4:2:0 (4x4 Linear)"; break; 13566a394d56SJernej Skrabec case V4L2_PIX_FMT_NV12_16L16: descr = "Y/UV 4:2:0 (16x16 Linear)"; break; 13576a394d56SJernej Skrabec case V4L2_PIX_FMT_NV12_32L32: descr = "Y/UV 4:2:0 (32x32 Linear)"; break; 13586a394d56SJernej Skrabec case V4L2_PIX_FMT_P010_4L4: descr = "10-bit Y/UV 4:2:0 (4x4 Linear)"; break; 13596a394d56SJernej Skrabec case V4L2_PIX_FMT_NV12M: descr = "Y/UV 4:2:0 (N-C)"; break; 13606a394d56SJernej Skrabec case V4L2_PIX_FMT_NV21M: descr = "Y/VU 4:2:0 (N-C)"; break; 13616a394d56SJernej Skrabec case V4L2_PIX_FMT_NV16M: descr = "Y/UV 4:2:2 (N-C)"; break; 13626a394d56SJernej Skrabec case V4L2_PIX_FMT_NV61M: descr = "Y/VU 4:2:2 (N-C)"; break; 13636a394d56SJernej Skrabec case V4L2_PIX_FMT_NV12MT: descr = "Y/UV 4:2:0 (64x32 MB, N-C)"; break; 13646a394d56SJernej Skrabec case V4L2_PIX_FMT_NV12MT_16X16: descr = "Y/UV 4:2:0 (16x16 MB, N-C)"; break; 1365aa108040SMing Qian case V4L2_PIX_FMT_P012M: descr = "12-bit Y/UV 4:2:0 (N-C)"; break; 1366ba300204SHans Verkuil case V4L2_PIX_FMT_YUV420M: descr = "Planar YUV 4:2:0 (N-C)"; break; 1367ba300204SHans Verkuil case V4L2_PIX_FMT_YVU420M: descr = "Planar YVU 4:2:0 (N-C)"; break; 1368d65fae92SLaurent Pinchart case V4L2_PIX_FMT_YUV422M: descr = "Planar YUV 4:2:2 (N-C)"; break; 1369d65fae92SLaurent Pinchart case V4L2_PIX_FMT_YVU422M: descr = "Planar YVU 4:2:2 (N-C)"; break; 1370d65fae92SLaurent Pinchart case V4L2_PIX_FMT_YUV444M: descr = "Planar YUV 4:4:4 (N-C)"; break; 1371d65fae92SLaurent Pinchart case V4L2_PIX_FMT_YVU444M: descr = "Planar YVU 4:4:4 (N-C)"; break; 1372ba300204SHans Verkuil case V4L2_PIX_FMT_SBGGR8: descr = "8-bit Bayer BGBG/GRGR"; break; 1373ba300204SHans Verkuil case V4L2_PIX_FMT_SGBRG8: descr = "8-bit Bayer GBGB/RGRG"; break; 1374ba300204SHans Verkuil case V4L2_PIX_FMT_SGRBG8: descr = "8-bit Bayer GRGR/BGBG"; break; 1375ba300204SHans Verkuil case V4L2_PIX_FMT_SRGGB8: descr = "8-bit Bayer RGRG/GBGB"; break; 1376ba300204SHans Verkuil case V4L2_PIX_FMT_SBGGR10: descr = "10-bit Bayer BGBG/GRGR"; break; 1377ba300204SHans Verkuil case V4L2_PIX_FMT_SGBRG10: descr = "10-bit Bayer GBGB/RGRG"; break; 1378ba300204SHans Verkuil case V4L2_PIX_FMT_SGRBG10: descr = "10-bit Bayer GRGR/BGBG"; break; 1379ba300204SHans Verkuil case V4L2_PIX_FMT_SRGGB10: descr = "10-bit Bayer RGRG/GBGB"; break; 1380ba300204SHans Verkuil case V4L2_PIX_FMT_SBGGR10P: descr = "10-bit Bayer BGBG/GRGR Packed"; break; 1381ba300204SHans Verkuil case V4L2_PIX_FMT_SGBRG10P: descr = "10-bit Bayer GBGB/RGRG Packed"; break; 1382ba300204SHans Verkuil case V4L2_PIX_FMT_SGRBG10P: descr = "10-bit Bayer GRGR/BGBG Packed"; break; 1383ba300204SHans Verkuil case V4L2_PIX_FMT_SRGGB10P: descr = "10-bit Bayer RGRG/GBGB Packed"; break; 1384e8391b76SYong Zhi case V4L2_PIX_FMT_IPU3_SBGGR10: descr = "10-bit bayer BGGR IPU3 Packed"; break; 1385e8391b76SYong Zhi case V4L2_PIX_FMT_IPU3_SGBRG10: descr = "10-bit bayer GBRG IPU3 Packed"; break; 1386e8391b76SYong Zhi case V4L2_PIX_FMT_IPU3_SGRBG10: descr = "10-bit bayer GRBG IPU3 Packed"; break; 1387e8391b76SYong Zhi case V4L2_PIX_FMT_IPU3_SRGGB10: descr = "10-bit bayer RGGB IPU3 Packed"; break; 1388ba300204SHans Verkuil case V4L2_PIX_FMT_SBGGR10ALAW8: descr = "8-bit Bayer BGBG/GRGR (A-law)"; break; 1389ba300204SHans Verkuil case V4L2_PIX_FMT_SGBRG10ALAW8: descr = "8-bit Bayer GBGB/RGRG (A-law)"; break; 1390ba300204SHans Verkuil case V4L2_PIX_FMT_SGRBG10ALAW8: descr = "8-bit Bayer GRGR/BGBG (A-law)"; break; 1391ba300204SHans Verkuil case V4L2_PIX_FMT_SRGGB10ALAW8: descr = "8-bit Bayer RGRG/GBGB (A-law)"; break; 1392ba300204SHans Verkuil case V4L2_PIX_FMT_SBGGR10DPCM8: descr = "8-bit Bayer BGBG/GRGR (DPCM)"; break; 1393ba300204SHans Verkuil case V4L2_PIX_FMT_SGBRG10DPCM8: descr = "8-bit Bayer GBGB/RGRG (DPCM)"; break; 1394ba300204SHans Verkuil case V4L2_PIX_FMT_SGRBG10DPCM8: descr = "8-bit Bayer GRGR/BGBG (DPCM)"; break; 1395ba300204SHans Verkuil case V4L2_PIX_FMT_SRGGB10DPCM8: descr = "8-bit Bayer RGRG/GBGB (DPCM)"; break; 1396d1b3437eSSakari Ailus case V4L2_PIX_FMT_SBGGR12: descr = "12-bit Bayer BGBG/GRGR"; break; 1397d1b3437eSSakari Ailus case V4L2_PIX_FMT_SGBRG12: descr = "12-bit Bayer GBGB/RGRG"; break; 1398d1b3437eSSakari Ailus case V4L2_PIX_FMT_SGRBG12: descr = "12-bit Bayer GRGR/BGBG"; break; 1399d1b3437eSSakari Ailus case V4L2_PIX_FMT_SRGGB12: descr = "12-bit Bayer RGRG/GBGB"; break; 1400d1b3437eSSakari Ailus case V4L2_PIX_FMT_SBGGR12P: descr = "12-bit Bayer BGBG/GRGR Packed"; break; 1401d1b3437eSSakari Ailus case V4L2_PIX_FMT_SGBRG12P: descr = "12-bit Bayer GBGB/RGRG Packed"; break; 1402d1b3437eSSakari Ailus case V4L2_PIX_FMT_SGRBG12P: descr = "12-bit Bayer GRGR/BGBG Packed"; break; 1403d1b3437eSSakari Ailus case V4L2_PIX_FMT_SRGGB12P: descr = "12-bit Bayer RGRG/GBGB Packed"; break; 1404d12127edSSakari Ailus case V4L2_PIX_FMT_SBGGR14: descr = "14-bit Bayer BGBG/GRGR"; break; 1405d12127edSSakari Ailus case V4L2_PIX_FMT_SGBRG14: descr = "14-bit Bayer GBGB/RGRG"; break; 1406d12127edSSakari Ailus case V4L2_PIX_FMT_SGRBG14: descr = "14-bit Bayer GRGR/BGBG"; break; 1407d12127edSSakari Ailus case V4L2_PIX_FMT_SRGGB14: descr = "14-bit Bayer RGRG/GBGB"; break; 140883b15832SSakari Ailus case V4L2_PIX_FMT_SBGGR14P: descr = "14-bit Bayer BGBG/GRGR Packed"; break; 140983b15832SSakari Ailus case V4L2_PIX_FMT_SGBRG14P: descr = "14-bit Bayer GBGB/RGRG Packed"; break; 141083b15832SSakari Ailus case V4L2_PIX_FMT_SGRBG14P: descr = "14-bit Bayer GRGR/BGBG Packed"; break; 141183b15832SSakari Ailus case V4L2_PIX_FMT_SRGGB14P: descr = "14-bit Bayer RGRG/GBGB Packed"; break; 1412b9a4b13cSSakari Ailus case V4L2_PIX_FMT_SBGGR16: descr = "16-bit Bayer BGBG/GRGR"; break; 1413b9a4b13cSSakari Ailus case V4L2_PIX_FMT_SGBRG16: descr = "16-bit Bayer GBGB/RGRG"; break; 1414b9a4b13cSSakari Ailus case V4L2_PIX_FMT_SGRBG16: descr = "16-bit Bayer GRGR/BGBG"; break; 1415b9a4b13cSSakari Ailus case V4L2_PIX_FMT_SRGGB16: descr = "16-bit Bayer RGRG/GBGB"; break; 141699b74277SMauro Carvalho Chehab case V4L2_PIX_FMT_SN9C20X_I420: descr = "GSPCA SN9C20X I420"; break; 1417ba300204SHans Verkuil case V4L2_PIX_FMT_SPCA501: descr = "GSPCA SPCA501"; break; 1418ba300204SHans Verkuil case V4L2_PIX_FMT_SPCA505: descr = "GSPCA SPCA505"; break; 1419ba300204SHans Verkuil case V4L2_PIX_FMT_SPCA508: descr = "GSPCA SPCA508"; break; 1420ba300204SHans Verkuil case V4L2_PIX_FMT_STV0680: descr = "GSPCA STV0680"; break; 1421ba300204SHans Verkuil case V4L2_PIX_FMT_TM6000: descr = "A/V + VBI Mux Packet"; break; 1422ba300204SHans Verkuil case V4L2_PIX_FMT_CIT_YYVYUY: descr = "GSPCA CIT YYVYUY"; break; 1423ba300204SHans Verkuil case V4L2_PIX_FMT_KONICA420: descr = "GSPCA KONICA420"; break; 1424ffe5350cSAlexandre Courbot case V4L2_PIX_FMT_MM21: descr = "Mediatek 8-bit Block Format"; break; 142566b2ab27SRicardo Ribalda Delgado case V4L2_PIX_FMT_HSV24: descr = "24-bit HSV 8-8-8"; break; 142666b2ab27SRicardo Ribalda Delgado case V4L2_PIX_FMT_HSV32: descr = "32-bit XHSV 8-8-8-8"; break; 142748fc10aaSAntti Palosaari case V4L2_SDR_FMT_CU8: descr = "Complex U8"; break; 142848fc10aaSAntti Palosaari case V4L2_SDR_FMT_CU16LE: descr = "Complex U16LE"; break; 1429ba300204SHans Verkuil case V4L2_SDR_FMT_CS8: descr = "Complex S8"; break; 1430ba300204SHans Verkuil case V4L2_SDR_FMT_CS14LE: descr = "Complex S14LE"; break; 1431ba300204SHans Verkuil case V4L2_SDR_FMT_RU12LE: descr = "Real U12LE"; break; 1432c28f2118SRamesh Shanmugasundaram case V4L2_SDR_FMT_PCU16BE: descr = "Planar Complex U16BE"; break; 1433c28f2118SRamesh Shanmugasundaram case V4L2_SDR_FMT_PCU18BE: descr = "Planar Complex U18BE"; break; 1434c28f2118SRamesh Shanmugasundaram case V4L2_SDR_FMT_PCU20BE: descr = "Planar Complex U20BE"; break; 14354747bd0fSHans Verkuil case V4L2_TCH_FMT_DELTA_TD16: descr = "16-bit Signed Deltas"; break; 14364747bd0fSHans Verkuil case V4L2_TCH_FMT_DELTA_TD08: descr = "8-bit Signed Deltas"; break; 14374747bd0fSHans Verkuil case V4L2_TCH_FMT_TU16: descr = "16-bit Unsigned Touch Data"; break; 14384747bd0fSHans Verkuil case V4L2_TCH_FMT_TU08: descr = "8-bit Unsigned Touch Data"; break; 143914d66538SLaurent Pinchart case V4L2_META_FMT_VSP1_HGO: descr = "R-Car VSP1 1-D Histogram"; break; 14405deb1c04SNiklas Söderlund case V4L2_META_FMT_VSP1_HGT: descr = "R-Car VSP1 2-D Histogram"; break; 14414747bd0fSHans Verkuil case V4L2_META_FMT_UVC: descr = "UVC Payload Header Metadata"; break; 14424747bd0fSHans Verkuil case V4L2_META_FMT_D4XX: descr = "Intel D4xx UVC Metadata"; break; 144378892b6bSVandana BN case V4L2_META_FMT_VIVID: descr = "Vivid Metadata"; break; 1444df22026aSShunqian Zheng case V4L2_META_FMT_RK_ISP1_PARAMS: descr = "Rockchip ISP1 3A Parameters"; break; 1445df22026aSShunqian Zheng case V4L2_META_FMT_RK_ISP1_STAT_3A: descr = "Rockchip ISP1 3A Statistics"; break; 14465b8bb216SMing Qian case V4L2_PIX_FMT_NV12_8L128: descr = "NV12 (8x128 Linear)"; break; 144772a74c8fSMing Qian case V4L2_PIX_FMT_NV12M_8L128: descr = "NV12M (8x128 Linear)"; break; 14485b8bb216SMing Qian case V4L2_PIX_FMT_NV12_10BE_8L128: descr = "10-bit NV12 (8x128 Linear, BE)"; break; 144972a74c8fSMing Qian case V4L2_PIX_FMT_NV12M_10BE_8L128: descr = "10-bit NV12M (8x128 Linear, BE)"; break; 14500dc1d7a7STomi Valkeinen case V4L2_PIX_FMT_Y210: descr = "10-bit YUYV Packed"; break; 14510dc1d7a7STomi Valkeinen case V4L2_PIX_FMT_Y212: descr = "12-bit YUYV Packed"; break; 14520dc1d7a7STomi Valkeinen case V4L2_PIX_FMT_Y216: descr = "16-bit YUYV Packed"; break; 1453ba300204SHans Verkuil 1454ba300204SHans Verkuil default: 1455ba300204SHans Verkuil /* Compressed formats */ 1456ba300204SHans Verkuil flags = V4L2_FMT_FLAG_COMPRESSED; 1457ba300204SHans Verkuil switch (fmt->pixelformat) { 1458ba300204SHans Verkuil /* Max description length mask: descr = "0123456789012345678901234567890" */ 1459ba300204SHans Verkuil case V4L2_PIX_FMT_MJPEG: descr = "Motion-JPEG"; break; 1460ba300204SHans Verkuil case V4L2_PIX_FMT_JPEG: descr = "JFIF JPEG"; break; 1461ba300204SHans Verkuil case V4L2_PIX_FMT_DV: descr = "1394"; break; 1462ba300204SHans Verkuil case V4L2_PIX_FMT_MPEG: descr = "MPEG-1/2/4"; break; 1463ba300204SHans Verkuil case V4L2_PIX_FMT_H264: descr = "H.264"; break; 1464ba300204SHans Verkuil case V4L2_PIX_FMT_H264_NO_SC: descr = "H.264 (No Start Codes)"; break; 1465ba300204SHans Verkuil case V4L2_PIX_FMT_H264_MVC: descr = "H.264 MVC"; break; 14667bb3c32aSEzequiel Garcia case V4L2_PIX_FMT_H264_SLICE: descr = "H.264 Parsed Slice Data"; break; 1467ba300204SHans Verkuil case V4L2_PIX_FMT_H263: descr = "H.263"; break; 1468ba300204SHans Verkuil case V4L2_PIX_FMT_MPEG1: descr = "MPEG-1 ES"; break; 1469ba300204SHans Verkuil case V4L2_PIX_FMT_MPEG2: descr = "MPEG-2 ES"; break; 1470c27bb30eSPaul Kocialkowski case V4L2_PIX_FMT_MPEG2_SLICE: descr = "MPEG-2 Parsed Slice Data"; break; 14714747bd0fSHans Verkuil case V4L2_PIX_FMT_MPEG4: descr = "MPEG-4 Part 2 ES"; break; 1472ba300204SHans Verkuil case V4L2_PIX_FMT_XVID: descr = "Xvid"; break; 1473ba300204SHans Verkuil case V4L2_PIX_FMT_VC1_ANNEX_G: descr = "VC-1 (SMPTE 412M Annex G)"; break; 1474ba300204SHans Verkuil case V4L2_PIX_FMT_VC1_ANNEX_L: descr = "VC-1 (SMPTE 412M Annex L)"; break; 1475ba300204SHans Verkuil case V4L2_PIX_FMT_VP8: descr = "VP8"; break; 1476a57d6acaSPawel Osciak case V4L2_PIX_FMT_VP8_FRAME: descr = "VP8 Frame"; break; 1477fa14a564SWu-Cheng Li case V4L2_PIX_FMT_VP9: descr = "VP9"; break; 1478b88dbe38SAndrzej Pietrasiewicz case V4L2_PIX_FMT_VP9_FRAME: descr = "VP9 Frame"; break; 14791c791727SSmitha T Murthy case V4L2_PIX_FMT_HEVC: descr = "HEVC"; break; /* aka H.265 */ 1480256fa392SPaul Kocialkowski case V4L2_PIX_FMT_HEVC_SLICE: descr = "HEVC Parsed Slice Data"; break; 148162c3fce0SHans Verkuil case V4L2_PIX_FMT_FWHT: descr = "FWHT"; break; /* used in vicodec */ 1482f05a51b9SHans Verkuil case V4L2_PIX_FMT_FWHT_STATELESS: descr = "FWHT Stateless"; break; /* used in vicodec */ 1483ae77d139SMing Qian case V4L2_PIX_FMT_SPK: descr = "Sorenson Spark"; break; 1484ec9aa62aSMing Qian case V4L2_PIX_FMT_RV30: descr = "RealVideo 8"; break; 1485ec9aa62aSMing Qian case V4L2_PIX_FMT_RV40: descr = "RealVideo 9 & 10"; break; 1486ba300204SHans Verkuil case V4L2_PIX_FMT_CPIA1: descr = "GSPCA CPiA YUV"; break; 1487ba300204SHans Verkuil case V4L2_PIX_FMT_WNVA: descr = "WNVA"; break; 1488ba300204SHans Verkuil case V4L2_PIX_FMT_SN9C10X: descr = "GSPCA SN9C10X"; break; 1489ba300204SHans Verkuil case V4L2_PIX_FMT_PWC1: descr = "Raw Philips Webcam Type (Old)"; break; 1490ba300204SHans Verkuil case V4L2_PIX_FMT_PWC2: descr = "Raw Philips Webcam Type (New)"; break; 1491ba300204SHans Verkuil case V4L2_PIX_FMT_ET61X251: descr = "GSPCA ET61X251"; break; 1492ba300204SHans Verkuil case V4L2_PIX_FMT_SPCA561: descr = "GSPCA SPCA561"; break; 1493ba300204SHans Verkuil case V4L2_PIX_FMT_PAC207: descr = "GSPCA PAC207"; break; 1494ba300204SHans Verkuil case V4L2_PIX_FMT_MR97310A: descr = "GSPCA MR97310A"; break; 1495ba300204SHans Verkuil case V4L2_PIX_FMT_JL2005BCD: descr = "GSPCA JL2005BCD"; break; 1496ba300204SHans Verkuil case V4L2_PIX_FMT_SN9C2028: descr = "GSPCA SN9C2028"; break; 1497ba300204SHans Verkuil case V4L2_PIX_FMT_SQ905C: descr = "GSPCA SQ905C"; break; 1498ba300204SHans Verkuil case V4L2_PIX_FMT_PJPG: descr = "GSPCA PJPG"; break; 1499ba300204SHans Verkuil case V4L2_PIX_FMT_OV511: descr = "GSPCA OV511"; break; 1500ba300204SHans Verkuil case V4L2_PIX_FMT_OV518: descr = "GSPCA OV518"; break; 1501ba300204SHans Verkuil case V4L2_PIX_FMT_JPGL: descr = "JPEG Lite"; break; 1502ba300204SHans Verkuil case V4L2_PIX_FMT_SE401: descr = "GSPCA SE401"; break; 1503ba300204SHans Verkuil case V4L2_PIX_FMT_S5C_UYVY_JPG: descr = "S5C73MX interleaved UYVY/JPEG"; break; 1504d4de6634STiffany Lin case V4L2_PIX_FMT_MT21C: descr = "Mediatek Compressed Format"; break; 15052308d5afSStanimir Varbanov case V4L2_PIX_FMT_QC08C: descr = "QCOM Compressed 8-bit Format"; break; 15062308d5afSStanimir Varbanov case V4L2_PIX_FMT_QC10C: descr = "QCOM Compressed 10-bit Format"; break; 15077a4b3770SJammy Huang case V4L2_PIX_FMT_AJPG: descr = "Aspeed JPEG"; break; 1508ba300204SHans Verkuil default: 1509ba300204SHans Verkuil if (fmt->description[0]) 1510ba300204SHans Verkuil return; 1511c2286cc0SSakari Ailus WARN(1, "Unknown pixelformat 0x%08x\n", fmt->pixelformat); 1512ba300204SHans Verkuil flags = 0; 1513e927e1e0SSakari Ailus snprintf(fmt->description, sz, "%p4cc", 1514e927e1e0SSakari Ailus &fmt->pixelformat); 1515ba300204SHans Verkuil break; 1516ba300204SHans Verkuil } 1517ba300204SHans Verkuil } 1518ba300204SHans Verkuil 1519ba300204SHans Verkuil if (descr) 1520e7dd89ceSHans Petter Selasky WARN_ON(strscpy(fmt->description, descr, sz) < 0); 15217c490e25SHans Verkuil fmt->flags |= flags; 1522ba300204SHans Verkuil } 1523ba300204SHans Verkuil 15245bc3cb74SMauro Carvalho Chehab static int v4l_enum_fmt(const struct v4l2_ioctl_ops *ops, 15255bc3cb74SMauro Carvalho Chehab struct file *file, void *fh, void *arg) 15265bc3cb74SMauro Carvalho Chehab { 15277e98b7b5SBoris Brezillon struct video_device *vdev = video_devdata(file); 15285bc3cb74SMauro Carvalho Chehab struct v4l2_fmtdesc *p = arg; 1529b2469c81SHans Verkuil int ret = check_fmt(file, p->type); 1530e5b6b07aSLaurent Pinchart u32 mbus_code; 1531f0d2b7a8SBoris Brezillon u32 cap_mask; 1532b2469c81SHans Verkuil 1533b2469c81SHans Verkuil if (ret) 1534b2469c81SHans Verkuil return ret; 1535b2469c81SHans Verkuil ret = -EINVAL; 15365bc3cb74SMauro Carvalho Chehab 1537e5b6b07aSLaurent Pinchart if (!(vdev->device_caps & V4L2_CAP_IO_MC)) 1538e5b6b07aSLaurent Pinchart p->mbus_code = 0; 1539e5b6b07aSLaurent Pinchart 1540e5b6b07aSLaurent Pinchart mbus_code = p->mbus_code; 15410625b6b8SXiu Jianfeng memset_after(p, 0, type); 1542e5b6b07aSLaurent Pinchart p->mbus_code = mbus_code; 1543e5b6b07aSLaurent Pinchart 15445bc3cb74SMauro Carvalho Chehab switch (p->type) { 15455bc3cb74SMauro Carvalho Chehab case V4L2_BUF_TYPE_VIDEO_CAPTURE: 15467e98b7b5SBoris Brezillon case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE: 1547f0d2b7a8SBoris Brezillon cap_mask = V4L2_CAP_VIDEO_CAPTURE_MPLANE | 1548f0d2b7a8SBoris Brezillon V4L2_CAP_VIDEO_M2M_MPLANE; 1549f0d2b7a8SBoris Brezillon if (!!(vdev->device_caps & cap_mask) != 15507e98b7b5SBoris Brezillon (p->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)) 15517e98b7b5SBoris Brezillon break; 15527e98b7b5SBoris Brezillon 1553b2469c81SHans Verkuil if (unlikely(!ops->vidioc_enum_fmt_vid_cap)) 15545bc3cb74SMauro Carvalho Chehab break; 1555ba300204SHans Verkuil ret = ops->vidioc_enum_fmt_vid_cap(file, fh, arg); 1556ba300204SHans Verkuil break; 15575bc3cb74SMauro Carvalho Chehab case V4L2_BUF_TYPE_VIDEO_OVERLAY: 1558b2469c81SHans Verkuil if (unlikely(!ops->vidioc_enum_fmt_vid_overlay)) 15595bc3cb74SMauro Carvalho Chehab break; 1560ba300204SHans Verkuil ret = ops->vidioc_enum_fmt_vid_overlay(file, fh, arg); 1561ba300204SHans Verkuil break; 15625bc3cb74SMauro Carvalho Chehab case V4L2_BUF_TYPE_VIDEO_OUTPUT: 15637e98b7b5SBoris Brezillon case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE: 1564f0d2b7a8SBoris Brezillon cap_mask = V4L2_CAP_VIDEO_OUTPUT_MPLANE | 1565f0d2b7a8SBoris Brezillon V4L2_CAP_VIDEO_M2M_MPLANE; 1566f0d2b7a8SBoris Brezillon if (!!(vdev->device_caps & cap_mask) != 15677e98b7b5SBoris Brezillon (p->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)) 15687e98b7b5SBoris Brezillon break; 15697e98b7b5SBoris Brezillon 1570b2469c81SHans Verkuil if (unlikely(!ops->vidioc_enum_fmt_vid_out)) 15715bc3cb74SMauro Carvalho Chehab break; 1572ba300204SHans Verkuil ret = ops->vidioc_enum_fmt_vid_out(file, fh, arg); 1573ba300204SHans Verkuil break; 1574582c52cbSAntti Palosaari case V4L2_BUF_TYPE_SDR_CAPTURE: 1575b2469c81SHans Verkuil if (unlikely(!ops->vidioc_enum_fmt_sdr_cap)) 1576582c52cbSAntti Palosaari break; 1577ba300204SHans Verkuil ret = ops->vidioc_enum_fmt_sdr_cap(file, fh, arg); 1578ba300204SHans Verkuil break; 15799effc72fSAntti Palosaari case V4L2_BUF_TYPE_SDR_OUTPUT: 1580b2469c81SHans Verkuil if (unlikely(!ops->vidioc_enum_fmt_sdr_out)) 15819effc72fSAntti Palosaari break; 15829effc72fSAntti Palosaari ret = ops->vidioc_enum_fmt_sdr_out(file, fh, arg); 15839effc72fSAntti Palosaari break; 1584fb9ffa6aSLaurent Pinchart case V4L2_BUF_TYPE_META_CAPTURE: 1585b2469c81SHans Verkuil if (unlikely(!ops->vidioc_enum_fmt_meta_cap)) 1586fb9ffa6aSLaurent Pinchart break; 1587fb9ffa6aSLaurent Pinchart ret = ops->vidioc_enum_fmt_meta_cap(file, fh, arg); 1588fb9ffa6aSLaurent Pinchart break; 158972148d1aSSakari Ailus case V4L2_BUF_TYPE_META_OUTPUT: 159072148d1aSSakari Ailus if (unlikely(!ops->vidioc_enum_fmt_meta_out)) 159172148d1aSSakari Ailus break; 159272148d1aSSakari Ailus ret = ops->vidioc_enum_fmt_meta_out(file, fh, arg); 159372148d1aSSakari Ailus break; 15945bc3cb74SMauro Carvalho Chehab } 1595ba300204SHans Verkuil if (ret == 0) 1596ba300204SHans Verkuil v4l_fill_fmtdesc(p); 1597ba300204SHans Verkuil return ret; 15985bc3cb74SMauro Carvalho Chehab } 15995bc3cb74SMauro Carvalho Chehab 1600545b618cSVandana BN static void v4l_pix_format_touch(struct v4l2_pix_format *p) 1601545b618cSVandana BN { 1602545b618cSVandana BN /* 1603545b618cSVandana BN * The v4l2_pix_format structure contains fields that make no sense for 1604545b618cSVandana BN * touch. Set them to default values in this case. 1605545b618cSVandana BN */ 1606545b618cSVandana BN 1607545b618cSVandana BN p->field = V4L2_FIELD_NONE; 1608545b618cSVandana BN p->colorspace = V4L2_COLORSPACE_RAW; 1609545b618cSVandana BN p->flags = 0; 1610545b618cSVandana BN p->ycbcr_enc = 0; 1611545b618cSVandana BN p->quantization = 0; 1612545b618cSVandana BN p->xfer_func = 0; 1613545b618cSVandana BN } 1614545b618cSVandana BN 16155bc3cb74SMauro Carvalho Chehab static int v4l_g_fmt(const struct v4l2_ioctl_ops *ops, 16165bc3cb74SMauro Carvalho Chehab struct file *file, void *fh, void *arg) 16175bc3cb74SMauro Carvalho Chehab { 16185bc3cb74SMauro Carvalho Chehab struct v4l2_format *p = arg; 1619545b618cSVandana BN struct video_device *vfd = video_devdata(file); 1620b2469c81SHans Verkuil int ret = check_fmt(file, p->type); 1621b2469c81SHans Verkuil 1622b2469c81SHans Verkuil if (ret) 1623b2469c81SHans Verkuil return ret; 1624d52e2381SLaurent Pinchart 1625e5ce558aSHans Verkuil memset(&p->fmt, 0, sizeof(p->fmt)); 1626e5ce558aSHans Verkuil 16275bc3cb74SMauro Carvalho Chehab switch (p->type) { 16285bc3cb74SMauro Carvalho Chehab case V4L2_BUF_TYPE_VIDEO_CAPTURE: 1629b2469c81SHans Verkuil if (unlikely(!ops->vidioc_g_fmt_vid_cap)) 16305bc3cb74SMauro Carvalho Chehab break; 163148f2650aSHans Verkuil p->fmt.pix.priv = V4L2_PIX_FMT_PRIV_MAGIC; 1632d52e2381SLaurent Pinchart ret = ops->vidioc_g_fmt_vid_cap(file, fh, arg); 163348f2650aSHans Verkuil /* just in case the driver zeroed it again */ 1634d52e2381SLaurent Pinchart p->fmt.pix.priv = V4L2_PIX_FMT_PRIV_MAGIC; 1635545b618cSVandana BN if (vfd->vfl_type == VFL_TYPE_TOUCH) 1636545b618cSVandana BN v4l_pix_format_touch(&p->fmt.pix); 1637d52e2381SLaurent Pinchart return ret; 16385bc3cb74SMauro Carvalho Chehab case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE: 16395bc3cb74SMauro Carvalho Chehab return ops->vidioc_g_fmt_vid_cap_mplane(file, fh, arg); 16405bc3cb74SMauro Carvalho Chehab case V4L2_BUF_TYPE_VIDEO_OVERLAY: 16415bc3cb74SMauro Carvalho Chehab return ops->vidioc_g_fmt_vid_overlay(file, fh, arg); 16424b20259fSHans Verkuil case V4L2_BUF_TYPE_VBI_CAPTURE: 16434b20259fSHans Verkuil return ops->vidioc_g_fmt_vbi_cap(file, fh, arg); 16444b20259fSHans Verkuil case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE: 16454b20259fSHans Verkuil return ops->vidioc_g_fmt_sliced_vbi_cap(file, fh, arg); 16465bc3cb74SMauro Carvalho Chehab case V4L2_BUF_TYPE_VIDEO_OUTPUT: 1647b2469c81SHans Verkuil if (unlikely(!ops->vidioc_g_fmt_vid_out)) 16485bc3cb74SMauro Carvalho Chehab break; 164948f2650aSHans Verkuil p->fmt.pix.priv = V4L2_PIX_FMT_PRIV_MAGIC; 1650d52e2381SLaurent Pinchart ret = ops->vidioc_g_fmt_vid_out(file, fh, arg); 165148f2650aSHans Verkuil /* just in case the driver zeroed it again */ 1652d52e2381SLaurent Pinchart p->fmt.pix.priv = V4L2_PIX_FMT_PRIV_MAGIC; 1653d52e2381SLaurent Pinchart return ret; 16545bc3cb74SMauro Carvalho Chehab case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE: 16555bc3cb74SMauro Carvalho Chehab return ops->vidioc_g_fmt_vid_out_mplane(file, fh, arg); 16565bc3cb74SMauro Carvalho Chehab case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY: 16575bc3cb74SMauro Carvalho Chehab return ops->vidioc_g_fmt_vid_out_overlay(file, fh, arg); 16585bc3cb74SMauro Carvalho Chehab case V4L2_BUF_TYPE_VBI_OUTPUT: 16595bc3cb74SMauro Carvalho Chehab return ops->vidioc_g_fmt_vbi_out(file, fh, arg); 16605bc3cb74SMauro Carvalho Chehab case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT: 16615bc3cb74SMauro Carvalho Chehab return ops->vidioc_g_fmt_sliced_vbi_out(file, fh, arg); 1662582c52cbSAntti Palosaari case V4L2_BUF_TYPE_SDR_CAPTURE: 1663582c52cbSAntti Palosaari return ops->vidioc_g_fmt_sdr_cap(file, fh, arg); 16649effc72fSAntti Palosaari case V4L2_BUF_TYPE_SDR_OUTPUT: 16659effc72fSAntti Palosaari return ops->vidioc_g_fmt_sdr_out(file, fh, arg); 1666fb9ffa6aSLaurent Pinchart case V4L2_BUF_TYPE_META_CAPTURE: 1667fb9ffa6aSLaurent Pinchart return ops->vidioc_g_fmt_meta_cap(file, fh, arg); 166872148d1aSSakari Ailus case V4L2_BUF_TYPE_META_OUTPUT: 166972148d1aSSakari Ailus return ops->vidioc_g_fmt_meta_out(file, fh, arg); 16705bc3cb74SMauro Carvalho Chehab } 16715bc3cb74SMauro Carvalho Chehab return -EINVAL; 16725bc3cb74SMauro Carvalho Chehab } 16735bc3cb74SMauro Carvalho Chehab 16745bc3cb74SMauro Carvalho Chehab static int v4l_s_fmt(const struct v4l2_ioctl_ops *ops, 16755bc3cb74SMauro Carvalho Chehab struct file *file, void *fh, void *arg) 16765bc3cb74SMauro Carvalho Chehab { 16775bc3cb74SMauro Carvalho Chehab struct v4l2_format *p = arg; 16784b20259fSHans Verkuil struct video_device *vfd = video_devdata(file); 1679b2469c81SHans Verkuil int ret = check_fmt(file, p->type); 16804e1e0eb0SEzequiel Garcia unsigned int i; 1681b2469c81SHans Verkuil 1682b2469c81SHans Verkuil if (ret) 1683b2469c81SHans Verkuil return ret; 16845bc3cb74SMauro Carvalho Chehab 168577fa4e07SShuah Khan ret = v4l_enable_media_source(vfd); 168677fa4e07SShuah Khan if (ret) 168777fa4e07SShuah Khan return ret; 1688d52e2381SLaurent Pinchart v4l_sanitize_format(p); 1689d52e2381SLaurent Pinchart 16905bc3cb74SMauro Carvalho Chehab switch (p->type) { 16915bc3cb74SMauro Carvalho Chehab case V4L2_BUF_TYPE_VIDEO_CAPTURE: 1692b2469c81SHans Verkuil if (unlikely(!ops->vidioc_s_fmt_vid_cap)) 16935bc3cb74SMauro Carvalho Chehab break; 16940625b6b8SXiu Jianfeng memset_after(p, 0, fmt.pix); 169548f2650aSHans Verkuil ret = ops->vidioc_s_fmt_vid_cap(file, fh, arg); 169648f2650aSHans Verkuil /* just in case the driver zeroed it again */ 169748f2650aSHans Verkuil p->fmt.pix.priv = V4L2_PIX_FMT_PRIV_MAGIC; 1698b2469c81SHans Verkuil if (vfd->vfl_type == VFL_TYPE_TOUCH) 1699b2fe22d0SNick Dyer v4l_pix_format_touch(&p->fmt.pix); 170048f2650aSHans Verkuil return ret; 17015bc3cb74SMauro Carvalho Chehab case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE: 1702b2469c81SHans Verkuil if (unlikely(!ops->vidioc_s_fmt_vid_cap_mplane)) 17035bc3cb74SMauro Carvalho Chehab break; 17040625b6b8SXiu Jianfeng memset_after(p, 0, fmt.pix_mp.xfer_func); 17054e1e0eb0SEzequiel Garcia for (i = 0; i < p->fmt.pix_mp.num_planes; i++) 17060625b6b8SXiu Jianfeng memset_after(&p->fmt.pix_mp.plane_fmt[i], 17070625b6b8SXiu Jianfeng 0, bytesperline); 17085bc3cb74SMauro Carvalho Chehab return ops->vidioc_s_fmt_vid_cap_mplane(file, fh, arg); 17095bc3cb74SMauro Carvalho Chehab case V4L2_BUF_TYPE_VIDEO_OVERLAY: 1710b2469c81SHans Verkuil if (unlikely(!ops->vidioc_s_fmt_vid_overlay)) 17115bc3cb74SMauro Carvalho Chehab break; 17120625b6b8SXiu Jianfeng memset_after(p, 0, fmt.win); 171399ba0703SHans Verkuil p->fmt.win.clips = NULL; 171499ba0703SHans Verkuil p->fmt.win.clipcount = 0; 171599ba0703SHans Verkuil p->fmt.win.bitmap = NULL; 17165bc3cb74SMauro Carvalho Chehab return ops->vidioc_s_fmt_vid_overlay(file, fh, arg); 17174b20259fSHans Verkuil case V4L2_BUF_TYPE_VBI_CAPTURE: 1718b2469c81SHans Verkuil if (unlikely(!ops->vidioc_s_fmt_vbi_cap)) 17194b20259fSHans Verkuil break; 17200625b6b8SXiu Jianfeng memset_after(p, 0, fmt.vbi.flags); 17214b20259fSHans Verkuil return ops->vidioc_s_fmt_vbi_cap(file, fh, arg); 17224b20259fSHans Verkuil case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE: 1723b2469c81SHans Verkuil if (unlikely(!ops->vidioc_s_fmt_sliced_vbi_cap)) 17244b20259fSHans Verkuil break; 17250625b6b8SXiu Jianfeng memset_after(p, 0, fmt.sliced.io_size); 17264b20259fSHans Verkuil return ops->vidioc_s_fmt_sliced_vbi_cap(file, fh, arg); 17275bc3cb74SMauro Carvalho Chehab case V4L2_BUF_TYPE_VIDEO_OUTPUT: 1728b2469c81SHans Verkuil if (unlikely(!ops->vidioc_s_fmt_vid_out)) 17295bc3cb74SMauro Carvalho Chehab break; 17300625b6b8SXiu Jianfeng memset_after(p, 0, fmt.pix); 173148f2650aSHans Verkuil ret = ops->vidioc_s_fmt_vid_out(file, fh, arg); 173248f2650aSHans Verkuil /* just in case the driver zeroed it again */ 173348f2650aSHans Verkuil p->fmt.pix.priv = V4L2_PIX_FMT_PRIV_MAGIC; 173448f2650aSHans Verkuil return ret; 17355bc3cb74SMauro Carvalho Chehab case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE: 1736b2469c81SHans Verkuil if (unlikely(!ops->vidioc_s_fmt_vid_out_mplane)) 17375bc3cb74SMauro Carvalho Chehab break; 17380625b6b8SXiu Jianfeng memset_after(p, 0, fmt.pix_mp.xfer_func); 17394e1e0eb0SEzequiel Garcia for (i = 0; i < p->fmt.pix_mp.num_planes; i++) 17400625b6b8SXiu Jianfeng memset_after(&p->fmt.pix_mp.plane_fmt[i], 17410625b6b8SXiu Jianfeng 0, bytesperline); 17425bc3cb74SMauro Carvalho Chehab return ops->vidioc_s_fmt_vid_out_mplane(file, fh, arg); 17435bc3cb74SMauro Carvalho Chehab case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY: 1744b2469c81SHans Verkuil if (unlikely(!ops->vidioc_s_fmt_vid_out_overlay)) 17455bc3cb74SMauro Carvalho Chehab break; 17460625b6b8SXiu Jianfeng memset_after(p, 0, fmt.win); 174799ba0703SHans Verkuil p->fmt.win.clips = NULL; 174899ba0703SHans Verkuil p->fmt.win.clipcount = 0; 174999ba0703SHans Verkuil p->fmt.win.bitmap = NULL; 17505bc3cb74SMauro Carvalho Chehab return ops->vidioc_s_fmt_vid_out_overlay(file, fh, arg); 17515bc3cb74SMauro Carvalho Chehab case V4L2_BUF_TYPE_VBI_OUTPUT: 1752b2469c81SHans Verkuil if (unlikely(!ops->vidioc_s_fmt_vbi_out)) 17535bc3cb74SMauro Carvalho Chehab break; 17540625b6b8SXiu Jianfeng memset_after(p, 0, fmt.vbi.flags); 17555bc3cb74SMauro Carvalho Chehab return ops->vidioc_s_fmt_vbi_out(file, fh, arg); 17565bc3cb74SMauro Carvalho Chehab case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT: 1757b2469c81SHans Verkuil if (unlikely(!ops->vidioc_s_fmt_sliced_vbi_out)) 17585bc3cb74SMauro Carvalho Chehab break; 17590625b6b8SXiu Jianfeng memset_after(p, 0, fmt.sliced.io_size); 17605bc3cb74SMauro Carvalho Chehab return ops->vidioc_s_fmt_sliced_vbi_out(file, fh, arg); 1761582c52cbSAntti Palosaari case V4L2_BUF_TYPE_SDR_CAPTURE: 1762b2469c81SHans Verkuil if (unlikely(!ops->vidioc_s_fmt_sdr_cap)) 1763582c52cbSAntti Palosaari break; 17640625b6b8SXiu Jianfeng memset_after(p, 0, fmt.sdr.buffersize); 1765582c52cbSAntti Palosaari return ops->vidioc_s_fmt_sdr_cap(file, fh, arg); 17669effc72fSAntti Palosaari case V4L2_BUF_TYPE_SDR_OUTPUT: 1767b2469c81SHans Verkuil if (unlikely(!ops->vidioc_s_fmt_sdr_out)) 17689effc72fSAntti Palosaari break; 17690625b6b8SXiu Jianfeng memset_after(p, 0, fmt.sdr.buffersize); 17709effc72fSAntti Palosaari return ops->vidioc_s_fmt_sdr_out(file, fh, arg); 1771fb9ffa6aSLaurent Pinchart case V4L2_BUF_TYPE_META_CAPTURE: 1772b2469c81SHans Verkuil if (unlikely(!ops->vidioc_s_fmt_meta_cap)) 1773fb9ffa6aSLaurent Pinchart break; 17740625b6b8SXiu Jianfeng memset_after(p, 0, fmt.meta); 1775fb9ffa6aSLaurent Pinchart return ops->vidioc_s_fmt_meta_cap(file, fh, arg); 177672148d1aSSakari Ailus case V4L2_BUF_TYPE_META_OUTPUT: 177772148d1aSSakari Ailus if (unlikely(!ops->vidioc_s_fmt_meta_out)) 177872148d1aSSakari Ailus break; 17790625b6b8SXiu Jianfeng memset_after(p, 0, fmt.meta); 178072148d1aSSakari Ailus return ops->vidioc_s_fmt_meta_out(file, fh, arg); 17815bc3cb74SMauro Carvalho Chehab } 17825bc3cb74SMauro Carvalho Chehab return -EINVAL; 17835bc3cb74SMauro Carvalho Chehab } 17845bc3cb74SMauro Carvalho Chehab 17855bc3cb74SMauro Carvalho Chehab static int v4l_try_fmt(const struct v4l2_ioctl_ops *ops, 17865bc3cb74SMauro Carvalho Chehab struct file *file, void *fh, void *arg) 17875bc3cb74SMauro Carvalho Chehab { 17885bc3cb74SMauro Carvalho Chehab struct v4l2_format *p = arg; 1789999a4312SHans Verkuil struct video_device *vfd = video_devdata(file); 1790b2469c81SHans Verkuil int ret = check_fmt(file, p->type); 17914e1e0eb0SEzequiel Garcia unsigned int i; 1792b2469c81SHans Verkuil 1793b2469c81SHans Verkuil if (ret) 1794b2469c81SHans Verkuil return ret; 17955bc3cb74SMauro Carvalho Chehab 1796d52e2381SLaurent Pinchart v4l_sanitize_format(p); 1797d52e2381SLaurent Pinchart 17985bc3cb74SMauro Carvalho Chehab switch (p->type) { 17995bc3cb74SMauro Carvalho Chehab case V4L2_BUF_TYPE_VIDEO_CAPTURE: 1800b2469c81SHans Verkuil if (unlikely(!ops->vidioc_try_fmt_vid_cap)) 18015bc3cb74SMauro Carvalho Chehab break; 18020625b6b8SXiu Jianfeng memset_after(p, 0, fmt.pix); 180348f2650aSHans Verkuil ret = ops->vidioc_try_fmt_vid_cap(file, fh, arg); 180448f2650aSHans Verkuil /* just in case the driver zeroed it again */ 180548f2650aSHans Verkuil p->fmt.pix.priv = V4L2_PIX_FMT_PRIV_MAGIC; 1806999a4312SHans Verkuil if (vfd->vfl_type == VFL_TYPE_TOUCH) 1807999a4312SHans Verkuil v4l_pix_format_touch(&p->fmt.pix); 180848f2650aSHans Verkuil return ret; 18095bc3cb74SMauro Carvalho Chehab case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE: 1810b2469c81SHans Verkuil if (unlikely(!ops->vidioc_try_fmt_vid_cap_mplane)) 18115bc3cb74SMauro Carvalho Chehab break; 18120625b6b8SXiu Jianfeng memset_after(p, 0, fmt.pix_mp.xfer_func); 18134e1e0eb0SEzequiel Garcia for (i = 0; i < p->fmt.pix_mp.num_planes; i++) 18140625b6b8SXiu Jianfeng memset_after(&p->fmt.pix_mp.plane_fmt[i], 18150625b6b8SXiu Jianfeng 0, bytesperline); 18165bc3cb74SMauro Carvalho Chehab return ops->vidioc_try_fmt_vid_cap_mplane(file, fh, arg); 18175bc3cb74SMauro Carvalho Chehab case V4L2_BUF_TYPE_VIDEO_OVERLAY: 1818b2469c81SHans Verkuil if (unlikely(!ops->vidioc_try_fmt_vid_overlay)) 18195bc3cb74SMauro Carvalho Chehab break; 18200625b6b8SXiu Jianfeng memset_after(p, 0, fmt.win); 182199ba0703SHans Verkuil p->fmt.win.clips = NULL; 182299ba0703SHans Verkuil p->fmt.win.clipcount = 0; 182399ba0703SHans Verkuil p->fmt.win.bitmap = NULL; 18245bc3cb74SMauro Carvalho Chehab return ops->vidioc_try_fmt_vid_overlay(file, fh, arg); 18254b20259fSHans Verkuil case V4L2_BUF_TYPE_VBI_CAPTURE: 1826b2469c81SHans Verkuil if (unlikely(!ops->vidioc_try_fmt_vbi_cap)) 18274b20259fSHans Verkuil break; 18280625b6b8SXiu Jianfeng memset_after(p, 0, fmt.vbi.flags); 18294b20259fSHans Verkuil return ops->vidioc_try_fmt_vbi_cap(file, fh, arg); 18304b20259fSHans Verkuil case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE: 1831b2469c81SHans Verkuil if (unlikely(!ops->vidioc_try_fmt_sliced_vbi_cap)) 18324b20259fSHans Verkuil break; 18330625b6b8SXiu Jianfeng memset_after(p, 0, fmt.sliced.io_size); 18344b20259fSHans Verkuil return ops->vidioc_try_fmt_sliced_vbi_cap(file, fh, arg); 18355bc3cb74SMauro Carvalho Chehab case V4L2_BUF_TYPE_VIDEO_OUTPUT: 1836b2469c81SHans Verkuil if (unlikely(!ops->vidioc_try_fmt_vid_out)) 18375bc3cb74SMauro Carvalho Chehab break; 18380625b6b8SXiu Jianfeng memset_after(p, 0, fmt.pix); 183948f2650aSHans Verkuil ret = ops->vidioc_try_fmt_vid_out(file, fh, arg); 184048f2650aSHans Verkuil /* just in case the driver zeroed it again */ 184148f2650aSHans Verkuil p->fmt.pix.priv = V4L2_PIX_FMT_PRIV_MAGIC; 184248f2650aSHans Verkuil return ret; 18435bc3cb74SMauro Carvalho Chehab case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE: 1844b2469c81SHans Verkuil if (unlikely(!ops->vidioc_try_fmt_vid_out_mplane)) 18455bc3cb74SMauro Carvalho Chehab break; 18460625b6b8SXiu Jianfeng memset_after(p, 0, fmt.pix_mp.xfer_func); 18474e1e0eb0SEzequiel Garcia for (i = 0; i < p->fmt.pix_mp.num_planes; i++) 18480625b6b8SXiu Jianfeng memset_after(&p->fmt.pix_mp.plane_fmt[i], 18490625b6b8SXiu Jianfeng 0, bytesperline); 18505bc3cb74SMauro Carvalho Chehab return ops->vidioc_try_fmt_vid_out_mplane(file, fh, arg); 18515bc3cb74SMauro Carvalho Chehab case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY: 1852b2469c81SHans Verkuil if (unlikely(!ops->vidioc_try_fmt_vid_out_overlay)) 18535bc3cb74SMauro Carvalho Chehab break; 18540625b6b8SXiu Jianfeng memset_after(p, 0, fmt.win); 185599ba0703SHans Verkuil p->fmt.win.clips = NULL; 185699ba0703SHans Verkuil p->fmt.win.clipcount = 0; 185799ba0703SHans Verkuil p->fmt.win.bitmap = NULL; 18585bc3cb74SMauro Carvalho Chehab return ops->vidioc_try_fmt_vid_out_overlay(file, fh, arg); 18595bc3cb74SMauro Carvalho Chehab case V4L2_BUF_TYPE_VBI_OUTPUT: 1860b2469c81SHans Verkuil if (unlikely(!ops->vidioc_try_fmt_vbi_out)) 18615bc3cb74SMauro Carvalho Chehab break; 18620625b6b8SXiu Jianfeng memset_after(p, 0, fmt.vbi.flags); 18635bc3cb74SMauro Carvalho Chehab return ops->vidioc_try_fmt_vbi_out(file, fh, arg); 18645bc3cb74SMauro Carvalho Chehab case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT: 1865b2469c81SHans Verkuil if (unlikely(!ops->vidioc_try_fmt_sliced_vbi_out)) 18665bc3cb74SMauro Carvalho Chehab break; 18670625b6b8SXiu Jianfeng memset_after(p, 0, fmt.sliced.io_size); 18685bc3cb74SMauro Carvalho Chehab return ops->vidioc_try_fmt_sliced_vbi_out(file, fh, arg); 1869582c52cbSAntti Palosaari case V4L2_BUF_TYPE_SDR_CAPTURE: 1870b2469c81SHans Verkuil if (unlikely(!ops->vidioc_try_fmt_sdr_cap)) 1871582c52cbSAntti Palosaari break; 18720625b6b8SXiu Jianfeng memset_after(p, 0, fmt.sdr.buffersize); 1873582c52cbSAntti Palosaari return ops->vidioc_try_fmt_sdr_cap(file, fh, arg); 18749effc72fSAntti Palosaari case V4L2_BUF_TYPE_SDR_OUTPUT: 1875b2469c81SHans Verkuil if (unlikely(!ops->vidioc_try_fmt_sdr_out)) 18769effc72fSAntti Palosaari break; 18770625b6b8SXiu Jianfeng memset_after(p, 0, fmt.sdr.buffersize); 18789effc72fSAntti Palosaari return ops->vidioc_try_fmt_sdr_out(file, fh, arg); 1879fb9ffa6aSLaurent Pinchart case V4L2_BUF_TYPE_META_CAPTURE: 1880b2469c81SHans Verkuil if (unlikely(!ops->vidioc_try_fmt_meta_cap)) 1881fb9ffa6aSLaurent Pinchart break; 18820625b6b8SXiu Jianfeng memset_after(p, 0, fmt.meta); 1883fb9ffa6aSLaurent Pinchart return ops->vidioc_try_fmt_meta_cap(file, fh, arg); 188472148d1aSSakari Ailus case V4L2_BUF_TYPE_META_OUTPUT: 188572148d1aSSakari Ailus if (unlikely(!ops->vidioc_try_fmt_meta_out)) 188672148d1aSSakari Ailus break; 18870625b6b8SXiu Jianfeng memset_after(p, 0, fmt.meta); 188872148d1aSSakari Ailus return ops->vidioc_try_fmt_meta_out(file, fh, arg); 18895bc3cb74SMauro Carvalho Chehab } 18905bc3cb74SMauro Carvalho Chehab return -EINVAL; 18915bc3cb74SMauro Carvalho Chehab } 18925bc3cb74SMauro Carvalho Chehab 18935bc3cb74SMauro Carvalho Chehab static int v4l_streamon(const struct v4l2_ioctl_ops *ops, 18945bc3cb74SMauro Carvalho Chehab struct file *file, void *fh, void *arg) 18955bc3cb74SMauro Carvalho Chehab { 18965bc3cb74SMauro Carvalho Chehab return ops->vidioc_streamon(file, fh, *(unsigned int *)arg); 18975bc3cb74SMauro Carvalho Chehab } 18985bc3cb74SMauro Carvalho Chehab 18995bc3cb74SMauro Carvalho Chehab static int v4l_streamoff(const struct v4l2_ioctl_ops *ops, 19005bc3cb74SMauro Carvalho Chehab struct file *file, void *fh, void *arg) 19015bc3cb74SMauro Carvalho Chehab { 19025bc3cb74SMauro Carvalho Chehab return ops->vidioc_streamoff(file, fh, *(unsigned int *)arg); 19035bc3cb74SMauro Carvalho Chehab } 19045bc3cb74SMauro Carvalho Chehab 19055bc3cb74SMauro Carvalho Chehab static int v4l_g_tuner(const struct v4l2_ioctl_ops *ops, 19065bc3cb74SMauro Carvalho Chehab struct file *file, void *fh, void *arg) 19075bc3cb74SMauro Carvalho Chehab { 19085bc3cb74SMauro Carvalho Chehab struct video_device *vfd = video_devdata(file); 19095bc3cb74SMauro Carvalho Chehab struct v4l2_tuner *p = arg; 19105bc3cb74SMauro Carvalho Chehab int err; 19115bc3cb74SMauro Carvalho Chehab 19125bc3cb74SMauro Carvalho Chehab p->type = (vfd->vfl_type == VFL_TYPE_RADIO) ? 19135bc3cb74SMauro Carvalho Chehab V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV; 19145bc3cb74SMauro Carvalho Chehab err = ops->vidioc_g_tuner(file, fh, p); 19155bc3cb74SMauro Carvalho Chehab if (!err) 19165bc3cb74SMauro Carvalho Chehab p->capability |= V4L2_TUNER_CAP_FREQ_BANDS; 19175bc3cb74SMauro Carvalho Chehab return err; 19185bc3cb74SMauro Carvalho Chehab } 19195bc3cb74SMauro Carvalho Chehab 19205bc3cb74SMauro Carvalho Chehab static int v4l_s_tuner(const struct v4l2_ioctl_ops *ops, 19215bc3cb74SMauro Carvalho Chehab struct file *file, void *fh, void *arg) 19225bc3cb74SMauro Carvalho Chehab { 19235bc3cb74SMauro Carvalho Chehab struct video_device *vfd = video_devdata(file); 19245bc3cb74SMauro Carvalho Chehab struct v4l2_tuner *p = arg; 192577fa4e07SShuah Khan int ret; 19265bc3cb74SMauro Carvalho Chehab 192777fa4e07SShuah Khan ret = v4l_enable_media_source(vfd); 192877fa4e07SShuah Khan if (ret) 192977fa4e07SShuah Khan return ret; 19305bc3cb74SMauro Carvalho Chehab p->type = (vfd->vfl_type == VFL_TYPE_RADIO) ? 19315bc3cb74SMauro Carvalho Chehab V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV; 19325bc3cb74SMauro Carvalho Chehab return ops->vidioc_s_tuner(file, fh, p); 19335bc3cb74SMauro Carvalho Chehab } 19345bc3cb74SMauro Carvalho Chehab 19355bc3cb74SMauro Carvalho Chehab static int v4l_g_modulator(const struct v4l2_ioctl_ops *ops, 19365bc3cb74SMauro Carvalho Chehab struct file *file, void *fh, void *arg) 19375bc3cb74SMauro Carvalho Chehab { 19384124a3c4SAntti Palosaari struct video_device *vfd = video_devdata(file); 19395bc3cb74SMauro Carvalho Chehab struct v4l2_modulator *p = arg; 19405bc3cb74SMauro Carvalho Chehab int err; 19415bc3cb74SMauro Carvalho Chehab 19424124a3c4SAntti Palosaari if (vfd->vfl_type == VFL_TYPE_RADIO) 19434124a3c4SAntti Palosaari p->type = V4L2_TUNER_RADIO; 19444124a3c4SAntti Palosaari 19455bc3cb74SMauro Carvalho Chehab err = ops->vidioc_g_modulator(file, fh, p); 19465bc3cb74SMauro Carvalho Chehab if (!err) 19475bc3cb74SMauro Carvalho Chehab p->capability |= V4L2_TUNER_CAP_FREQ_BANDS; 19485bc3cb74SMauro Carvalho Chehab return err; 19495bc3cb74SMauro Carvalho Chehab } 19505bc3cb74SMauro Carvalho Chehab 19514124a3c4SAntti Palosaari static int v4l_s_modulator(const struct v4l2_ioctl_ops *ops, 19524124a3c4SAntti Palosaari struct file *file, void *fh, void *arg) 19534124a3c4SAntti Palosaari { 19544124a3c4SAntti Palosaari struct video_device *vfd = video_devdata(file); 19554124a3c4SAntti Palosaari struct v4l2_modulator *p = arg; 19564124a3c4SAntti Palosaari 19574124a3c4SAntti Palosaari if (vfd->vfl_type == VFL_TYPE_RADIO) 19584124a3c4SAntti Palosaari p->type = V4L2_TUNER_RADIO; 19594124a3c4SAntti Palosaari 19604124a3c4SAntti Palosaari return ops->vidioc_s_modulator(file, fh, p); 19614124a3c4SAntti Palosaari } 19624124a3c4SAntti Palosaari 19635bc3cb74SMauro Carvalho Chehab static int v4l_g_frequency(const struct v4l2_ioctl_ops *ops, 19645bc3cb74SMauro Carvalho Chehab struct file *file, void *fh, void *arg) 19655bc3cb74SMauro Carvalho Chehab { 19665bc3cb74SMauro Carvalho Chehab struct video_device *vfd = video_devdata(file); 19675bc3cb74SMauro Carvalho Chehab struct v4l2_frequency *p = arg; 19685bc3cb74SMauro Carvalho Chehab 196984099a28SAntti Palosaari if (vfd->vfl_type == VFL_TYPE_SDR) 1970f3c3ececSAntti Palosaari p->type = V4L2_TUNER_SDR; 197184099a28SAntti Palosaari else 19725bc3cb74SMauro Carvalho Chehab p->type = (vfd->vfl_type == VFL_TYPE_RADIO) ? 19735bc3cb74SMauro Carvalho Chehab V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV; 19745bc3cb74SMauro Carvalho Chehab return ops->vidioc_g_frequency(file, fh, p); 19755bc3cb74SMauro Carvalho Chehab } 19765bc3cb74SMauro Carvalho Chehab 19775bc3cb74SMauro Carvalho Chehab static int v4l_s_frequency(const struct v4l2_ioctl_ops *ops, 19785bc3cb74SMauro Carvalho Chehab struct file *file, void *fh, void *arg) 19795bc3cb74SMauro Carvalho Chehab { 19805bc3cb74SMauro Carvalho Chehab struct video_device *vfd = video_devdata(file); 1981b530a447SHans Verkuil const struct v4l2_frequency *p = arg; 19825bc3cb74SMauro Carvalho Chehab enum v4l2_tuner_type type; 198377fa4e07SShuah Khan int ret; 19845bc3cb74SMauro Carvalho Chehab 198577fa4e07SShuah Khan ret = v4l_enable_media_source(vfd); 198677fa4e07SShuah Khan if (ret) 198777fa4e07SShuah Khan return ret; 198884099a28SAntti Palosaari if (vfd->vfl_type == VFL_TYPE_SDR) { 1989f3c3ececSAntti Palosaari if (p->type != V4L2_TUNER_SDR && p->type != V4L2_TUNER_RF) 199084099a28SAntti Palosaari return -EINVAL; 199184099a28SAntti Palosaari } else { 19925bc3cb74SMauro Carvalho Chehab type = (vfd->vfl_type == VFL_TYPE_RADIO) ? 19935bc3cb74SMauro Carvalho Chehab V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV; 199484099a28SAntti Palosaari if (type != p->type) 19955bc3cb74SMauro Carvalho Chehab return -EINVAL; 199684099a28SAntti Palosaari } 19975bc3cb74SMauro Carvalho Chehab return ops->vidioc_s_frequency(file, fh, p); 19985bc3cb74SMauro Carvalho Chehab } 19995bc3cb74SMauro Carvalho Chehab 20005bc3cb74SMauro Carvalho Chehab static int v4l_enumstd(const struct v4l2_ioctl_ops *ops, 20015bc3cb74SMauro Carvalho Chehab struct file *file, void *fh, void *arg) 20025bc3cb74SMauro Carvalho Chehab { 20035bc3cb74SMauro Carvalho Chehab struct video_device *vfd = video_devdata(file); 20045bc3cb74SMauro Carvalho Chehab struct v4l2_standard *p = arg; 20055bc3cb74SMauro Carvalho Chehab 2006aa2f8871SNiklas Söderlund return v4l_video_std_enumstd(p, vfd->tvnorms); 20075bc3cb74SMauro Carvalho Chehab } 20085bc3cb74SMauro Carvalho Chehab 20095bc3cb74SMauro Carvalho Chehab static int v4l_s_std(const struct v4l2_ioctl_ops *ops, 20105bc3cb74SMauro Carvalho Chehab struct file *file, void *fh, void *arg) 20115bc3cb74SMauro Carvalho Chehab { 20125bc3cb74SMauro Carvalho Chehab struct video_device *vfd = video_devdata(file); 2013314527acSHans Verkuil v4l2_std_id id = *(v4l2_std_id *)arg, norm; 201477fa4e07SShuah Khan int ret; 20155bc3cb74SMauro Carvalho Chehab 201677fa4e07SShuah Khan ret = v4l_enable_media_source(vfd); 201777fa4e07SShuah Khan if (ret) 201877fa4e07SShuah Khan return ret; 2019314527acSHans Verkuil norm = id & vfd->tvnorms; 20205bc3cb74SMauro Carvalho Chehab if (vfd->tvnorms && !norm) /* Check if std is supported */ 20215bc3cb74SMauro Carvalho Chehab return -EINVAL; 20225bc3cb74SMauro Carvalho Chehab 20235bc3cb74SMauro Carvalho Chehab /* Calls the specific handler */ 2024ca371575SHans Verkuil return ops->vidioc_s_std(file, fh, norm); 20255bc3cb74SMauro Carvalho Chehab } 20265bc3cb74SMauro Carvalho Chehab 20275bc3cb74SMauro Carvalho Chehab static int v4l_querystd(const struct v4l2_ioctl_ops *ops, 20285bc3cb74SMauro Carvalho Chehab struct file *file, void *fh, void *arg) 20295bc3cb74SMauro Carvalho Chehab { 20305bc3cb74SMauro Carvalho Chehab struct video_device *vfd = video_devdata(file); 20315bc3cb74SMauro Carvalho Chehab v4l2_std_id *p = arg; 203277fa4e07SShuah Khan int ret; 20335bc3cb74SMauro Carvalho Chehab 203477fa4e07SShuah Khan ret = v4l_enable_media_source(vfd); 203577fa4e07SShuah Khan if (ret) 203677fa4e07SShuah Khan return ret; 20375bc3cb74SMauro Carvalho Chehab /* 20381a2c6866SHans Verkuil * If no signal is detected, then the driver should return 20391a2c6866SHans Verkuil * V4L2_STD_UNKNOWN. Otherwise it should return tvnorms with 20401a2c6866SHans Verkuil * any standards that do not apply removed. 20411a2c6866SHans Verkuil * 20425bc3cb74SMauro Carvalho Chehab * This means that tuners, audio and video decoders can join 20435bc3cb74SMauro Carvalho Chehab * their efforts to improve the standards detection. 20445bc3cb74SMauro Carvalho Chehab */ 20455bc3cb74SMauro Carvalho Chehab *p = vfd->tvnorms; 20465bc3cb74SMauro Carvalho Chehab return ops->vidioc_querystd(file, fh, arg); 20475bc3cb74SMauro Carvalho Chehab } 20485bc3cb74SMauro Carvalho Chehab 20495bc3cb74SMauro Carvalho Chehab static int v4l_s_hw_freq_seek(const struct v4l2_ioctl_ops *ops, 20505bc3cb74SMauro Carvalho Chehab struct file *file, void *fh, void *arg) 20515bc3cb74SMauro Carvalho Chehab { 20525bc3cb74SMauro Carvalho Chehab struct video_device *vfd = video_devdata(file); 20535bc3cb74SMauro Carvalho Chehab struct v4l2_hw_freq_seek *p = arg; 20545bc3cb74SMauro Carvalho Chehab enum v4l2_tuner_type type; 205577fa4e07SShuah Khan int ret; 20565bc3cb74SMauro Carvalho Chehab 205777fa4e07SShuah Khan ret = v4l_enable_media_source(vfd); 205877fa4e07SShuah Khan if (ret) 205977fa4e07SShuah Khan return ret; 206084099a28SAntti Palosaari /* s_hw_freq_seek is not supported for SDR for now */ 206184099a28SAntti Palosaari if (vfd->vfl_type == VFL_TYPE_SDR) 206284099a28SAntti Palosaari return -EINVAL; 206384099a28SAntti Palosaari 20645bc3cb74SMauro Carvalho Chehab type = (vfd->vfl_type == VFL_TYPE_RADIO) ? 20655bc3cb74SMauro Carvalho Chehab V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV; 20665bc3cb74SMauro Carvalho Chehab if (p->type != type) 20675bc3cb74SMauro Carvalho Chehab return -EINVAL; 20685bc3cb74SMauro Carvalho Chehab return ops->vidioc_s_hw_freq_seek(file, fh, p); 20695bc3cb74SMauro Carvalho Chehab } 20705bc3cb74SMauro Carvalho Chehab 2071d04794daSHans Verkuil static int v4l_s_fbuf(const struct v4l2_ioctl_ops *ops, 2072d04794daSHans Verkuil struct file *file, void *fh, void *arg) 2073d04794daSHans Verkuil { 2074d04794daSHans Verkuil struct v4l2_framebuffer *p = arg; 2075d04794daSHans Verkuil 2076d04794daSHans Verkuil p->base = NULL; 2077d04794daSHans Verkuil return ops->vidioc_s_fbuf(file, fh, p); 2078d04794daSHans Verkuil } 2079d04794daSHans Verkuil 2080737c097bSHans Verkuil static int v4l_overlay(const struct v4l2_ioctl_ops *ops, 2081737c097bSHans Verkuil struct file *file, void *fh, void *arg) 2082737c097bSHans Verkuil { 2083737c097bSHans Verkuil return ops->vidioc_overlay(file, fh, *(unsigned int *)arg); 2084737c097bSHans Verkuil } 2085737c097bSHans Verkuil 20865bc3cb74SMauro Carvalho Chehab static int v4l_reqbufs(const struct v4l2_ioctl_ops *ops, 20875bc3cb74SMauro Carvalho Chehab struct file *file, void *fh, void *arg) 20885bc3cb74SMauro Carvalho Chehab { 20895bc3cb74SMauro Carvalho Chehab struct v4l2_requestbuffers *p = arg; 20904b20259fSHans Verkuil int ret = check_fmt(file, p->type); 20915bc3cb74SMauro Carvalho Chehab 20925bc3cb74SMauro Carvalho Chehab if (ret) 20935bc3cb74SMauro Carvalho Chehab return ret; 2094129134e5SSergey Senozhatsky 20950625b6b8SXiu Jianfeng memset_after(p, 0, flags); 2096129134e5SSergey Senozhatsky 20975bc3cb74SMauro Carvalho Chehab return ops->vidioc_reqbufs(file, fh, p); 20985bc3cb74SMauro Carvalho Chehab } 20995bc3cb74SMauro Carvalho Chehab 21005bc3cb74SMauro Carvalho Chehab static int v4l_querybuf(const struct v4l2_ioctl_ops *ops, 21015bc3cb74SMauro Carvalho Chehab struct file *file, void *fh, void *arg) 21025bc3cb74SMauro Carvalho Chehab { 21035bc3cb74SMauro Carvalho Chehab struct v4l2_buffer *p = arg; 21044b20259fSHans Verkuil int ret = check_fmt(file, p->type); 21055bc3cb74SMauro Carvalho Chehab 21065bc3cb74SMauro Carvalho Chehab return ret ? ret : ops->vidioc_querybuf(file, fh, p); 21075bc3cb74SMauro Carvalho Chehab } 21085bc3cb74SMauro Carvalho Chehab 21095bc3cb74SMauro Carvalho Chehab static int v4l_qbuf(const struct v4l2_ioctl_ops *ops, 21105bc3cb74SMauro Carvalho Chehab struct file *file, void *fh, void *arg) 21115bc3cb74SMauro Carvalho Chehab { 21125bc3cb74SMauro Carvalho Chehab struct v4l2_buffer *p = arg; 21134b20259fSHans Verkuil int ret = check_fmt(file, p->type); 21145bc3cb74SMauro Carvalho Chehab 21155bc3cb74SMauro Carvalho Chehab return ret ? ret : ops->vidioc_qbuf(file, fh, p); 21165bc3cb74SMauro Carvalho Chehab } 21175bc3cb74SMauro Carvalho Chehab 21185bc3cb74SMauro Carvalho Chehab static int v4l_dqbuf(const struct v4l2_ioctl_ops *ops, 21195bc3cb74SMauro Carvalho Chehab struct file *file, void *fh, void *arg) 21205bc3cb74SMauro Carvalho Chehab { 21215bc3cb74SMauro Carvalho Chehab struct v4l2_buffer *p = arg; 21224b20259fSHans Verkuil int ret = check_fmt(file, p->type); 21235bc3cb74SMauro Carvalho Chehab 21245bc3cb74SMauro Carvalho Chehab return ret ? ret : ops->vidioc_dqbuf(file, fh, p); 21255bc3cb74SMauro Carvalho Chehab } 21265bc3cb74SMauro Carvalho Chehab 21275bc3cb74SMauro Carvalho Chehab static int v4l_create_bufs(const struct v4l2_ioctl_ops *ops, 21285bc3cb74SMauro Carvalho Chehab struct file *file, void *fh, void *arg) 21295bc3cb74SMauro Carvalho Chehab { 21305bc3cb74SMauro Carvalho Chehab struct v4l2_create_buffers *create = arg; 21314b20259fSHans Verkuil int ret = check_fmt(file, create->format.type); 21325bc3cb74SMauro Carvalho Chehab 2133d52e2381SLaurent Pinchart if (ret) 2134d52e2381SLaurent Pinchart return ret; 2135d52e2381SLaurent Pinchart 21360625b6b8SXiu Jianfeng memset_after(create, 0, flags); 21375d351251SHans Verkuil 2138d52e2381SLaurent Pinchart v4l_sanitize_format(&create->format); 2139d52e2381SLaurent Pinchart 2140d52e2381SLaurent Pinchart ret = ops->vidioc_create_bufs(file, fh, create); 2141d52e2381SLaurent Pinchart 2142d52e2381SLaurent Pinchart if (create->format.type == V4L2_BUF_TYPE_VIDEO_CAPTURE || 2143d52e2381SLaurent Pinchart create->format.type == V4L2_BUF_TYPE_VIDEO_OUTPUT) 2144d52e2381SLaurent Pinchart create->format.fmt.pix.priv = V4L2_PIX_FMT_PRIV_MAGIC; 2145d52e2381SLaurent Pinchart 2146d52e2381SLaurent Pinchart return ret; 21475bc3cb74SMauro Carvalho Chehab } 21485bc3cb74SMauro Carvalho Chehab 21495bc3cb74SMauro Carvalho Chehab static int v4l_prepare_buf(const struct v4l2_ioctl_ops *ops, 21505bc3cb74SMauro Carvalho Chehab struct file *file, void *fh, void *arg) 21515bc3cb74SMauro Carvalho Chehab { 21525bc3cb74SMauro Carvalho Chehab struct v4l2_buffer *b = arg; 21534b20259fSHans Verkuil int ret = check_fmt(file, b->type); 21545bc3cb74SMauro Carvalho Chehab 21555bc3cb74SMauro Carvalho Chehab return ret ? ret : ops->vidioc_prepare_buf(file, fh, b); 21565bc3cb74SMauro Carvalho Chehab } 21575bc3cb74SMauro Carvalho Chehab 21585bc3cb74SMauro Carvalho Chehab static int v4l_g_parm(const struct v4l2_ioctl_ops *ops, 21595bc3cb74SMauro Carvalho Chehab struct file *file, void *fh, void *arg) 21605bc3cb74SMauro Carvalho Chehab { 2161cd9d9377SHans Verkuil struct video_device *vfd = video_devdata(file); 21625bc3cb74SMauro Carvalho Chehab struct v4l2_streamparm *p = arg; 21635bc3cb74SMauro Carvalho Chehab v4l2_std_id std; 21644b20259fSHans Verkuil int ret = check_fmt(file, p->type); 21655bc3cb74SMauro Carvalho Chehab 21665bc3cb74SMauro Carvalho Chehab if (ret) 21675bc3cb74SMauro Carvalho Chehab return ret; 21685bc3cb74SMauro Carvalho Chehab if (ops->vidioc_g_parm) 21695bc3cb74SMauro Carvalho Chehab return ops->vidioc_g_parm(file, fh, p); 21705bc3cb74SMauro Carvalho Chehab if (p->type != V4L2_BUF_TYPE_VIDEO_CAPTURE && 21715bc3cb74SMauro Carvalho Chehab p->type != V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) 21725bc3cb74SMauro Carvalho Chehab return -EINVAL; 2173cd9d9377SHans Verkuil if (vfd->device_caps & V4L2_CAP_READWRITE) 21745bc3cb74SMauro Carvalho Chehab p->parm.capture.readbuffers = 2; 21755bc3cb74SMauro Carvalho Chehab ret = ops->vidioc_g_std(file, fh, &std); 21765bc3cb74SMauro Carvalho Chehab if (ret == 0) 2177ca371575SHans Verkuil v4l2_video_std_frame_period(std, &p->parm.capture.timeperframe); 21785bc3cb74SMauro Carvalho Chehab return ret; 21795bc3cb74SMauro Carvalho Chehab } 21805bc3cb74SMauro Carvalho Chehab 21815bc3cb74SMauro Carvalho Chehab static int v4l_s_parm(const struct v4l2_ioctl_ops *ops, 21825bc3cb74SMauro Carvalho Chehab struct file *file, void *fh, void *arg) 21835bc3cb74SMauro Carvalho Chehab { 21845bc3cb74SMauro Carvalho Chehab struct v4l2_streamparm *p = arg; 21854b20259fSHans Verkuil int ret = check_fmt(file, p->type); 21865bc3cb74SMauro Carvalho Chehab 21878a7c5594SHans Verkuil if (ret) 21888a7c5594SHans Verkuil return ret; 21898a7c5594SHans Verkuil 21904f62e840SHans Verkuil /* Note: extendedmode is never used in drivers */ 21918a7c5594SHans Verkuil if (V4L2_TYPE_IS_OUTPUT(p->type)) { 21928a7c5594SHans Verkuil memset(p->parm.output.reserved, 0, 21938a7c5594SHans Verkuil sizeof(p->parm.output.reserved)); 21948a7c5594SHans Verkuil p->parm.output.extendedmode = 0; 21958a7c5594SHans Verkuil p->parm.output.outputmode &= V4L2_MODE_HIGHQUALITY; 21968a7c5594SHans Verkuil } else { 21978a7c5594SHans Verkuil memset(p->parm.capture.reserved, 0, 21988a7c5594SHans Verkuil sizeof(p->parm.capture.reserved)); 21994f62e840SHans Verkuil p->parm.capture.extendedmode = 0; 22008a7c5594SHans Verkuil p->parm.capture.capturemode &= V4L2_MODE_HIGHQUALITY; 22018a7c5594SHans Verkuil } 22028a7c5594SHans Verkuil return ops->vidioc_s_parm(file, fh, p); 22035bc3cb74SMauro Carvalho Chehab } 22045bc3cb74SMauro Carvalho Chehab 22055bc3cb74SMauro Carvalho Chehab static int v4l_queryctrl(const struct v4l2_ioctl_ops *ops, 22065bc3cb74SMauro Carvalho Chehab struct file *file, void *fh, void *arg) 22075bc3cb74SMauro Carvalho Chehab { 22085bc3cb74SMauro Carvalho Chehab struct video_device *vfd = video_devdata(file); 22095bc3cb74SMauro Carvalho Chehab struct v4l2_queryctrl *p = arg; 22105bc3cb74SMauro Carvalho Chehab struct v4l2_fh *vfh = 22115bc3cb74SMauro Carvalho Chehab test_bit(V4L2_FL_USES_V4L2_FH, &vfd->flags) ? fh : NULL; 22125bc3cb74SMauro Carvalho Chehab 22135bc3cb74SMauro Carvalho Chehab if (vfh && vfh->ctrl_handler) 22145bc3cb74SMauro Carvalho Chehab return v4l2_queryctrl(vfh->ctrl_handler, p); 22155bc3cb74SMauro Carvalho Chehab if (vfd->ctrl_handler) 22165bc3cb74SMauro Carvalho Chehab return v4l2_queryctrl(vfd->ctrl_handler, p); 22175bc3cb74SMauro Carvalho Chehab if (ops->vidioc_queryctrl) 22185bc3cb74SMauro Carvalho Chehab return ops->vidioc_queryctrl(file, fh, p); 22195bc3cb74SMauro Carvalho Chehab return -ENOTTY; 22205bc3cb74SMauro Carvalho Chehab } 22215bc3cb74SMauro Carvalho Chehab 2222e6bee368SHans Verkuil static int v4l_query_ext_ctrl(const struct v4l2_ioctl_ops *ops, 2223e6bee368SHans Verkuil struct file *file, void *fh, void *arg) 2224e6bee368SHans Verkuil { 2225e6bee368SHans Verkuil struct video_device *vfd = video_devdata(file); 2226e6bee368SHans Verkuil struct v4l2_query_ext_ctrl *p = arg; 2227e6bee368SHans Verkuil struct v4l2_fh *vfh = 2228e6bee368SHans Verkuil test_bit(V4L2_FL_USES_V4L2_FH, &vfd->flags) ? fh : NULL; 2229e6bee368SHans Verkuil 2230e6bee368SHans Verkuil if (vfh && vfh->ctrl_handler) 2231e6bee368SHans Verkuil return v4l2_query_ext_ctrl(vfh->ctrl_handler, p); 2232e6bee368SHans Verkuil if (vfd->ctrl_handler) 2233e6bee368SHans Verkuil return v4l2_query_ext_ctrl(vfd->ctrl_handler, p); 2234e6bee368SHans Verkuil if (ops->vidioc_query_ext_ctrl) 2235e6bee368SHans Verkuil return ops->vidioc_query_ext_ctrl(file, fh, p); 2236e6bee368SHans Verkuil return -ENOTTY; 2237e6bee368SHans Verkuil } 2238e6bee368SHans Verkuil 22395bc3cb74SMauro Carvalho Chehab static int v4l_querymenu(const struct v4l2_ioctl_ops *ops, 22405bc3cb74SMauro Carvalho Chehab struct file *file, void *fh, void *arg) 22415bc3cb74SMauro Carvalho Chehab { 22425bc3cb74SMauro Carvalho Chehab struct video_device *vfd = video_devdata(file); 22435bc3cb74SMauro Carvalho Chehab struct v4l2_querymenu *p = arg; 22445bc3cb74SMauro Carvalho Chehab struct v4l2_fh *vfh = 22455bc3cb74SMauro Carvalho Chehab test_bit(V4L2_FL_USES_V4L2_FH, &vfd->flags) ? fh : NULL; 22465bc3cb74SMauro Carvalho Chehab 22475bc3cb74SMauro Carvalho Chehab if (vfh && vfh->ctrl_handler) 22485bc3cb74SMauro Carvalho Chehab return v4l2_querymenu(vfh->ctrl_handler, p); 22495bc3cb74SMauro Carvalho Chehab if (vfd->ctrl_handler) 22505bc3cb74SMauro Carvalho Chehab return v4l2_querymenu(vfd->ctrl_handler, p); 22515bc3cb74SMauro Carvalho Chehab if (ops->vidioc_querymenu) 22525bc3cb74SMauro Carvalho Chehab return ops->vidioc_querymenu(file, fh, p); 22535bc3cb74SMauro Carvalho Chehab return -ENOTTY; 22545bc3cb74SMauro Carvalho Chehab } 22555bc3cb74SMauro Carvalho Chehab 22565bc3cb74SMauro Carvalho Chehab static int v4l_g_ctrl(const struct v4l2_ioctl_ops *ops, 22575bc3cb74SMauro Carvalho Chehab struct file *file, void *fh, void *arg) 22585bc3cb74SMauro Carvalho Chehab { 22595bc3cb74SMauro Carvalho Chehab struct video_device *vfd = video_devdata(file); 22605bc3cb74SMauro Carvalho Chehab struct v4l2_control *p = arg; 22615bc3cb74SMauro Carvalho Chehab struct v4l2_fh *vfh = 22625bc3cb74SMauro Carvalho Chehab test_bit(V4L2_FL_USES_V4L2_FH, &vfd->flags) ? fh : NULL; 22635bc3cb74SMauro Carvalho Chehab struct v4l2_ext_controls ctrls; 22645bc3cb74SMauro Carvalho Chehab struct v4l2_ext_control ctrl; 22655bc3cb74SMauro Carvalho Chehab 22665bc3cb74SMauro Carvalho Chehab if (vfh && vfh->ctrl_handler) 22675bc3cb74SMauro Carvalho Chehab return v4l2_g_ctrl(vfh->ctrl_handler, p); 22685bc3cb74SMauro Carvalho Chehab if (vfd->ctrl_handler) 22695bc3cb74SMauro Carvalho Chehab return v4l2_g_ctrl(vfd->ctrl_handler, p); 22705bc3cb74SMauro Carvalho Chehab if (ops->vidioc_g_ctrl) 22715bc3cb74SMauro Carvalho Chehab return ops->vidioc_g_ctrl(file, fh, p); 22725bc3cb74SMauro Carvalho Chehab if (ops->vidioc_g_ext_ctrls == NULL) 22735bc3cb74SMauro Carvalho Chehab return -ENOTTY; 22745bc3cb74SMauro Carvalho Chehab 22750f8017beSRicardo Ribalda ctrls.which = V4L2_CTRL_ID2WHICH(p->id); 22765bc3cb74SMauro Carvalho Chehab ctrls.count = 1; 22775bc3cb74SMauro Carvalho Chehab ctrls.controls = &ctrl; 22785bc3cb74SMauro Carvalho Chehab ctrl.id = p->id; 22795bc3cb74SMauro Carvalho Chehab ctrl.value = p->value; 2280861f92cbSRicardo Ribalda if (check_ext_ctrls(&ctrls, VIDIOC_G_CTRL)) { 22815bc3cb74SMauro Carvalho Chehab int ret = ops->vidioc_g_ext_ctrls(file, fh, &ctrls); 22825bc3cb74SMauro Carvalho Chehab 22835bc3cb74SMauro Carvalho Chehab if (ret == 0) 22845bc3cb74SMauro Carvalho Chehab p->value = ctrl.value; 22855bc3cb74SMauro Carvalho Chehab return ret; 22865bc3cb74SMauro Carvalho Chehab } 22875bc3cb74SMauro Carvalho Chehab return -EINVAL; 22885bc3cb74SMauro Carvalho Chehab } 22895bc3cb74SMauro Carvalho Chehab 22905bc3cb74SMauro Carvalho Chehab static int v4l_s_ctrl(const struct v4l2_ioctl_ops *ops, 22915bc3cb74SMauro Carvalho Chehab struct file *file, void *fh, void *arg) 22925bc3cb74SMauro Carvalho Chehab { 22935bc3cb74SMauro Carvalho Chehab struct video_device *vfd = video_devdata(file); 22945bc3cb74SMauro Carvalho Chehab struct v4l2_control *p = arg; 22955bc3cb74SMauro Carvalho Chehab struct v4l2_fh *vfh = 22965bc3cb74SMauro Carvalho Chehab test_bit(V4L2_FL_USES_V4L2_FH, &vfd->flags) ? fh : NULL; 22975bc3cb74SMauro Carvalho Chehab struct v4l2_ext_controls ctrls; 22985bc3cb74SMauro Carvalho Chehab struct v4l2_ext_control ctrl; 2299c87ed935SRicardo Ribalda int ret; 23005bc3cb74SMauro Carvalho Chehab 23015bc3cb74SMauro Carvalho Chehab if (vfh && vfh->ctrl_handler) 23025bc3cb74SMauro Carvalho Chehab return v4l2_s_ctrl(vfh, vfh->ctrl_handler, p); 23035bc3cb74SMauro Carvalho Chehab if (vfd->ctrl_handler) 23045bc3cb74SMauro Carvalho Chehab return v4l2_s_ctrl(NULL, vfd->ctrl_handler, p); 23055bc3cb74SMauro Carvalho Chehab if (ops->vidioc_s_ctrl) 23065bc3cb74SMauro Carvalho Chehab return ops->vidioc_s_ctrl(file, fh, p); 23075bc3cb74SMauro Carvalho Chehab if (ops->vidioc_s_ext_ctrls == NULL) 23085bc3cb74SMauro Carvalho Chehab return -ENOTTY; 23095bc3cb74SMauro Carvalho Chehab 23100f8017beSRicardo Ribalda ctrls.which = V4L2_CTRL_ID2WHICH(p->id); 23115bc3cb74SMauro Carvalho Chehab ctrls.count = 1; 23125bc3cb74SMauro Carvalho Chehab ctrls.controls = &ctrl; 23135bc3cb74SMauro Carvalho Chehab ctrl.id = p->id; 23145bc3cb74SMauro Carvalho Chehab ctrl.value = p->value; 2315c87ed935SRicardo Ribalda if (!check_ext_ctrls(&ctrls, VIDIOC_S_CTRL)) 23165bc3cb74SMauro Carvalho Chehab return -EINVAL; 2317c87ed935SRicardo Ribalda ret = ops->vidioc_s_ext_ctrls(file, fh, &ctrls); 2318c87ed935SRicardo Ribalda p->value = ctrl.value; 2319c87ed935SRicardo Ribalda return ret; 23205bc3cb74SMauro Carvalho Chehab } 23215bc3cb74SMauro Carvalho Chehab 23225bc3cb74SMauro Carvalho Chehab static int v4l_g_ext_ctrls(const struct v4l2_ioctl_ops *ops, 23235bc3cb74SMauro Carvalho Chehab struct file *file, void *fh, void *arg) 23245bc3cb74SMauro Carvalho Chehab { 23255bc3cb74SMauro Carvalho Chehab struct video_device *vfd = video_devdata(file); 23265bc3cb74SMauro Carvalho Chehab struct v4l2_ext_controls *p = arg; 23275bc3cb74SMauro Carvalho Chehab struct v4l2_fh *vfh = 23285bc3cb74SMauro Carvalho Chehab test_bit(V4L2_FL_USES_V4L2_FH, &vfd->flags) ? fh : NULL; 23295bc3cb74SMauro Carvalho Chehab 23305bc3cb74SMauro Carvalho Chehab p->error_idx = p->count; 23315bc3cb74SMauro Carvalho Chehab if (vfh && vfh->ctrl_handler) 2332173f6eacSEzequiel Garcia return v4l2_g_ext_ctrls(vfh->ctrl_handler, 2333173f6eacSEzequiel Garcia vfd, vfd->v4l2_dev->mdev, p); 23345bc3cb74SMauro Carvalho Chehab if (vfd->ctrl_handler) 2335173f6eacSEzequiel Garcia return v4l2_g_ext_ctrls(vfd->ctrl_handler, 2336173f6eacSEzequiel Garcia vfd, vfd->v4l2_dev->mdev, p); 23375bc3cb74SMauro Carvalho Chehab if (ops->vidioc_g_ext_ctrls == NULL) 23385bc3cb74SMauro Carvalho Chehab return -ENOTTY; 2339861f92cbSRicardo Ribalda return check_ext_ctrls(p, VIDIOC_G_EXT_CTRLS) ? 2340861f92cbSRicardo Ribalda ops->vidioc_g_ext_ctrls(file, fh, p) : -EINVAL; 23415bc3cb74SMauro Carvalho Chehab } 23425bc3cb74SMauro Carvalho Chehab 23435bc3cb74SMauro Carvalho Chehab static int v4l_s_ext_ctrls(const struct v4l2_ioctl_ops *ops, 23445bc3cb74SMauro Carvalho Chehab struct file *file, void *fh, void *arg) 23455bc3cb74SMauro Carvalho Chehab { 23465bc3cb74SMauro Carvalho Chehab struct video_device *vfd = video_devdata(file); 23475bc3cb74SMauro Carvalho Chehab struct v4l2_ext_controls *p = arg; 23485bc3cb74SMauro Carvalho Chehab struct v4l2_fh *vfh = 23495bc3cb74SMauro Carvalho Chehab test_bit(V4L2_FL_USES_V4L2_FH, &vfd->flags) ? fh : NULL; 23505bc3cb74SMauro Carvalho Chehab 23515bc3cb74SMauro Carvalho Chehab p->error_idx = p->count; 23525bc3cb74SMauro Carvalho Chehab if (vfh && vfh->ctrl_handler) 2353173f6eacSEzequiel Garcia return v4l2_s_ext_ctrls(vfh, vfh->ctrl_handler, 2354173f6eacSEzequiel Garcia vfd, vfd->v4l2_dev->mdev, p); 23555bc3cb74SMauro Carvalho Chehab if (vfd->ctrl_handler) 2356173f6eacSEzequiel Garcia return v4l2_s_ext_ctrls(NULL, vfd->ctrl_handler, 2357173f6eacSEzequiel Garcia vfd, vfd->v4l2_dev->mdev, p); 23585bc3cb74SMauro Carvalho Chehab if (ops->vidioc_s_ext_ctrls == NULL) 23595bc3cb74SMauro Carvalho Chehab return -ENOTTY; 2360861f92cbSRicardo Ribalda return check_ext_ctrls(p, VIDIOC_S_EXT_CTRLS) ? 2361861f92cbSRicardo Ribalda ops->vidioc_s_ext_ctrls(file, fh, p) : -EINVAL; 23625bc3cb74SMauro Carvalho Chehab } 23635bc3cb74SMauro Carvalho Chehab 23645bc3cb74SMauro Carvalho Chehab static int v4l_try_ext_ctrls(const struct v4l2_ioctl_ops *ops, 23655bc3cb74SMauro Carvalho Chehab struct file *file, void *fh, void *arg) 23665bc3cb74SMauro Carvalho Chehab { 23675bc3cb74SMauro Carvalho Chehab struct video_device *vfd = video_devdata(file); 23685bc3cb74SMauro Carvalho Chehab struct v4l2_ext_controls *p = arg; 23695bc3cb74SMauro Carvalho Chehab struct v4l2_fh *vfh = 23705bc3cb74SMauro Carvalho Chehab test_bit(V4L2_FL_USES_V4L2_FH, &vfd->flags) ? fh : NULL; 23715bc3cb74SMauro Carvalho Chehab 23725bc3cb74SMauro Carvalho Chehab p->error_idx = p->count; 23735bc3cb74SMauro Carvalho Chehab if (vfh && vfh->ctrl_handler) 2374173f6eacSEzequiel Garcia return v4l2_try_ext_ctrls(vfh->ctrl_handler, 2375173f6eacSEzequiel Garcia vfd, vfd->v4l2_dev->mdev, p); 23765bc3cb74SMauro Carvalho Chehab if (vfd->ctrl_handler) 2377173f6eacSEzequiel Garcia return v4l2_try_ext_ctrls(vfd->ctrl_handler, 2378173f6eacSEzequiel Garcia vfd, vfd->v4l2_dev->mdev, p); 23795bc3cb74SMauro Carvalho Chehab if (ops->vidioc_try_ext_ctrls == NULL) 23805bc3cb74SMauro Carvalho Chehab return -ENOTTY; 2381861f92cbSRicardo Ribalda return check_ext_ctrls(p, VIDIOC_TRY_EXT_CTRLS) ? 2382861f92cbSRicardo Ribalda ops->vidioc_try_ext_ctrls(file, fh, p) : -EINVAL; 23835bc3cb74SMauro Carvalho Chehab } 23845bc3cb74SMauro Carvalho Chehab 2385eaec420fSHans Verkuil /* 2386eaec420fSHans Verkuil * The selection API specified originally that the _MPLANE buffer types 2387eaec420fSHans Verkuil * shouldn't be used. The reasons for this are lost in the mists of time 2388eaec420fSHans Verkuil * (or just really crappy memories). Regardless, this is really annoying 2389eaec420fSHans Verkuil * for userspace. So to keep things simple we map _MPLANE buffer types 2390eaec420fSHans Verkuil * to their 'regular' counterparts before calling the driver. And we 2391eaec420fSHans Verkuil * restore it afterwards. This way applications can use either buffer 2392eaec420fSHans Verkuil * type and drivers don't need to check for both. 2393eaec420fSHans Verkuil */ 2394eaec420fSHans Verkuil static int v4l_g_selection(const struct v4l2_ioctl_ops *ops, 2395eaec420fSHans Verkuil struct file *file, void *fh, void *arg) 2396eaec420fSHans Verkuil { 2397eaec420fSHans Verkuil struct v4l2_selection *p = arg; 2398eaec420fSHans Verkuil u32 old_type = p->type; 2399eaec420fSHans Verkuil int ret; 2400eaec420fSHans Verkuil 2401eaec420fSHans Verkuil if (p->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) 2402eaec420fSHans Verkuil p->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 2403eaec420fSHans Verkuil else if (p->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) 2404eaec420fSHans Verkuil p->type = V4L2_BUF_TYPE_VIDEO_OUTPUT; 2405eaec420fSHans Verkuil ret = ops->vidioc_g_selection(file, fh, p); 2406eaec420fSHans Verkuil p->type = old_type; 2407eaec420fSHans Verkuil return ret; 2408eaec420fSHans Verkuil } 2409eaec420fSHans Verkuil 2410eaec420fSHans Verkuil static int v4l_s_selection(const struct v4l2_ioctl_ops *ops, 2411eaec420fSHans Verkuil struct file *file, void *fh, void *arg) 2412eaec420fSHans Verkuil { 2413eaec420fSHans Verkuil struct v4l2_selection *p = arg; 2414eaec420fSHans Verkuil u32 old_type = p->type; 2415eaec420fSHans Verkuil int ret; 2416eaec420fSHans Verkuil 2417eaec420fSHans Verkuil if (p->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) 2418eaec420fSHans Verkuil p->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 2419eaec420fSHans Verkuil else if (p->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) 2420eaec420fSHans Verkuil p->type = V4L2_BUF_TYPE_VIDEO_OUTPUT; 2421eaec420fSHans Verkuil ret = ops->vidioc_s_selection(file, fh, p); 2422eaec420fSHans Verkuil p->type = old_type; 2423eaec420fSHans Verkuil return ret; 2424eaec420fSHans Verkuil } 2425eaec420fSHans Verkuil 24265bc3cb74SMauro Carvalho Chehab static int v4l_g_crop(const struct v4l2_ioctl_ops *ops, 24275bc3cb74SMauro Carvalho Chehab struct file *file, void *fh, void *arg) 24285bc3cb74SMauro Carvalho Chehab { 24298cbd94bdSHans Verkuil struct video_device *vfd = video_devdata(file); 24305bc3cb74SMauro Carvalho Chehab struct v4l2_crop *p = arg; 24315bc3cb74SMauro Carvalho Chehab struct v4l2_selection s = { 24325bc3cb74SMauro Carvalho Chehab .type = p->type, 24335bc3cb74SMauro Carvalho Chehab }; 24345bc3cb74SMauro Carvalho Chehab int ret; 24355bc3cb74SMauro Carvalho Chehab 24365bc3cb74SMauro Carvalho Chehab /* simulate capture crop using selection api */ 24375bc3cb74SMauro Carvalho Chehab 24385bc3cb74SMauro Carvalho Chehab /* crop means compose for output devices */ 24395bc3cb74SMauro Carvalho Chehab if (V4L2_TYPE_IS_OUTPUT(p->type)) 24405b79da06SHans Verkuil s.target = V4L2_SEL_TGT_COMPOSE; 24415bc3cb74SMauro Carvalho Chehab else 24425b79da06SHans Verkuil s.target = V4L2_SEL_TGT_CROP; 24435bc3cb74SMauro Carvalho Chehab 24448cbd94bdSHans Verkuil if (test_bit(V4L2_FL_QUIRK_INVERTED_CROP, &vfd->flags)) 24458cbd94bdSHans Verkuil s.target = s.target == V4L2_SEL_TGT_COMPOSE ? 24468cbd94bdSHans Verkuil V4L2_SEL_TGT_CROP : V4L2_SEL_TGT_COMPOSE; 24478cbd94bdSHans Verkuil 2448eaec420fSHans Verkuil ret = v4l_g_selection(ops, file, fh, &s); 24495bc3cb74SMauro Carvalho Chehab 24505bc3cb74SMauro Carvalho Chehab /* copying results to old structure on success */ 24515bc3cb74SMauro Carvalho Chehab if (!ret) 24525bc3cb74SMauro Carvalho Chehab p->c = s.r; 24535bc3cb74SMauro Carvalho Chehab return ret; 24545bc3cb74SMauro Carvalho Chehab } 24555bc3cb74SMauro Carvalho Chehab 24565bc3cb74SMauro Carvalho Chehab static int v4l_s_crop(const struct v4l2_ioctl_ops *ops, 24575bc3cb74SMauro Carvalho Chehab struct file *file, void *fh, void *arg) 24585bc3cb74SMauro Carvalho Chehab { 24598cbd94bdSHans Verkuil struct video_device *vfd = video_devdata(file); 24605bc3cb74SMauro Carvalho Chehab struct v4l2_crop *p = arg; 24615bc3cb74SMauro Carvalho Chehab struct v4l2_selection s = { 24625bc3cb74SMauro Carvalho Chehab .type = p->type, 24635bc3cb74SMauro Carvalho Chehab .r = p->c, 24645bc3cb74SMauro Carvalho Chehab }; 24655bc3cb74SMauro Carvalho Chehab 24665bc3cb74SMauro Carvalho Chehab /* simulate capture crop using selection api */ 24675bc3cb74SMauro Carvalho Chehab 24685bc3cb74SMauro Carvalho Chehab /* crop means compose for output devices */ 24695bc3cb74SMauro Carvalho Chehab if (V4L2_TYPE_IS_OUTPUT(p->type)) 24705b79da06SHans Verkuil s.target = V4L2_SEL_TGT_COMPOSE; 24715bc3cb74SMauro Carvalho Chehab else 24725b79da06SHans Verkuil s.target = V4L2_SEL_TGT_CROP; 24735bc3cb74SMauro Carvalho Chehab 24748cbd94bdSHans Verkuil if (test_bit(V4L2_FL_QUIRK_INVERTED_CROP, &vfd->flags)) 24758cbd94bdSHans Verkuil s.target = s.target == V4L2_SEL_TGT_COMPOSE ? 24768cbd94bdSHans Verkuil V4L2_SEL_TGT_CROP : V4L2_SEL_TGT_COMPOSE; 24778cbd94bdSHans Verkuil 2478eaec420fSHans Verkuil return v4l_s_selection(ops, file, fh, &s); 24795bc3cb74SMauro Carvalho Chehab } 24805bc3cb74SMauro Carvalho Chehab 24815bc3cb74SMauro Carvalho Chehab static int v4l_cropcap(const struct v4l2_ioctl_ops *ops, 24825bc3cb74SMauro Carvalho Chehab struct file *file, void *fh, void *arg) 24835bc3cb74SMauro Carvalho Chehab { 24848cbd94bdSHans Verkuil struct video_device *vfd = video_devdata(file); 24855bc3cb74SMauro Carvalho Chehab struct v4l2_cropcap *p = arg; 24865bc3cb74SMauro Carvalho Chehab struct v4l2_selection s = { .type = p->type }; 248795dd7b7eSHans Verkuil int ret = 0; 248895dd7b7eSHans Verkuil 248995dd7b7eSHans Verkuil /* setting trivial pixelaspect */ 249095dd7b7eSHans Verkuil p->pixelaspect.numerator = 1; 249195dd7b7eSHans Verkuil p->pixelaspect.denominator = 1; 249295dd7b7eSHans Verkuil 24935200ab6aSHans Verkuil if (s.type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) 24945200ab6aSHans Verkuil s.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 24955200ab6aSHans Verkuil else if (s.type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) 24965200ab6aSHans Verkuil s.type = V4L2_BUF_TYPE_VIDEO_OUTPUT; 24975200ab6aSHans Verkuil 249895dd7b7eSHans Verkuil /* 249995dd7b7eSHans Verkuil * The determine_valid_ioctls() call already should ensure 250095dd7b7eSHans Verkuil * that this can never happen, but just in case... 250195dd7b7eSHans Verkuil */ 25025200ab6aSHans Verkuil if (WARN_ON(!ops->vidioc_g_selection)) 250395dd7b7eSHans Verkuil return -ENOTTY; 250495dd7b7eSHans Verkuil 25055200ab6aSHans Verkuil if (ops->vidioc_g_pixelaspect) 25065200ab6aSHans Verkuil ret = ops->vidioc_g_pixelaspect(file, fh, s.type, 25075200ab6aSHans Verkuil &p->pixelaspect); 250895dd7b7eSHans Verkuil 250995dd7b7eSHans Verkuil /* 251095dd7b7eSHans Verkuil * Ignore ENOTTY or ENOIOCTLCMD error returns, just use the 251195dd7b7eSHans Verkuil * square pixel aspect ratio in that case. 251295dd7b7eSHans Verkuil */ 251395dd7b7eSHans Verkuil if (ret && ret != -ENOTTY && ret != -ENOIOCTLCMD) 251495dd7b7eSHans Verkuil return ret; 251595dd7b7eSHans Verkuil 251695dd7b7eSHans Verkuil /* Use g_selection() to fill in the bounds and defrect rectangles */ 25175bc3cb74SMauro Carvalho Chehab 25185bc3cb74SMauro Carvalho Chehab /* obtaining bounds */ 25195bc3cb74SMauro Carvalho Chehab if (V4L2_TYPE_IS_OUTPUT(p->type)) 25205bc3cb74SMauro Carvalho Chehab s.target = V4L2_SEL_TGT_COMPOSE_BOUNDS; 25215bc3cb74SMauro Carvalho Chehab else 25225bc3cb74SMauro Carvalho Chehab s.target = V4L2_SEL_TGT_CROP_BOUNDS; 25235bc3cb74SMauro Carvalho Chehab 25248cbd94bdSHans Verkuil if (test_bit(V4L2_FL_QUIRK_INVERTED_CROP, &vfd->flags)) 25258cbd94bdSHans Verkuil s.target = s.target == V4L2_SEL_TGT_COMPOSE_BOUNDS ? 25268cbd94bdSHans Verkuil V4L2_SEL_TGT_CROP_BOUNDS : V4L2_SEL_TGT_COMPOSE_BOUNDS; 25278cbd94bdSHans Verkuil 2528eaec420fSHans Verkuil ret = v4l_g_selection(ops, file, fh, &s); 25295bc3cb74SMauro Carvalho Chehab if (ret) 25305bc3cb74SMauro Carvalho Chehab return ret; 25315bc3cb74SMauro Carvalho Chehab p->bounds = s.r; 25325bc3cb74SMauro Carvalho Chehab 25335bc3cb74SMauro Carvalho Chehab /* obtaining defrect */ 25348cbd94bdSHans Verkuil if (s.target == V4L2_SEL_TGT_COMPOSE_BOUNDS) 25355bc3cb74SMauro Carvalho Chehab s.target = V4L2_SEL_TGT_COMPOSE_DEFAULT; 25365bc3cb74SMauro Carvalho Chehab else 25375bc3cb74SMauro Carvalho Chehab s.target = V4L2_SEL_TGT_CROP_DEFAULT; 25385bc3cb74SMauro Carvalho Chehab 2539eaec420fSHans Verkuil ret = v4l_g_selection(ops, file, fh, &s); 25405bc3cb74SMauro Carvalho Chehab if (ret) 25415bc3cb74SMauro Carvalho Chehab return ret; 25425bc3cb74SMauro Carvalho Chehab p->defrect = s.r; 25439409945cSHans Verkuil 25445bc3cb74SMauro Carvalho Chehab return 0; 25455bc3cb74SMauro Carvalho Chehab } 25465bc3cb74SMauro Carvalho Chehab 25475bc3cb74SMauro Carvalho Chehab static int v4l_log_status(const struct v4l2_ioctl_ops *ops, 25485bc3cb74SMauro Carvalho Chehab struct file *file, void *fh, void *arg) 25495bc3cb74SMauro Carvalho Chehab { 25505bc3cb74SMauro Carvalho Chehab struct video_device *vfd = video_devdata(file); 25515bc3cb74SMauro Carvalho Chehab int ret; 25525bc3cb74SMauro Carvalho Chehab 25535bc3cb74SMauro Carvalho Chehab if (vfd->v4l2_dev) 25545bc3cb74SMauro Carvalho Chehab pr_info("%s: ================= START STATUS =================\n", 25555bc3cb74SMauro Carvalho Chehab vfd->v4l2_dev->name); 25565bc3cb74SMauro Carvalho Chehab ret = ops->vidioc_log_status(file, fh); 25575bc3cb74SMauro Carvalho Chehab if (vfd->v4l2_dev) 25585bc3cb74SMauro Carvalho Chehab pr_info("%s: ================== END STATUS ==================\n", 25595bc3cb74SMauro Carvalho Chehab vfd->v4l2_dev->name); 25605bc3cb74SMauro Carvalho Chehab return ret; 25615bc3cb74SMauro Carvalho Chehab } 25625bc3cb74SMauro Carvalho Chehab 25635bc3cb74SMauro Carvalho Chehab static int v4l_dbg_g_register(const struct v4l2_ioctl_ops *ops, 25645bc3cb74SMauro Carvalho Chehab struct file *file, void *fh, void *arg) 25655bc3cb74SMauro Carvalho Chehab { 25665bc3cb74SMauro Carvalho Chehab #ifdef CONFIG_VIDEO_ADV_DEBUG 25675bc3cb74SMauro Carvalho Chehab struct v4l2_dbg_register *p = arg; 256879b0c640SHans Verkuil struct video_device *vfd = video_devdata(file); 256979b0c640SHans Verkuil struct v4l2_subdev *sd; 257079b0c640SHans Verkuil int idx = 0; 25715bc3cb74SMauro Carvalho Chehab 25725bc3cb74SMauro Carvalho Chehab if (!capable(CAP_SYS_ADMIN)) 25735bc3cb74SMauro Carvalho Chehab return -EPERM; 25743eef2510SHans Verkuil if (p->match.type == V4L2_CHIP_MATCH_SUBDEV) { 257579b0c640SHans Verkuil if (vfd->v4l2_dev == NULL) 257679b0c640SHans Verkuil return -EINVAL; 25773eef2510SHans Verkuil v4l2_device_for_each_subdev(sd, vfd->v4l2_dev) 25783eef2510SHans Verkuil if (p->match.addr == idx++) 257979b0c640SHans Verkuil return v4l2_subdev_call(sd, core, g_register, p); 258079b0c640SHans Verkuil return -EINVAL; 258179b0c640SHans Verkuil } 2582191b79b0SHans Verkuil if (ops->vidioc_g_register && p->match.type == V4L2_CHIP_MATCH_BRIDGE && 2583191b79b0SHans Verkuil (ops->vidioc_g_chip_info || p->match.addr == 0)) 25845bc3cb74SMauro Carvalho Chehab return ops->vidioc_g_register(file, fh, p); 258579b0c640SHans Verkuil return -EINVAL; 25865bc3cb74SMauro Carvalho Chehab #else 25875bc3cb74SMauro Carvalho Chehab return -ENOTTY; 25885bc3cb74SMauro Carvalho Chehab #endif 25895bc3cb74SMauro Carvalho Chehab } 25905bc3cb74SMauro Carvalho Chehab 25915bc3cb74SMauro Carvalho Chehab static int v4l_dbg_s_register(const struct v4l2_ioctl_ops *ops, 25925bc3cb74SMauro Carvalho Chehab struct file *file, void *fh, void *arg) 25935bc3cb74SMauro Carvalho Chehab { 25945bc3cb74SMauro Carvalho Chehab #ifdef CONFIG_VIDEO_ADV_DEBUG 2595977ba3b1SHans Verkuil const struct v4l2_dbg_register *p = arg; 259679b0c640SHans Verkuil struct video_device *vfd = video_devdata(file); 259779b0c640SHans Verkuil struct v4l2_subdev *sd; 259879b0c640SHans Verkuil int idx = 0; 25995bc3cb74SMauro Carvalho Chehab 26005bc3cb74SMauro Carvalho Chehab if (!capable(CAP_SYS_ADMIN)) 26015bc3cb74SMauro Carvalho Chehab return -EPERM; 26023eef2510SHans Verkuil if (p->match.type == V4L2_CHIP_MATCH_SUBDEV) { 260379b0c640SHans Verkuil if (vfd->v4l2_dev == NULL) 260479b0c640SHans Verkuil return -EINVAL; 26053eef2510SHans Verkuil v4l2_device_for_each_subdev(sd, vfd->v4l2_dev) 26063eef2510SHans Verkuil if (p->match.addr == idx++) 260779b0c640SHans Verkuil return v4l2_subdev_call(sd, core, s_register, p); 260879b0c640SHans Verkuil return -EINVAL; 260979b0c640SHans Verkuil } 2610191b79b0SHans Verkuil if (ops->vidioc_s_register && p->match.type == V4L2_CHIP_MATCH_BRIDGE && 2611191b79b0SHans Verkuil (ops->vidioc_g_chip_info || p->match.addr == 0)) 26125bc3cb74SMauro Carvalho Chehab return ops->vidioc_s_register(file, fh, p); 261379b0c640SHans Verkuil return -EINVAL; 26145bc3cb74SMauro Carvalho Chehab #else 26155bc3cb74SMauro Carvalho Chehab return -ENOTTY; 26165bc3cb74SMauro Carvalho Chehab #endif 26175bc3cb74SMauro Carvalho Chehab } 26185bc3cb74SMauro Carvalho Chehab 261996b03d2aSHans Verkuil static int v4l_dbg_g_chip_info(const struct v4l2_ioctl_ops *ops, 262079b0c640SHans Verkuil struct file *file, void *fh, void *arg) 262179b0c640SHans Verkuil { 2622cd634f1bSHans Verkuil #ifdef CONFIG_VIDEO_ADV_DEBUG 262379b0c640SHans Verkuil struct video_device *vfd = video_devdata(file); 262496b03d2aSHans Verkuil struct v4l2_dbg_chip_info *p = arg; 262579b0c640SHans Verkuil struct v4l2_subdev *sd; 262679b0c640SHans Verkuil int idx = 0; 262779b0c640SHans Verkuil 262879b0c640SHans Verkuil switch (p->match.type) { 262979b0c640SHans Verkuil case V4L2_CHIP_MATCH_BRIDGE: 263079b0c640SHans Verkuil if (ops->vidioc_s_register) 263179b0c640SHans Verkuil p->flags |= V4L2_CHIP_FL_WRITABLE; 263279b0c640SHans Verkuil if (ops->vidioc_g_register) 263379b0c640SHans Verkuil p->flags |= V4L2_CHIP_FL_READABLE; 2634c0decac1SMauro Carvalho Chehab strscpy(p->name, vfd->v4l2_dev->name, sizeof(p->name)); 263596b03d2aSHans Verkuil if (ops->vidioc_g_chip_info) 263696b03d2aSHans Verkuil return ops->vidioc_g_chip_info(file, fh, arg); 26370f0fe4b9SHans Verkuil if (p->match.addr) 26380f0fe4b9SHans Verkuil return -EINVAL; 263979b0c640SHans Verkuil return 0; 264079b0c640SHans Verkuil 26413eef2510SHans Verkuil case V4L2_CHIP_MATCH_SUBDEV: 264279b0c640SHans Verkuil if (vfd->v4l2_dev == NULL) 264379b0c640SHans Verkuil break; 264479b0c640SHans Verkuil v4l2_device_for_each_subdev(sd, vfd->v4l2_dev) { 26453eef2510SHans Verkuil if (p->match.addr != idx++) 26463eef2510SHans Verkuil continue; 264779b0c640SHans Verkuil if (sd->ops->core && sd->ops->core->s_register) 264879b0c640SHans Verkuil p->flags |= V4L2_CHIP_FL_WRITABLE; 264979b0c640SHans Verkuil if (sd->ops->core && sd->ops->core->g_register) 265079b0c640SHans Verkuil p->flags |= V4L2_CHIP_FL_READABLE; 2651c0decac1SMauro Carvalho Chehab strscpy(p->name, sd->name, sizeof(p->name)); 265279b0c640SHans Verkuil return 0; 265379b0c640SHans Verkuil } 265479b0c640SHans Verkuil break; 265579b0c640SHans Verkuil } 265679b0c640SHans Verkuil return -EINVAL; 2657cd634f1bSHans Verkuil #else 2658cd634f1bSHans Verkuil return -ENOTTY; 2659cd634f1bSHans Verkuil #endif 266079b0c640SHans Verkuil } 266179b0c640SHans Verkuil 26625bc3cb74SMauro Carvalho Chehab static int v4l_dqevent(const struct v4l2_ioctl_ops *ops, 26635bc3cb74SMauro Carvalho Chehab struct file *file, void *fh, void *arg) 26645bc3cb74SMauro Carvalho Chehab { 26655bc3cb74SMauro Carvalho Chehab return v4l2_event_dequeue(fh, arg, file->f_flags & O_NONBLOCK); 26665bc3cb74SMauro Carvalho Chehab } 26675bc3cb74SMauro Carvalho Chehab 26685bc3cb74SMauro Carvalho Chehab static int v4l_subscribe_event(const struct v4l2_ioctl_ops *ops, 26695bc3cb74SMauro Carvalho Chehab struct file *file, void *fh, void *arg) 26705bc3cb74SMauro Carvalho Chehab { 26715bc3cb74SMauro Carvalho Chehab return ops->vidioc_subscribe_event(fh, arg); 26725bc3cb74SMauro Carvalho Chehab } 26735bc3cb74SMauro Carvalho Chehab 26745bc3cb74SMauro Carvalho Chehab static int v4l_unsubscribe_event(const struct v4l2_ioctl_ops *ops, 26755bc3cb74SMauro Carvalho Chehab struct file *file, void *fh, void *arg) 26765bc3cb74SMauro Carvalho Chehab { 26775bc3cb74SMauro Carvalho Chehab return ops->vidioc_unsubscribe_event(fh, arg); 26785bc3cb74SMauro Carvalho Chehab } 26795bc3cb74SMauro Carvalho Chehab 26805bc3cb74SMauro Carvalho Chehab static int v4l_g_sliced_vbi_cap(const struct v4l2_ioctl_ops *ops, 26815bc3cb74SMauro Carvalho Chehab struct file *file, void *fh, void *arg) 26825bc3cb74SMauro Carvalho Chehab { 26835bc3cb74SMauro Carvalho Chehab struct v4l2_sliced_vbi_cap *p = arg; 26844b20259fSHans Verkuil int ret = check_fmt(file, p->type); 26854b20259fSHans Verkuil 26864b20259fSHans Verkuil if (ret) 26874b20259fSHans Verkuil return ret; 26885bc3cb74SMauro Carvalho Chehab 26895bc3cb74SMauro Carvalho Chehab /* Clear up to type, everything after type is zeroed already */ 26905bc3cb74SMauro Carvalho Chehab memset(p, 0, offsetof(struct v4l2_sliced_vbi_cap, type)); 26915bc3cb74SMauro Carvalho Chehab 26925bc3cb74SMauro Carvalho Chehab return ops->vidioc_g_sliced_vbi_cap(file, fh, p); 26935bc3cb74SMauro Carvalho Chehab } 26945bc3cb74SMauro Carvalho Chehab 26955bc3cb74SMauro Carvalho Chehab static int v4l_enum_freq_bands(const struct v4l2_ioctl_ops *ops, 26965bc3cb74SMauro Carvalho Chehab struct file *file, void *fh, void *arg) 26975bc3cb74SMauro Carvalho Chehab { 26985bc3cb74SMauro Carvalho Chehab struct video_device *vfd = video_devdata(file); 26995bc3cb74SMauro Carvalho Chehab struct v4l2_frequency_band *p = arg; 27005bc3cb74SMauro Carvalho Chehab enum v4l2_tuner_type type; 27015bc3cb74SMauro Carvalho Chehab int err; 27025bc3cb74SMauro Carvalho Chehab 270384099a28SAntti Palosaari if (vfd->vfl_type == VFL_TYPE_SDR) { 2704f3c3ececSAntti Palosaari if (p->type != V4L2_TUNER_SDR && p->type != V4L2_TUNER_RF) 270584099a28SAntti Palosaari return -EINVAL; 270684099a28SAntti Palosaari type = p->type; 270784099a28SAntti Palosaari } else { 27085bc3cb74SMauro Carvalho Chehab type = (vfd->vfl_type == VFL_TYPE_RADIO) ? 27095bc3cb74SMauro Carvalho Chehab V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV; 27105bc3cb74SMauro Carvalho Chehab if (type != p->type) 27115bc3cb74SMauro Carvalho Chehab return -EINVAL; 271284099a28SAntti Palosaari } 2713a7f404afSHans Verkuil if (ops->vidioc_enum_freq_bands) { 2714a7f404afSHans Verkuil err = ops->vidioc_enum_freq_bands(file, fh, p); 2715a7f404afSHans Verkuil if (err != -ENOTTY) 2716a7f404afSHans Verkuil return err; 2717a7f404afSHans Verkuil } 271873f35418SHans Verkuil if (is_valid_ioctl(vfd, VIDIOC_G_TUNER)) { 27195bc3cb74SMauro Carvalho Chehab struct v4l2_tuner t = { 27205bc3cb74SMauro Carvalho Chehab .index = p->tuner, 27215bc3cb74SMauro Carvalho Chehab .type = type, 27225bc3cb74SMauro Carvalho Chehab }; 27235bc3cb74SMauro Carvalho Chehab 272479e8c7beSMauro Carvalho Chehab if (p->index) 272579e8c7beSMauro Carvalho Chehab return -EINVAL; 27265bc3cb74SMauro Carvalho Chehab err = ops->vidioc_g_tuner(file, fh, &t); 27275bc3cb74SMauro Carvalho Chehab if (err) 27285bc3cb74SMauro Carvalho Chehab return err; 27295bc3cb74SMauro Carvalho Chehab p->capability = t.capability | V4L2_TUNER_CAP_FREQ_BANDS; 27305bc3cb74SMauro Carvalho Chehab p->rangelow = t.rangelow; 27315bc3cb74SMauro Carvalho Chehab p->rangehigh = t.rangehigh; 27325bc3cb74SMauro Carvalho Chehab p->modulation = (type == V4L2_TUNER_RADIO) ? 27335bc3cb74SMauro Carvalho Chehab V4L2_BAND_MODULATION_FM : V4L2_BAND_MODULATION_VSB; 27345bc3cb74SMauro Carvalho Chehab return 0; 27355bc3cb74SMauro Carvalho Chehab } 273673f35418SHans Verkuil if (is_valid_ioctl(vfd, VIDIOC_G_MODULATOR)) { 27375bc3cb74SMauro Carvalho Chehab struct v4l2_modulator m = { 27385bc3cb74SMauro Carvalho Chehab .index = p->tuner, 27395bc3cb74SMauro Carvalho Chehab }; 27405bc3cb74SMauro Carvalho Chehab 27415bc3cb74SMauro Carvalho Chehab if (type != V4L2_TUNER_RADIO) 27425bc3cb74SMauro Carvalho Chehab return -EINVAL; 274379e8c7beSMauro Carvalho Chehab if (p->index) 274479e8c7beSMauro Carvalho Chehab return -EINVAL; 27455bc3cb74SMauro Carvalho Chehab err = ops->vidioc_g_modulator(file, fh, &m); 27465bc3cb74SMauro Carvalho Chehab if (err) 27475bc3cb74SMauro Carvalho Chehab return err; 27485bc3cb74SMauro Carvalho Chehab p->capability = m.capability | V4L2_TUNER_CAP_FREQ_BANDS; 27495bc3cb74SMauro Carvalho Chehab p->rangelow = m.rangelow; 27505bc3cb74SMauro Carvalho Chehab p->rangehigh = m.rangehigh; 27515bc3cb74SMauro Carvalho Chehab p->modulation = (type == V4L2_TUNER_RADIO) ? 27525bc3cb74SMauro Carvalho Chehab V4L2_BAND_MODULATION_FM : V4L2_BAND_MODULATION_VSB; 27535bc3cb74SMauro Carvalho Chehab return 0; 27545bc3cb74SMauro Carvalho Chehab } 27555bc3cb74SMauro Carvalho Chehab return -ENOTTY; 27565bc3cb74SMauro Carvalho Chehab } 27575bc3cb74SMauro Carvalho Chehab 27585bc3cb74SMauro Carvalho Chehab struct v4l2_ioctl_info { 27595bc3cb74SMauro Carvalho Chehab unsigned int ioctl; 27605bc3cb74SMauro Carvalho Chehab u32 flags; 27615bc3cb74SMauro Carvalho Chehab const char * const name; 27623ad3b7a2SSami Tolvanen int (*func)(const struct v4l2_ioctl_ops *ops, struct file *file, 27633ad3b7a2SSami Tolvanen void *fh, void *p); 27645bc3cb74SMauro Carvalho Chehab void (*debug)(const void *arg, bool write_only); 27655bc3cb74SMauro Carvalho Chehab }; 27665bc3cb74SMauro Carvalho Chehab 27675bc3cb74SMauro Carvalho Chehab /* This control needs a priority check */ 27685bc3cb74SMauro Carvalho Chehab #define INFO_FL_PRIO (1 << 0) 27695bc3cb74SMauro Carvalho Chehab /* This control can be valid if the filehandle passes a control handler. */ 27705bc3cb74SMauro Carvalho Chehab #define INFO_FL_CTRL (1 << 1) 27715bc3cb74SMauro Carvalho Chehab /* Queuing ioctl */ 27723ad3b7a2SSami Tolvanen #define INFO_FL_QUEUE (1 << 2) 2773043f77edSHans Verkuil /* Always copy back result, even on error */ 27743ad3b7a2SSami Tolvanen #define INFO_FL_ALWAYS_COPY (1 << 3) 27755bc3cb74SMauro Carvalho Chehab /* Zero struct from after the field to the end */ 27765bc3cb74SMauro Carvalho Chehab #define INFO_FL_CLEAR(v4l2_struct, field) \ 27775bc3cb74SMauro Carvalho Chehab ((offsetof(struct v4l2_struct, field) + \ 2778c593642cSPankaj Bharadiya sizeof_field(struct v4l2_struct, field)) << 16) 27795bc3cb74SMauro Carvalho Chehab #define INFO_FL_CLEAR_MASK (_IOC_SIZEMASK << 16) 27805bc3cb74SMauro Carvalho Chehab 27813ad3b7a2SSami Tolvanen #define DEFINE_V4L_STUB_FUNC(_vidioc) \ 27823ad3b7a2SSami Tolvanen static int v4l_stub_ ## _vidioc( \ 27833ad3b7a2SSami Tolvanen const struct v4l2_ioctl_ops *ops, \ 27843ad3b7a2SSami Tolvanen struct file *file, void *fh, void *p) \ 27853ad3b7a2SSami Tolvanen { \ 27863ad3b7a2SSami Tolvanen return ops->vidioc_ ## _vidioc(file, fh, p); \ 27873ad3b7a2SSami Tolvanen } 27883ad3b7a2SSami Tolvanen 27893ad3b7a2SSami Tolvanen #define IOCTL_INFO(_ioctl, _func, _debug, _flags) \ 27905bc3cb74SMauro Carvalho Chehab [_IOC_NR(_ioctl)] = { \ 27915bc3cb74SMauro Carvalho Chehab .ioctl = _ioctl, \ 27923ad3b7a2SSami Tolvanen .flags = _flags, \ 27935bc3cb74SMauro Carvalho Chehab .name = #_ioctl, \ 27943ad3b7a2SSami Tolvanen .func = _func, \ 27955bc3cb74SMauro Carvalho Chehab .debug = _debug, \ 27965bc3cb74SMauro Carvalho Chehab } 27975bc3cb74SMauro Carvalho Chehab 27983ad3b7a2SSami Tolvanen DEFINE_V4L_STUB_FUNC(g_fbuf) 27993ad3b7a2SSami Tolvanen DEFINE_V4L_STUB_FUNC(expbuf) 28003ad3b7a2SSami Tolvanen DEFINE_V4L_STUB_FUNC(g_std) 28013ad3b7a2SSami Tolvanen DEFINE_V4L_STUB_FUNC(g_audio) 28023ad3b7a2SSami Tolvanen DEFINE_V4L_STUB_FUNC(s_audio) 28033ad3b7a2SSami Tolvanen DEFINE_V4L_STUB_FUNC(g_edid) 28043ad3b7a2SSami Tolvanen DEFINE_V4L_STUB_FUNC(s_edid) 28053ad3b7a2SSami Tolvanen DEFINE_V4L_STUB_FUNC(g_audout) 28063ad3b7a2SSami Tolvanen DEFINE_V4L_STUB_FUNC(s_audout) 28073ad3b7a2SSami Tolvanen DEFINE_V4L_STUB_FUNC(g_jpegcomp) 28083ad3b7a2SSami Tolvanen DEFINE_V4L_STUB_FUNC(s_jpegcomp) 28093ad3b7a2SSami Tolvanen DEFINE_V4L_STUB_FUNC(enumaudio) 28103ad3b7a2SSami Tolvanen DEFINE_V4L_STUB_FUNC(enumaudout) 28113ad3b7a2SSami Tolvanen DEFINE_V4L_STUB_FUNC(enum_framesizes) 28123ad3b7a2SSami Tolvanen DEFINE_V4L_STUB_FUNC(enum_frameintervals) 28133ad3b7a2SSami Tolvanen DEFINE_V4L_STUB_FUNC(g_enc_index) 28143ad3b7a2SSami Tolvanen DEFINE_V4L_STUB_FUNC(encoder_cmd) 28153ad3b7a2SSami Tolvanen DEFINE_V4L_STUB_FUNC(try_encoder_cmd) 28163ad3b7a2SSami Tolvanen DEFINE_V4L_STUB_FUNC(decoder_cmd) 28173ad3b7a2SSami Tolvanen DEFINE_V4L_STUB_FUNC(try_decoder_cmd) 28183ad3b7a2SSami Tolvanen DEFINE_V4L_STUB_FUNC(s_dv_timings) 28193ad3b7a2SSami Tolvanen DEFINE_V4L_STUB_FUNC(g_dv_timings) 28203ad3b7a2SSami Tolvanen DEFINE_V4L_STUB_FUNC(enum_dv_timings) 28213ad3b7a2SSami Tolvanen DEFINE_V4L_STUB_FUNC(query_dv_timings) 28223ad3b7a2SSami Tolvanen DEFINE_V4L_STUB_FUNC(dv_timings_cap) 28235bc3cb74SMauro Carvalho Chehab 28247c91d0a4SEric Biggers static const struct v4l2_ioctl_info v4l2_ioctls[] = { 28253ad3b7a2SSami Tolvanen IOCTL_INFO(VIDIOC_QUERYCAP, v4l_querycap, v4l_print_querycap, 0), 2826e5b6b07aSLaurent Pinchart IOCTL_INFO(VIDIOC_ENUM_FMT, v4l_enum_fmt, v4l_print_fmtdesc, 0), 28273ad3b7a2SSami Tolvanen IOCTL_INFO(VIDIOC_G_FMT, v4l_g_fmt, v4l_print_format, 0), 28283ad3b7a2SSami Tolvanen IOCTL_INFO(VIDIOC_S_FMT, v4l_s_fmt, v4l_print_format, INFO_FL_PRIO), 28293ad3b7a2SSami Tolvanen IOCTL_INFO(VIDIOC_REQBUFS, v4l_reqbufs, v4l_print_requestbuffers, INFO_FL_PRIO | INFO_FL_QUEUE), 28303ad3b7a2SSami Tolvanen IOCTL_INFO(VIDIOC_QUERYBUF, v4l_querybuf, v4l_print_buffer, INFO_FL_QUEUE | INFO_FL_CLEAR(v4l2_buffer, length)), 28313ad3b7a2SSami Tolvanen IOCTL_INFO(VIDIOC_G_FBUF, v4l_stub_g_fbuf, v4l_print_framebuffer, 0), 2832d04794daSHans Verkuil IOCTL_INFO(VIDIOC_S_FBUF, v4l_s_fbuf, v4l_print_framebuffer, INFO_FL_PRIO), 28333ad3b7a2SSami Tolvanen IOCTL_INFO(VIDIOC_OVERLAY, v4l_overlay, v4l_print_u32, INFO_FL_PRIO), 28343ad3b7a2SSami Tolvanen IOCTL_INFO(VIDIOC_QBUF, v4l_qbuf, v4l_print_buffer, INFO_FL_QUEUE), 28353ad3b7a2SSami Tolvanen IOCTL_INFO(VIDIOC_EXPBUF, v4l_stub_expbuf, v4l_print_exportbuffer, INFO_FL_QUEUE | INFO_FL_CLEAR(v4l2_exportbuffer, flags)), 28363ad3b7a2SSami Tolvanen IOCTL_INFO(VIDIOC_DQBUF, v4l_dqbuf, v4l_print_buffer, INFO_FL_QUEUE), 28373ad3b7a2SSami Tolvanen IOCTL_INFO(VIDIOC_STREAMON, v4l_streamon, v4l_print_buftype, INFO_FL_PRIO | INFO_FL_QUEUE), 28383ad3b7a2SSami Tolvanen IOCTL_INFO(VIDIOC_STREAMOFF, v4l_streamoff, v4l_print_buftype, INFO_FL_PRIO | INFO_FL_QUEUE), 28393ad3b7a2SSami Tolvanen IOCTL_INFO(VIDIOC_G_PARM, v4l_g_parm, v4l_print_streamparm, INFO_FL_CLEAR(v4l2_streamparm, type)), 28403ad3b7a2SSami Tolvanen IOCTL_INFO(VIDIOC_S_PARM, v4l_s_parm, v4l_print_streamparm, INFO_FL_PRIO), 28413ad3b7a2SSami Tolvanen IOCTL_INFO(VIDIOC_G_STD, v4l_stub_g_std, v4l_print_std, 0), 28423ad3b7a2SSami Tolvanen IOCTL_INFO(VIDIOC_S_STD, v4l_s_std, v4l_print_std, INFO_FL_PRIO), 28433ad3b7a2SSami Tolvanen IOCTL_INFO(VIDIOC_ENUMSTD, v4l_enumstd, v4l_print_standard, INFO_FL_CLEAR(v4l2_standard, index)), 28443ad3b7a2SSami Tolvanen IOCTL_INFO(VIDIOC_ENUMINPUT, v4l_enuminput, v4l_print_enuminput, INFO_FL_CLEAR(v4l2_input, index)), 28453ad3b7a2SSami Tolvanen IOCTL_INFO(VIDIOC_G_CTRL, v4l_g_ctrl, v4l_print_control, INFO_FL_CTRL | INFO_FL_CLEAR(v4l2_control, id)), 28463ad3b7a2SSami Tolvanen IOCTL_INFO(VIDIOC_S_CTRL, v4l_s_ctrl, v4l_print_control, INFO_FL_PRIO | INFO_FL_CTRL), 28473ad3b7a2SSami Tolvanen IOCTL_INFO(VIDIOC_G_TUNER, v4l_g_tuner, v4l_print_tuner, INFO_FL_CLEAR(v4l2_tuner, index)), 28483ad3b7a2SSami Tolvanen IOCTL_INFO(VIDIOC_S_TUNER, v4l_s_tuner, v4l_print_tuner, INFO_FL_PRIO), 28493ad3b7a2SSami Tolvanen IOCTL_INFO(VIDIOC_G_AUDIO, v4l_stub_g_audio, v4l_print_audio, 0), 28503ad3b7a2SSami Tolvanen IOCTL_INFO(VIDIOC_S_AUDIO, v4l_stub_s_audio, v4l_print_audio, INFO_FL_PRIO), 28513ad3b7a2SSami Tolvanen IOCTL_INFO(VIDIOC_QUERYCTRL, v4l_queryctrl, v4l_print_queryctrl, INFO_FL_CTRL | INFO_FL_CLEAR(v4l2_queryctrl, id)), 28523ad3b7a2SSami Tolvanen IOCTL_INFO(VIDIOC_QUERYMENU, v4l_querymenu, v4l_print_querymenu, INFO_FL_CTRL | INFO_FL_CLEAR(v4l2_querymenu, index)), 2853f645e625SNiklas Söderlund IOCTL_INFO(VIDIOC_G_INPUT, v4l_g_input, v4l_print_u32, 0), 28543ad3b7a2SSami Tolvanen IOCTL_INFO(VIDIOC_S_INPUT, v4l_s_input, v4l_print_u32, INFO_FL_PRIO), 28553ad3b7a2SSami Tolvanen IOCTL_INFO(VIDIOC_G_EDID, v4l_stub_g_edid, v4l_print_edid, INFO_FL_ALWAYS_COPY), 28563ad3b7a2SSami Tolvanen IOCTL_INFO(VIDIOC_S_EDID, v4l_stub_s_edid, v4l_print_edid, INFO_FL_PRIO | INFO_FL_ALWAYS_COPY), 2857f645e625SNiklas Söderlund IOCTL_INFO(VIDIOC_G_OUTPUT, v4l_g_output, v4l_print_u32, 0), 28583ad3b7a2SSami Tolvanen IOCTL_INFO(VIDIOC_S_OUTPUT, v4l_s_output, v4l_print_u32, INFO_FL_PRIO), 28593ad3b7a2SSami Tolvanen IOCTL_INFO(VIDIOC_ENUMOUTPUT, v4l_enumoutput, v4l_print_enumoutput, INFO_FL_CLEAR(v4l2_output, index)), 28603ad3b7a2SSami Tolvanen IOCTL_INFO(VIDIOC_G_AUDOUT, v4l_stub_g_audout, v4l_print_audioout, 0), 28613ad3b7a2SSami Tolvanen IOCTL_INFO(VIDIOC_S_AUDOUT, v4l_stub_s_audout, v4l_print_audioout, INFO_FL_PRIO), 28623ad3b7a2SSami Tolvanen IOCTL_INFO(VIDIOC_G_MODULATOR, v4l_g_modulator, v4l_print_modulator, INFO_FL_CLEAR(v4l2_modulator, index)), 28633ad3b7a2SSami Tolvanen IOCTL_INFO(VIDIOC_S_MODULATOR, v4l_s_modulator, v4l_print_modulator, INFO_FL_PRIO), 28643ad3b7a2SSami Tolvanen IOCTL_INFO(VIDIOC_G_FREQUENCY, v4l_g_frequency, v4l_print_frequency, INFO_FL_CLEAR(v4l2_frequency, tuner)), 28653ad3b7a2SSami Tolvanen IOCTL_INFO(VIDIOC_S_FREQUENCY, v4l_s_frequency, v4l_print_frequency, INFO_FL_PRIO), 28663ad3b7a2SSami Tolvanen IOCTL_INFO(VIDIOC_CROPCAP, v4l_cropcap, v4l_print_cropcap, INFO_FL_CLEAR(v4l2_cropcap, type)), 28673ad3b7a2SSami Tolvanen IOCTL_INFO(VIDIOC_G_CROP, v4l_g_crop, v4l_print_crop, INFO_FL_CLEAR(v4l2_crop, type)), 28683ad3b7a2SSami Tolvanen IOCTL_INFO(VIDIOC_S_CROP, v4l_s_crop, v4l_print_crop, INFO_FL_PRIO), 28693ad3b7a2SSami Tolvanen IOCTL_INFO(VIDIOC_G_SELECTION, v4l_g_selection, v4l_print_selection, INFO_FL_CLEAR(v4l2_selection, r)), 28703ad3b7a2SSami Tolvanen IOCTL_INFO(VIDIOC_S_SELECTION, v4l_s_selection, v4l_print_selection, INFO_FL_PRIO | INFO_FL_CLEAR(v4l2_selection, r)), 28713ad3b7a2SSami Tolvanen IOCTL_INFO(VIDIOC_G_JPEGCOMP, v4l_stub_g_jpegcomp, v4l_print_jpegcompression, 0), 28723ad3b7a2SSami Tolvanen IOCTL_INFO(VIDIOC_S_JPEGCOMP, v4l_stub_s_jpegcomp, v4l_print_jpegcompression, INFO_FL_PRIO), 28733ad3b7a2SSami Tolvanen IOCTL_INFO(VIDIOC_QUERYSTD, v4l_querystd, v4l_print_std, 0), 28743ad3b7a2SSami Tolvanen IOCTL_INFO(VIDIOC_TRY_FMT, v4l_try_fmt, v4l_print_format, 0), 28753ad3b7a2SSami Tolvanen IOCTL_INFO(VIDIOC_ENUMAUDIO, v4l_stub_enumaudio, v4l_print_audio, INFO_FL_CLEAR(v4l2_audio, index)), 28763ad3b7a2SSami Tolvanen IOCTL_INFO(VIDIOC_ENUMAUDOUT, v4l_stub_enumaudout, v4l_print_audioout, INFO_FL_CLEAR(v4l2_audioout, index)), 28773ad3b7a2SSami Tolvanen IOCTL_INFO(VIDIOC_G_PRIORITY, v4l_g_priority, v4l_print_u32, 0), 28783ad3b7a2SSami Tolvanen IOCTL_INFO(VIDIOC_S_PRIORITY, v4l_s_priority, v4l_print_u32, INFO_FL_PRIO), 28793ad3b7a2SSami Tolvanen IOCTL_INFO(VIDIOC_G_SLICED_VBI_CAP, v4l_g_sliced_vbi_cap, v4l_print_sliced_vbi_cap, INFO_FL_CLEAR(v4l2_sliced_vbi_cap, type)), 28803ad3b7a2SSami Tolvanen IOCTL_INFO(VIDIOC_LOG_STATUS, v4l_log_status, v4l_print_newline, 0), 2881f0da34f3SHans Verkuil IOCTL_INFO(VIDIOC_G_EXT_CTRLS, v4l_g_ext_ctrls, v4l_print_ext_controls, INFO_FL_CTRL | INFO_FL_ALWAYS_COPY), 2882f0da34f3SHans Verkuil IOCTL_INFO(VIDIOC_S_EXT_CTRLS, v4l_s_ext_ctrls, v4l_print_ext_controls, INFO_FL_PRIO | INFO_FL_CTRL | INFO_FL_ALWAYS_COPY), 2883f0da34f3SHans Verkuil IOCTL_INFO(VIDIOC_TRY_EXT_CTRLS, v4l_try_ext_ctrls, v4l_print_ext_controls, INFO_FL_CTRL | INFO_FL_ALWAYS_COPY), 28843ad3b7a2SSami Tolvanen IOCTL_INFO(VIDIOC_ENUM_FRAMESIZES, v4l_stub_enum_framesizes, v4l_print_frmsizeenum, INFO_FL_CLEAR(v4l2_frmsizeenum, pixel_format)), 28853ad3b7a2SSami Tolvanen IOCTL_INFO(VIDIOC_ENUM_FRAMEINTERVALS, v4l_stub_enum_frameintervals, v4l_print_frmivalenum, INFO_FL_CLEAR(v4l2_frmivalenum, height)), 28863ad3b7a2SSami Tolvanen IOCTL_INFO(VIDIOC_G_ENC_INDEX, v4l_stub_g_enc_index, v4l_print_enc_idx, 0), 28873ad3b7a2SSami Tolvanen IOCTL_INFO(VIDIOC_ENCODER_CMD, v4l_stub_encoder_cmd, v4l_print_encoder_cmd, INFO_FL_PRIO | INFO_FL_CLEAR(v4l2_encoder_cmd, flags)), 28883ad3b7a2SSami Tolvanen IOCTL_INFO(VIDIOC_TRY_ENCODER_CMD, v4l_stub_try_encoder_cmd, v4l_print_encoder_cmd, INFO_FL_CLEAR(v4l2_encoder_cmd, flags)), 28893ad3b7a2SSami Tolvanen IOCTL_INFO(VIDIOC_DECODER_CMD, v4l_stub_decoder_cmd, v4l_print_decoder_cmd, INFO_FL_PRIO), 28903ad3b7a2SSami Tolvanen IOCTL_INFO(VIDIOC_TRY_DECODER_CMD, v4l_stub_try_decoder_cmd, v4l_print_decoder_cmd, 0), 28913ad3b7a2SSami Tolvanen IOCTL_INFO(VIDIOC_DBG_S_REGISTER, v4l_dbg_s_register, v4l_print_dbg_register, 0), 28923ad3b7a2SSami Tolvanen IOCTL_INFO(VIDIOC_DBG_G_REGISTER, v4l_dbg_g_register, v4l_print_dbg_register, 0), 28933ad3b7a2SSami Tolvanen IOCTL_INFO(VIDIOC_S_HW_FREQ_SEEK, v4l_s_hw_freq_seek, v4l_print_hw_freq_seek, INFO_FL_PRIO), 28943ad3b7a2SSami Tolvanen IOCTL_INFO(VIDIOC_S_DV_TIMINGS, v4l_stub_s_dv_timings, v4l_print_dv_timings, INFO_FL_PRIO | INFO_FL_CLEAR(v4l2_dv_timings, bt.flags)), 28953ad3b7a2SSami Tolvanen IOCTL_INFO(VIDIOC_G_DV_TIMINGS, v4l_stub_g_dv_timings, v4l_print_dv_timings, 0), 28963ad3b7a2SSami Tolvanen IOCTL_INFO(VIDIOC_DQEVENT, v4l_dqevent, v4l_print_event, 0), 28973ad3b7a2SSami Tolvanen IOCTL_INFO(VIDIOC_SUBSCRIBE_EVENT, v4l_subscribe_event, v4l_print_event_subscription, 0), 28983ad3b7a2SSami Tolvanen IOCTL_INFO(VIDIOC_UNSUBSCRIBE_EVENT, v4l_unsubscribe_event, v4l_print_event_subscription, 0), 28993ad3b7a2SSami Tolvanen IOCTL_INFO(VIDIOC_CREATE_BUFS, v4l_create_bufs, v4l_print_create_buffers, INFO_FL_PRIO | INFO_FL_QUEUE), 29003ad3b7a2SSami Tolvanen IOCTL_INFO(VIDIOC_PREPARE_BUF, v4l_prepare_buf, v4l_print_buffer, INFO_FL_QUEUE), 29013ad3b7a2SSami Tolvanen IOCTL_INFO(VIDIOC_ENUM_DV_TIMINGS, v4l_stub_enum_dv_timings, v4l_print_enum_dv_timings, INFO_FL_CLEAR(v4l2_enum_dv_timings, pad)), 29023ad3b7a2SSami Tolvanen IOCTL_INFO(VIDIOC_QUERY_DV_TIMINGS, v4l_stub_query_dv_timings, v4l_print_dv_timings, INFO_FL_ALWAYS_COPY), 29033ad3b7a2SSami Tolvanen IOCTL_INFO(VIDIOC_DV_TIMINGS_CAP, v4l_stub_dv_timings_cap, v4l_print_dv_timings_cap, INFO_FL_CLEAR(v4l2_dv_timings_cap, pad)), 29043ad3b7a2SSami Tolvanen IOCTL_INFO(VIDIOC_ENUM_FREQ_BANDS, v4l_enum_freq_bands, v4l_print_freq_band, 0), 29053ad3b7a2SSami Tolvanen IOCTL_INFO(VIDIOC_DBG_G_CHIP_INFO, v4l_dbg_g_chip_info, v4l_print_dbg_chip_info, INFO_FL_CLEAR(v4l2_dbg_chip_info, match)), 29063ad3b7a2SSami Tolvanen IOCTL_INFO(VIDIOC_QUERY_EXT_CTRL, v4l_query_ext_ctrl, v4l_print_query_ext_ctrl, INFO_FL_CTRL | INFO_FL_CLEAR(v4l2_query_ext_ctrl, id)), 29075bc3cb74SMauro Carvalho Chehab }; 29085bc3cb74SMauro Carvalho Chehab #define V4L2_IOCTLS ARRAY_SIZE(v4l2_ioctls) 29095bc3cb74SMauro Carvalho Chehab 291073a11062SHans Verkuil static bool v4l2_is_known_ioctl(unsigned int cmd) 29115bc3cb74SMauro Carvalho Chehab { 29125bc3cb74SMauro Carvalho Chehab if (_IOC_NR(cmd) >= V4L2_IOCTLS) 29135bc3cb74SMauro Carvalho Chehab return false; 29145bc3cb74SMauro Carvalho Chehab return v4l2_ioctls[_IOC_NR(cmd)].ioctl == cmd; 29155bc3cb74SMauro Carvalho Chehab } 29165bc3cb74SMauro Carvalho Chehab 291773a11062SHans Verkuil static struct mutex *v4l2_ioctl_get_lock(struct video_device *vdev, 2918d862bc08SHans Verkuil struct v4l2_fh *vfh, unsigned int cmd, 2919d862bc08SHans Verkuil void *arg) 29205bc3cb74SMauro Carvalho Chehab { 29215bc3cb74SMauro Carvalho Chehab if (_IOC_NR(cmd) >= V4L2_IOCTLS) 29225bc3cb74SMauro Carvalho Chehab return vdev->lock; 2923d862bc08SHans Verkuil if (vfh && vfh->m2m_ctx && 2924d862bc08SHans Verkuil (v4l2_ioctls[_IOC_NR(cmd)].flags & INFO_FL_QUEUE)) { 2925542a522dSEzequiel Garcia if (vfh->m2m_ctx->q_lock) 2926542a522dSEzequiel Garcia return vfh->m2m_ctx->q_lock; 2927d862bc08SHans Verkuil } 29285bc3cb74SMauro Carvalho Chehab if (vdev->queue && vdev->queue->lock && 29295bc3cb74SMauro Carvalho Chehab (v4l2_ioctls[_IOC_NR(cmd)].flags & INFO_FL_QUEUE)) 29305bc3cb74SMauro Carvalho Chehab return vdev->queue->lock; 29315bc3cb74SMauro Carvalho Chehab return vdev->lock; 29325bc3cb74SMauro Carvalho Chehab } 29335bc3cb74SMauro Carvalho Chehab 29345bc3cb74SMauro Carvalho Chehab /* Common ioctl debug function. This function can be used by 29355bc3cb74SMauro Carvalho Chehab external ioctl messages as well as internal V4L ioctl */ 29365bc3cb74SMauro Carvalho Chehab void v4l_printk_ioctl(const char *prefix, unsigned int cmd) 29375bc3cb74SMauro Carvalho Chehab { 29385bc3cb74SMauro Carvalho Chehab const char *dir, *type; 29395bc3cb74SMauro Carvalho Chehab 29405bc3cb74SMauro Carvalho Chehab if (prefix) 29415bc3cb74SMauro Carvalho Chehab printk(KERN_DEBUG "%s: ", prefix); 29425bc3cb74SMauro Carvalho Chehab 29435bc3cb74SMauro Carvalho Chehab switch (_IOC_TYPE(cmd)) { 29445bc3cb74SMauro Carvalho Chehab case 'd': 29455bc3cb74SMauro Carvalho Chehab type = "v4l2_int"; 29465bc3cb74SMauro Carvalho Chehab break; 29475bc3cb74SMauro Carvalho Chehab case 'V': 29485bc3cb74SMauro Carvalho Chehab if (_IOC_NR(cmd) >= V4L2_IOCTLS) { 29495bc3cb74SMauro Carvalho Chehab type = "v4l2"; 29505bc3cb74SMauro Carvalho Chehab break; 29515bc3cb74SMauro Carvalho Chehab } 29525bc3cb74SMauro Carvalho Chehab pr_cont("%s", v4l2_ioctls[_IOC_NR(cmd)].name); 29535bc3cb74SMauro Carvalho Chehab return; 29545bc3cb74SMauro Carvalho Chehab default: 29555bc3cb74SMauro Carvalho Chehab type = "unknown"; 29565bc3cb74SMauro Carvalho Chehab break; 29575bc3cb74SMauro Carvalho Chehab } 29585bc3cb74SMauro Carvalho Chehab 29595bc3cb74SMauro Carvalho Chehab switch (_IOC_DIR(cmd)) { 29605bc3cb74SMauro Carvalho Chehab case _IOC_NONE: dir = "--"; break; 29615bc3cb74SMauro Carvalho Chehab case _IOC_READ: dir = "r-"; break; 29625bc3cb74SMauro Carvalho Chehab case _IOC_WRITE: dir = "-w"; break; 29635bc3cb74SMauro Carvalho Chehab case _IOC_READ | _IOC_WRITE: dir = "rw"; break; 29645bc3cb74SMauro Carvalho Chehab default: dir = "*ERR*"; break; 29655bc3cb74SMauro Carvalho Chehab } 29665bc3cb74SMauro Carvalho Chehab pr_cont("%s ioctl '%c', dir=%s, #%d (0x%08x)", 29675bc3cb74SMauro Carvalho Chehab type, _IOC_TYPE(cmd), dir, _IOC_NR(cmd), cmd); 29685bc3cb74SMauro Carvalho Chehab } 29695bc3cb74SMauro Carvalho Chehab EXPORT_SYMBOL(v4l_printk_ioctl); 29705bc3cb74SMauro Carvalho Chehab 29715bc3cb74SMauro Carvalho Chehab static long __video_do_ioctl(struct file *file, 29725bc3cb74SMauro Carvalho Chehab unsigned int cmd, void *arg) 29735bc3cb74SMauro Carvalho Chehab { 29745bc3cb74SMauro Carvalho Chehab struct video_device *vfd = video_devdata(file); 2975cc6eddcdSHans Verkuil struct mutex *req_queue_lock = NULL; 297673a11062SHans Verkuil struct mutex *lock; /* ioctl serialization mutex */ 29775bc3cb74SMauro Carvalho Chehab const struct v4l2_ioctl_ops *ops = vfd->ioctl_ops; 29785bc3cb74SMauro Carvalho Chehab bool write_only = false; 29795bc3cb74SMauro Carvalho Chehab struct v4l2_ioctl_info default_info; 29805bc3cb74SMauro Carvalho Chehab const struct v4l2_ioctl_info *info; 29815bc3cb74SMauro Carvalho Chehab void *fh = file->private_data; 29825bc3cb74SMauro Carvalho Chehab struct v4l2_fh *vfh = NULL; 298317028cdbSHans Verkuil int dev_debug = vfd->dev_debug; 29845bc3cb74SMauro Carvalho Chehab long ret = -ENOTTY; 29855bc3cb74SMauro Carvalho Chehab 29865bc3cb74SMauro Carvalho Chehab if (ops == NULL) { 29875bc3cb74SMauro Carvalho Chehab pr_warn("%s: has no ioctl_ops.\n", 29885bc3cb74SMauro Carvalho Chehab video_device_node_name(vfd)); 29895bc3cb74SMauro Carvalho Chehab return ret; 29905bc3cb74SMauro Carvalho Chehab } 29915bc3cb74SMauro Carvalho Chehab 2992b7284bb0SRamakrishnan Muthukrishnan if (test_bit(V4L2_FL_USES_V4L2_FH, &vfd->flags)) 29935bc3cb74SMauro Carvalho Chehab vfh = file->private_data; 29945bc3cb74SMauro Carvalho Chehab 2995cc6eddcdSHans Verkuil /* 2996cc6eddcdSHans Verkuil * We need to serialize streamon/off with queueing new requests. 2997cc6eddcdSHans Verkuil * These ioctls may trigger the cancellation of a streaming 2998cc6eddcdSHans Verkuil * operation, and that should not be mixed with queueing a new 2999cc6eddcdSHans Verkuil * request at the same time. 3000cc6eddcdSHans Verkuil */ 3001cc6eddcdSHans Verkuil if (v4l2_device_supports_requests(vfd->v4l2_dev) && 3002cc6eddcdSHans Verkuil (cmd == VIDIOC_STREAMON || cmd == VIDIOC_STREAMOFF)) { 3003cc6eddcdSHans Verkuil req_queue_lock = &vfd->v4l2_dev->mdev->req_queue_mutex; 3004cc6eddcdSHans Verkuil 3005cc6eddcdSHans Verkuil if (mutex_lock_interruptible(req_queue_lock)) 3006cc6eddcdSHans Verkuil return -ERESTARTSYS; 3007cc6eddcdSHans Verkuil } 3008cc6eddcdSHans Verkuil 3009d862bc08SHans Verkuil lock = v4l2_ioctl_get_lock(vfd, vfh, cmd, arg); 301073a11062SHans Verkuil 3011cc6eddcdSHans Verkuil if (lock && mutex_lock_interruptible(lock)) { 3012cc6eddcdSHans Verkuil if (req_queue_lock) 3013cc6eddcdSHans Verkuil mutex_unlock(req_queue_lock); 301473a11062SHans Verkuil return -ERESTARTSYS; 3015cc6eddcdSHans Verkuil } 301673a11062SHans Verkuil 301773a11062SHans Verkuil if (!video_is_registered(vfd)) { 301873a11062SHans Verkuil ret = -ENODEV; 301973a11062SHans Verkuil goto unlock; 302073a11062SHans Verkuil } 302173a11062SHans Verkuil 30225bc3cb74SMauro Carvalho Chehab if (v4l2_is_known_ioctl(cmd)) { 30235bc3cb74SMauro Carvalho Chehab info = &v4l2_ioctls[_IOC_NR(cmd)]; 30245bc3cb74SMauro Carvalho Chehab 30255bc3cb74SMauro Carvalho Chehab if (!test_bit(_IOC_NR(cmd), vfd->valid_ioctls) && 30265bc3cb74SMauro Carvalho Chehab !((info->flags & INFO_FL_CTRL) && vfh && vfh->ctrl_handler)) 30275bc3cb74SMauro Carvalho Chehab goto done; 30285bc3cb74SMauro Carvalho Chehab 3029b7284bb0SRamakrishnan Muthukrishnan if (vfh && (info->flags & INFO_FL_PRIO)) { 30305bc3cb74SMauro Carvalho Chehab ret = v4l2_prio_check(vfd->prio, vfh->prio); 30315bc3cb74SMauro Carvalho Chehab if (ret) 30325bc3cb74SMauro Carvalho Chehab goto done; 30335bc3cb74SMauro Carvalho Chehab } 30345bc3cb74SMauro Carvalho Chehab } else { 30355bc3cb74SMauro Carvalho Chehab default_info.ioctl = cmd; 30365bc3cb74SMauro Carvalho Chehab default_info.flags = 0; 30375bc3cb74SMauro Carvalho Chehab default_info.debug = v4l_print_default; 30385bc3cb74SMauro Carvalho Chehab info = &default_info; 30395bc3cb74SMauro Carvalho Chehab } 30405bc3cb74SMauro Carvalho Chehab 30415bc3cb74SMauro Carvalho Chehab write_only = _IOC_DIR(cmd) == _IOC_WRITE; 30423ad3b7a2SSami Tolvanen if (info != &default_info) { 30433ad3b7a2SSami Tolvanen ret = info->func(ops, file, fh, arg); 30445bc3cb74SMauro Carvalho Chehab } else if (!ops->vidioc_default) { 30455bc3cb74SMauro Carvalho Chehab ret = -ENOTTY; 30465bc3cb74SMauro Carvalho Chehab } else { 30475bc3cb74SMauro Carvalho Chehab ret = ops->vidioc_default(file, fh, 3048b7284bb0SRamakrishnan Muthukrishnan vfh ? v4l2_prio_check(vfd->prio, vfh->prio) >= 0 : 0, 30495bc3cb74SMauro Carvalho Chehab cmd, arg); 30505bc3cb74SMauro Carvalho Chehab } 30515bc3cb74SMauro Carvalho Chehab 30525bc3cb74SMauro Carvalho Chehab done: 305317028cdbSHans Verkuil if (dev_debug & (V4L2_DEV_DEBUG_IOCTL | V4L2_DEV_DEBUG_IOCTL_ARG)) { 305417028cdbSHans Verkuil if (!(dev_debug & V4L2_DEV_DEBUG_STREAMING) && 305517028cdbSHans Verkuil (cmd == VIDIOC_QBUF || cmd == VIDIOC_DQBUF)) 30565983d3bcSHans Verkuil goto unlock; 305717028cdbSHans Verkuil 30585bc3cb74SMauro Carvalho Chehab v4l_printk_ioctl(video_device_node_name(vfd), cmd); 30595bc3cb74SMauro Carvalho Chehab if (ret < 0) 3060505d04bdSHans Verkuil pr_cont(": error %ld", ret); 306117028cdbSHans Verkuil if (!(dev_debug & V4L2_DEV_DEBUG_IOCTL_ARG)) 30625bc3cb74SMauro Carvalho Chehab pr_cont("\n"); 30635bc3cb74SMauro Carvalho Chehab else if (_IOC_DIR(cmd) == _IOC_NONE) 30645bc3cb74SMauro Carvalho Chehab info->debug(arg, write_only); 30655bc3cb74SMauro Carvalho Chehab else { 30665bc3cb74SMauro Carvalho Chehab pr_cont(": "); 30675bc3cb74SMauro Carvalho Chehab info->debug(arg, write_only); 30685bc3cb74SMauro Carvalho Chehab } 30695bc3cb74SMauro Carvalho Chehab } 30705bc3cb74SMauro Carvalho Chehab 307173a11062SHans Verkuil unlock: 307273a11062SHans Verkuil if (lock) 307373a11062SHans Verkuil mutex_unlock(lock); 3074cc6eddcdSHans Verkuil if (req_queue_lock) 3075cc6eddcdSHans Verkuil mutex_unlock(req_queue_lock); 30765bc3cb74SMauro Carvalho Chehab return ret; 30775bc3cb74SMauro Carvalho Chehab } 30785bc3cb74SMauro Carvalho Chehab 30795bc3cb74SMauro Carvalho Chehab static int check_array_args(unsigned int cmd, void *parg, size_t *array_size, 3080ba2d35c1SHans Verkuil void __user **user_ptr, void ***kernel_ptr) 30815bc3cb74SMauro Carvalho Chehab { 30825bc3cb74SMauro Carvalho Chehab int ret = 0; 30835bc3cb74SMauro Carvalho Chehab 30845bc3cb74SMauro Carvalho Chehab switch (cmd) { 308596b1a702SHans Verkuil case VIDIOC_PREPARE_BUF: 30865bc3cb74SMauro Carvalho Chehab case VIDIOC_QUERYBUF: 30875bc3cb74SMauro Carvalho Chehab case VIDIOC_QBUF: 30885bc3cb74SMauro Carvalho Chehab case VIDIOC_DQBUF: { 30895bc3cb74SMauro Carvalho Chehab struct v4l2_buffer *buf = parg; 30905bc3cb74SMauro Carvalho Chehab 30915bc3cb74SMauro Carvalho Chehab if (V4L2_TYPE_IS_MULTIPLANAR(buf->type) && buf->length > 0) { 30925bc3cb74SMauro Carvalho Chehab if (buf->length > VIDEO_MAX_PLANES) { 30935bc3cb74SMauro Carvalho Chehab ret = -EINVAL; 30945bc3cb74SMauro Carvalho Chehab break; 30955bc3cb74SMauro Carvalho Chehab } 30965bc3cb74SMauro Carvalho Chehab *user_ptr = (void __user *)buf->m.planes; 3097ba2d35c1SHans Verkuil *kernel_ptr = (void **)&buf->m.planes; 30985bc3cb74SMauro Carvalho Chehab *array_size = sizeof(struct v4l2_plane) * buf->length; 30995bc3cb74SMauro Carvalho Chehab ret = 1; 31005bc3cb74SMauro Carvalho Chehab } 31015bc3cb74SMauro Carvalho Chehab break; 31025bc3cb74SMauro Carvalho Chehab } 31035bc3cb74SMauro Carvalho Chehab 3104dd519bb3SHans Verkuil case VIDIOC_G_EDID: 3105dd519bb3SHans Verkuil case VIDIOC_S_EDID: { 3106dd519bb3SHans Verkuil struct v4l2_edid *edid = parg; 3107ed45ce2cSHans Verkuil 3108ed45ce2cSHans Verkuil if (edid->blocks) { 31091b8b10ccSHans Verkuil if (edid->blocks > 256) { 31101b8b10ccSHans Verkuil ret = -EINVAL; 31111b8b10ccSHans Verkuil break; 31121b8b10ccSHans Verkuil } 3113ed45ce2cSHans Verkuil *user_ptr = (void __user *)edid->edid; 3114ba2d35c1SHans Verkuil *kernel_ptr = (void **)&edid->edid; 3115ed45ce2cSHans Verkuil *array_size = edid->blocks * 128; 3116ed45ce2cSHans Verkuil ret = 1; 3117ed45ce2cSHans Verkuil } 3118ed45ce2cSHans Verkuil break; 3119ed45ce2cSHans Verkuil } 3120ed45ce2cSHans Verkuil 31215bc3cb74SMauro Carvalho Chehab case VIDIOC_S_EXT_CTRLS: 31225bc3cb74SMauro Carvalho Chehab case VIDIOC_G_EXT_CTRLS: 31235bc3cb74SMauro Carvalho Chehab case VIDIOC_TRY_EXT_CTRLS: { 31245bc3cb74SMauro Carvalho Chehab struct v4l2_ext_controls *ctrls = parg; 31255bc3cb74SMauro Carvalho Chehab 31265bc3cb74SMauro Carvalho Chehab if (ctrls->count != 0) { 31275bc3cb74SMauro Carvalho Chehab if (ctrls->count > V4L2_CID_MAX_CTRLS) { 31285bc3cb74SMauro Carvalho Chehab ret = -EINVAL; 31295bc3cb74SMauro Carvalho Chehab break; 31305bc3cb74SMauro Carvalho Chehab } 31315bc3cb74SMauro Carvalho Chehab *user_ptr = (void __user *)ctrls->controls; 3132ba2d35c1SHans Verkuil *kernel_ptr = (void **)&ctrls->controls; 31335bc3cb74SMauro Carvalho Chehab *array_size = sizeof(struct v4l2_ext_control) 31345bc3cb74SMauro Carvalho Chehab * ctrls->count; 31355bc3cb74SMauro Carvalho Chehab ret = 1; 31365bc3cb74SMauro Carvalho Chehab } 31375bc3cb74SMauro Carvalho Chehab break; 31385bc3cb74SMauro Carvalho Chehab } 3139a418bb3fSLaurent Pinchart 3140a418bb3fSLaurent Pinchart case VIDIOC_SUBDEV_G_ROUTING: 3141a418bb3fSLaurent Pinchart case VIDIOC_SUBDEV_S_ROUTING: { 3142a418bb3fSLaurent Pinchart struct v4l2_subdev_routing *routing = parg; 3143a418bb3fSLaurent Pinchart 3144a418bb3fSLaurent Pinchart if (routing->num_routes > 256) 3145a418bb3fSLaurent Pinchart return -E2BIG; 3146a418bb3fSLaurent Pinchart 3147a418bb3fSLaurent Pinchart *user_ptr = u64_to_user_ptr(routing->routes); 3148a418bb3fSLaurent Pinchart *kernel_ptr = (void **)&routing->routes; 3149a418bb3fSLaurent Pinchart *array_size = sizeof(struct v4l2_subdev_route) 3150a418bb3fSLaurent Pinchart * routing->num_routes; 3151a418bb3fSLaurent Pinchart ret = 1; 3152a418bb3fSLaurent Pinchart break; 3153a418bb3fSLaurent Pinchart } 31545bc3cb74SMauro Carvalho Chehab } 31555bc3cb74SMauro Carvalho Chehab 31565bc3cb74SMauro Carvalho Chehab return ret; 31575bc3cb74SMauro Carvalho Chehab } 31585bc3cb74SMauro Carvalho Chehab 3159c8ef1a60SArnd Bergmann static unsigned int video_translate_cmd(unsigned int cmd) 3160c8ef1a60SArnd Bergmann { 3161c344f07aSArnd Bergmann #if !defined(CONFIG_64BIT) && defined(CONFIG_COMPAT_32BIT_TIME) 31621a6c0b36SArnd Bergmann switch (cmd) { 31631a6c0b36SArnd Bergmann case VIDIOC_DQEVENT_TIME32: 31641a6c0b36SArnd Bergmann return VIDIOC_DQEVENT; 3165577c89b0SArnd Bergmann case VIDIOC_QUERYBUF_TIME32: 3166577c89b0SArnd Bergmann return VIDIOC_QUERYBUF; 3167577c89b0SArnd Bergmann case VIDIOC_QBUF_TIME32: 3168577c89b0SArnd Bergmann return VIDIOC_QBUF; 3169577c89b0SArnd Bergmann case VIDIOC_DQBUF_TIME32: 3170577c89b0SArnd Bergmann return VIDIOC_DQBUF; 3171577c89b0SArnd Bergmann case VIDIOC_PREPARE_BUF_TIME32: 3172577c89b0SArnd Bergmann return VIDIOC_PREPARE_BUF; 31731a6c0b36SArnd Bergmann } 3174c344f07aSArnd Bergmann #endif 31758dbcc3faSArnd Bergmann if (in_compat_syscall()) 31768dbcc3faSArnd Bergmann return v4l2_compat_translate_cmd(cmd); 31771a6c0b36SArnd Bergmann 3178c8ef1a60SArnd Bergmann return cmd; 3179c8ef1a60SArnd Bergmann } 3180c8ef1a60SArnd Bergmann 31818dbcc3faSArnd Bergmann static int video_get_user(void __user *arg, void *parg, 31828dbcc3faSArnd Bergmann unsigned int real_cmd, unsigned int cmd, 3183c8ef1a60SArnd Bergmann bool *always_copy) 3184c8ef1a60SArnd Bergmann { 31858dbcc3faSArnd Bergmann unsigned int n = _IOC_SIZE(real_cmd); 31868dbcc3faSArnd Bergmann int err = 0; 3187c8ef1a60SArnd Bergmann 3188c8ef1a60SArnd Bergmann if (!(_IOC_DIR(cmd) & _IOC_WRITE)) { 3189c8ef1a60SArnd Bergmann /* read-only ioctl */ 3190c8ef1a60SArnd Bergmann memset(parg, 0, n); 3191c8ef1a60SArnd Bergmann return 0; 3192c8ef1a60SArnd Bergmann } 3193c8ef1a60SArnd Bergmann 31948dbcc3faSArnd Bergmann /* 31958dbcc3faSArnd Bergmann * In some cases, only a few fields are used as input, 31968dbcc3faSArnd Bergmann * i.e. when the app sets "index" and then the driver 31978dbcc3faSArnd Bergmann * fills in the rest of the structure for the thing 31988dbcc3faSArnd Bergmann * with that index. We only need to copy up the first 31998dbcc3faSArnd Bergmann * non-input field. 32008dbcc3faSArnd Bergmann */ 32018dbcc3faSArnd Bergmann if (v4l2_is_known_ioctl(real_cmd)) { 32028dbcc3faSArnd Bergmann u32 flags = v4l2_ioctls[_IOC_NR(real_cmd)].flags; 32038dbcc3faSArnd Bergmann 32048dbcc3faSArnd Bergmann if (flags & INFO_FL_CLEAR_MASK) 32058dbcc3faSArnd Bergmann n = (flags & INFO_FL_CLEAR_MASK) >> 16; 32068dbcc3faSArnd Bergmann *always_copy = flags & INFO_FL_ALWAYS_COPY; 32078dbcc3faSArnd Bergmann } 32088dbcc3faSArnd Bergmann 32098dbcc3faSArnd Bergmann if (cmd == real_cmd) { 32108dbcc3faSArnd Bergmann if (copy_from_user(parg, (void __user *)arg, n)) 32118dbcc3faSArnd Bergmann err = -EFAULT; 32128dbcc3faSArnd Bergmann } else if (in_compat_syscall()) { 32137b53cca7SArnd Bergmann memset(parg, 0, n); 32148dbcc3faSArnd Bergmann err = v4l2_compat_get_user(arg, parg, cmd); 32158dbcc3faSArnd Bergmann } else { 32167b53cca7SArnd Bergmann memset(parg, 0, n); 3217c344f07aSArnd Bergmann #if !defined(CONFIG_64BIT) && defined(CONFIG_COMPAT_32BIT_TIME) 3218c8ef1a60SArnd Bergmann switch (cmd) { 3219577c89b0SArnd Bergmann case VIDIOC_QUERYBUF_TIME32: 3220577c89b0SArnd Bergmann case VIDIOC_QBUF_TIME32: 3221577c89b0SArnd Bergmann case VIDIOC_DQBUF_TIME32: 3222577c89b0SArnd Bergmann case VIDIOC_PREPARE_BUF_TIME32: { 3223577c89b0SArnd Bergmann struct v4l2_buffer_time32 vb32; 3224577c89b0SArnd Bergmann struct v4l2_buffer *vb = parg; 3225577c89b0SArnd Bergmann 3226577c89b0SArnd Bergmann if (copy_from_user(&vb32, arg, sizeof(vb32))) 3227577c89b0SArnd Bergmann return -EFAULT; 3228577c89b0SArnd Bergmann 3229577c89b0SArnd Bergmann *vb = (struct v4l2_buffer) { 3230577c89b0SArnd Bergmann .index = vb32.index, 3231577c89b0SArnd Bergmann .type = vb32.type, 3232577c89b0SArnd Bergmann .bytesused = vb32.bytesused, 3233577c89b0SArnd Bergmann .flags = vb32.flags, 3234577c89b0SArnd Bergmann .field = vb32.field, 3235577c89b0SArnd Bergmann .timestamp.tv_sec = vb32.timestamp.tv_sec, 3236577c89b0SArnd Bergmann .timestamp.tv_usec = vb32.timestamp.tv_usec, 3237577c89b0SArnd Bergmann .timecode = vb32.timecode, 3238577c89b0SArnd Bergmann .sequence = vb32.sequence, 3239577c89b0SArnd Bergmann .memory = vb32.memory, 3240577c89b0SArnd Bergmann .m.userptr = vb32.m.userptr, 3241577c89b0SArnd Bergmann .length = vb32.length, 3242577c89b0SArnd Bergmann .request_fd = vb32.request_fd, 3243577c89b0SArnd Bergmann }; 3244577c89b0SArnd Bergmann break; 3245577c89b0SArnd Bergmann } 3246c8ef1a60SArnd Bergmann } 3247c344f07aSArnd Bergmann #endif 32488dbcc3faSArnd Bergmann } 3249c8ef1a60SArnd Bergmann 3250c8ef1a60SArnd Bergmann /* zero out anything we don't copy from userspace */ 32518dbcc3faSArnd Bergmann if (!err && n < _IOC_SIZE(real_cmd)) 32528dbcc3faSArnd Bergmann memset((u8 *)parg + n, 0, _IOC_SIZE(real_cmd) - n); 32538dbcc3faSArnd Bergmann return err; 3254c8ef1a60SArnd Bergmann } 3255c8ef1a60SArnd Bergmann 32568dbcc3faSArnd Bergmann static int video_put_user(void __user *arg, void *parg, 32578dbcc3faSArnd Bergmann unsigned int real_cmd, unsigned int cmd) 3258c8ef1a60SArnd Bergmann { 3259c8ef1a60SArnd Bergmann if (!(_IOC_DIR(cmd) & _IOC_READ)) 3260c8ef1a60SArnd Bergmann return 0; 3261c8ef1a60SArnd Bergmann 32628dbcc3faSArnd Bergmann if (cmd == real_cmd) { 32638dbcc3faSArnd Bergmann /* Copy results into user buffer */ 32648dbcc3faSArnd Bergmann if (copy_to_user(arg, parg, _IOC_SIZE(cmd))) 32658dbcc3faSArnd Bergmann return -EFAULT; 32668dbcc3faSArnd Bergmann return 0; 32678dbcc3faSArnd Bergmann } 32688dbcc3faSArnd Bergmann 32698dbcc3faSArnd Bergmann if (in_compat_syscall()) 32708dbcc3faSArnd Bergmann return v4l2_compat_put_user(arg, parg, cmd); 32718dbcc3faSArnd Bergmann 3272c344f07aSArnd Bergmann #if !defined(CONFIG_64BIT) && defined(CONFIG_COMPAT_32BIT_TIME) 3273c8ef1a60SArnd Bergmann switch (cmd) { 32741a6c0b36SArnd Bergmann case VIDIOC_DQEVENT_TIME32: { 32751a6c0b36SArnd Bergmann struct v4l2_event *ev = parg; 32764ffb879eSPeilin Ye struct v4l2_event_time32 ev32; 32774ffb879eSPeilin Ye 32784ffb879eSPeilin Ye memset(&ev32, 0, sizeof(ev32)); 32794ffb879eSPeilin Ye 32804ffb879eSPeilin Ye ev32.type = ev->type; 32814ffb879eSPeilin Ye ev32.pending = ev->pending; 32824ffb879eSPeilin Ye ev32.sequence = ev->sequence; 32834ffb879eSPeilin Ye ev32.timestamp.tv_sec = ev->timestamp.tv_sec; 32844ffb879eSPeilin Ye ev32.timestamp.tv_nsec = ev->timestamp.tv_nsec; 32854ffb879eSPeilin Ye ev32.id = ev->id; 32861a6c0b36SArnd Bergmann 32871a6c0b36SArnd Bergmann memcpy(&ev32.u, &ev->u, sizeof(ev->u)); 32881a6c0b36SArnd Bergmann memcpy(&ev32.reserved, &ev->reserved, sizeof(ev->reserved)); 32891a6c0b36SArnd Bergmann 32901a6c0b36SArnd Bergmann if (copy_to_user(arg, &ev32, sizeof(ev32))) 32911a6c0b36SArnd Bergmann return -EFAULT; 32921a6c0b36SArnd Bergmann break; 32931a6c0b36SArnd Bergmann } 3294577c89b0SArnd Bergmann case VIDIOC_QUERYBUF_TIME32: 3295577c89b0SArnd Bergmann case VIDIOC_QBUF_TIME32: 3296577c89b0SArnd Bergmann case VIDIOC_DQBUF_TIME32: 3297577c89b0SArnd Bergmann case VIDIOC_PREPARE_BUF_TIME32: { 3298577c89b0SArnd Bergmann struct v4l2_buffer *vb = parg; 32994ffb879eSPeilin Ye struct v4l2_buffer_time32 vb32; 33004ffb879eSPeilin Ye 33014ffb879eSPeilin Ye memset(&vb32, 0, sizeof(vb32)); 33024ffb879eSPeilin Ye 33034ffb879eSPeilin Ye vb32.index = vb->index; 33044ffb879eSPeilin Ye vb32.type = vb->type; 33054ffb879eSPeilin Ye vb32.bytesused = vb->bytesused; 33064ffb879eSPeilin Ye vb32.flags = vb->flags; 33074ffb879eSPeilin Ye vb32.field = vb->field; 33084ffb879eSPeilin Ye vb32.timestamp.tv_sec = vb->timestamp.tv_sec; 33094ffb879eSPeilin Ye vb32.timestamp.tv_usec = vb->timestamp.tv_usec; 33104ffb879eSPeilin Ye vb32.timecode = vb->timecode; 33114ffb879eSPeilin Ye vb32.sequence = vb->sequence; 33124ffb879eSPeilin Ye vb32.memory = vb->memory; 33134ffb879eSPeilin Ye vb32.m.userptr = vb->m.userptr; 33144ffb879eSPeilin Ye vb32.length = vb->length; 33154ffb879eSPeilin Ye vb32.request_fd = vb->request_fd; 3316577c89b0SArnd Bergmann 3317577c89b0SArnd Bergmann if (copy_to_user(arg, &vb32, sizeof(vb32))) 3318577c89b0SArnd Bergmann return -EFAULT; 3319577c89b0SArnd Bergmann break; 3320577c89b0SArnd Bergmann } 3321c8ef1a60SArnd Bergmann } 3322c344f07aSArnd Bergmann #endif 3323c8ef1a60SArnd Bergmann 3324c8ef1a60SArnd Bergmann return 0; 3325c8ef1a60SArnd Bergmann } 3326c8ef1a60SArnd Bergmann 33275bc3cb74SMauro Carvalho Chehab long 3328c8ef1a60SArnd Bergmann video_usercopy(struct file *file, unsigned int orig_cmd, unsigned long arg, 33295bc3cb74SMauro Carvalho Chehab v4l2_kioctl func) 33305bc3cb74SMauro Carvalho Chehab { 33315bc3cb74SMauro Carvalho Chehab char sbuf[128]; 3332fb18802aSSakari Ailus void *mbuf = NULL, *array_buf = NULL; 33335bc3cb74SMauro Carvalho Chehab void *parg = (void *)arg; 33345bc3cb74SMauro Carvalho Chehab long err = -EINVAL; 33355bc3cb74SMauro Carvalho Chehab bool has_array_args; 3336043f77edSHans Verkuil bool always_copy = false; 33375bc3cb74SMauro Carvalho Chehab size_t array_size = 0; 33385bc3cb74SMauro Carvalho Chehab void __user *user_ptr = NULL; 33395bc3cb74SMauro Carvalho Chehab void **kernel_ptr = NULL; 3340c8ef1a60SArnd Bergmann unsigned int cmd = video_translate_cmd(orig_cmd); 3341f8a695c4SMauro Carvalho Chehab const size_t ioc_size = _IOC_SIZE(cmd); 33425bc3cb74SMauro Carvalho Chehab 33435bc3cb74SMauro Carvalho Chehab /* Copy arguments into temp kernel buffer */ 33445bc3cb74SMauro Carvalho Chehab if (_IOC_DIR(cmd) != _IOC_NONE) { 3345f8a695c4SMauro Carvalho Chehab if (ioc_size <= sizeof(sbuf)) { 33465bc3cb74SMauro Carvalho Chehab parg = sbuf; 33475bc3cb74SMauro Carvalho Chehab } else { 33485bc3cb74SMauro Carvalho Chehab /* too big to allocate from stack */ 334962a12551SSakari Ailus mbuf = kmalloc(ioc_size, GFP_KERNEL); 33505bc3cb74SMauro Carvalho Chehab if (NULL == mbuf) 33515bc3cb74SMauro Carvalho Chehab return -ENOMEM; 33525bc3cb74SMauro Carvalho Chehab parg = mbuf; 33535bc3cb74SMauro Carvalho Chehab } 33545bc3cb74SMauro Carvalho Chehab 33558dbcc3faSArnd Bergmann err = video_get_user((void __user *)arg, parg, cmd, 33568dbcc3faSArnd Bergmann orig_cmd, &always_copy); 3357c8ef1a60SArnd Bergmann if (err) 33585bc3cb74SMauro Carvalho Chehab goto out; 33591dc8b65cSArnd Bergmann } 33605bc3cb74SMauro Carvalho Chehab 33615bc3cb74SMauro Carvalho Chehab err = check_array_args(cmd, parg, &array_size, &user_ptr, &kernel_ptr); 33625bc3cb74SMauro Carvalho Chehab if (err < 0) 33635bc3cb74SMauro Carvalho Chehab goto out; 33645bc3cb74SMauro Carvalho Chehab has_array_args = err; 33655bc3cb74SMauro Carvalho Chehab 33665bc3cb74SMauro Carvalho Chehab if (has_array_args) { 3367fb18802aSSakari Ailus array_buf = kvmalloc(array_size, GFP_KERNEL); 33685bc3cb74SMauro Carvalho Chehab err = -ENOMEM; 3369fb18802aSSakari Ailus if (array_buf == NULL) 3370f0da34f3SHans Verkuil goto out; 33718dbcc3faSArnd Bergmann if (in_compat_syscall()) 3372fb18802aSSakari Ailus err = v4l2_compat_get_array_args(file, array_buf, 3373fb18802aSSakari Ailus user_ptr, array_size, 3374fb18802aSSakari Ailus orig_cmd, parg); 33758dbcc3faSArnd Bergmann else 3376fb18802aSSakari Ailus err = copy_from_user(array_buf, user_ptr, array_size) ? 33778dbcc3faSArnd Bergmann -EFAULT : 0; 33788dbcc3faSArnd Bergmann if (err) 3379f0da34f3SHans Verkuil goto out; 3380fb18802aSSakari Ailus *kernel_ptr = array_buf; 33815bc3cb74SMauro Carvalho Chehab } 33825bc3cb74SMauro Carvalho Chehab 33835bc3cb74SMauro Carvalho Chehab /* Handles IOCTL */ 33845bc3cb74SMauro Carvalho Chehab err = func(file, cmd, parg); 3385181a4a2dSHans Verkuil if (err == -ENOTTY || err == -ENOIOCTLCMD) { 33865bc3cb74SMauro Carvalho Chehab err = -ENOTTY; 3387181a4a2dSHans Verkuil goto out; 3388181a4a2dSHans Verkuil } 3389181a4a2dSHans Verkuil 3390aa32f4c0SHans Verkuil if (err == 0) { 3391aa32f4c0SHans Verkuil if (cmd == VIDIOC_DQBUF) 3392aa32f4c0SHans Verkuil trace_v4l2_dqbuf(video_devdata(file)->minor, parg); 3393aa32f4c0SHans Verkuil else if (cmd == VIDIOC_QBUF) 3394aa32f4c0SHans Verkuil trace_v4l2_qbuf(video_devdata(file)->minor, parg); 3395aa32f4c0SHans Verkuil } 33965bc3cb74SMauro Carvalho Chehab 3397f0da34f3SHans Verkuil /* 3398f0da34f3SHans Verkuil * Some ioctls can return an error, but still have valid 3399f0da34f3SHans Verkuil * results that must be returned. 3400a418bb3fSLaurent Pinchart * 3401a418bb3fSLaurent Pinchart * FIXME: subdev IOCTLS are partially handled here and partially in 3402a418bb3fSLaurent Pinchart * v4l2-subdev.c and the 'always_copy' flag can only be set for IOCTLS 3403a418bb3fSLaurent Pinchart * defined here as part of the 'v4l2_ioctls' array. As 3404a418bb3fSLaurent Pinchart * VIDIOC_SUBDEV_G_ROUTING needs to return results to applications even 3405a418bb3fSLaurent Pinchart * in case of failure, but it is not defined here as part of the 3406a418bb3fSLaurent Pinchart * 'v4l2_ioctls' array, insert an ad-hoc check to address that. 3407f0da34f3SHans Verkuil */ 3408a418bb3fSLaurent Pinchart if (err < 0 && !always_copy && cmd != VIDIOC_SUBDEV_G_ROUTING) 3409f0da34f3SHans Verkuil goto out; 3410f0da34f3SHans Verkuil 34115bc3cb74SMauro Carvalho Chehab if (has_array_args) { 3412ba2d35c1SHans Verkuil *kernel_ptr = (void __force *)user_ptr; 34138dbcc3faSArnd Bergmann if (in_compat_syscall()) { 34148dbcc3faSArnd Bergmann int put_err; 34158dbcc3faSArnd Bergmann 3416fb18802aSSakari Ailus put_err = v4l2_compat_put_array_args(file, user_ptr, 3417fb18802aSSakari Ailus array_buf, 3418fb18802aSSakari Ailus array_size, 3419fb18802aSSakari Ailus orig_cmd, parg); 34208dbcc3faSArnd Bergmann if (put_err) 34218dbcc3faSArnd Bergmann err = put_err; 3422fb18802aSSakari Ailus } else if (copy_to_user(user_ptr, array_buf, array_size)) { 34235bc3cb74SMauro Carvalho Chehab err = -EFAULT; 34248dbcc3faSArnd Bergmann } 34255bc3cb74SMauro Carvalho Chehab } 34265bc3cb74SMauro Carvalho Chehab 34278dbcc3faSArnd Bergmann if (video_put_user((void __user *)arg, parg, cmd, orig_cmd)) 34285bc3cb74SMauro Carvalho Chehab err = -EFAULT; 34295bc3cb74SMauro Carvalho Chehab out: 3430fb18802aSSakari Ailus kvfree(array_buf); 343162a12551SSakari Ailus kfree(mbuf); 34325bc3cb74SMauro Carvalho Chehab return err; 34335bc3cb74SMauro Carvalho Chehab } 34345bc3cb74SMauro Carvalho Chehab 34355bc3cb74SMauro Carvalho Chehab long video_ioctl2(struct file *file, 34365bc3cb74SMauro Carvalho Chehab unsigned int cmd, unsigned long arg) 34375bc3cb74SMauro Carvalho Chehab { 34385bc3cb74SMauro Carvalho Chehab return video_usercopy(file, cmd, arg, __video_do_ioctl); 34395bc3cb74SMauro Carvalho Chehab } 34405bc3cb74SMauro Carvalho Chehab EXPORT_SYMBOL(video_ioctl2); 3441