15bc3cb74SMauro Carvalho Chehab /* 25bc3cb74SMauro Carvalho Chehab * Video capture interface for Linux version 2 35bc3cb74SMauro Carvalho Chehab * 45bc3cb74SMauro Carvalho Chehab * A generic framework to process V4L2 ioctl commands. 55bc3cb74SMauro Carvalho Chehab * 65bc3cb74SMauro Carvalho Chehab * This program is free software; you can redistribute it and/or 75bc3cb74SMauro Carvalho Chehab * modify it under the terms of the GNU General Public License 85bc3cb74SMauro Carvalho Chehab * as published by the Free Software Foundation; either version 95bc3cb74SMauro Carvalho Chehab * 2 of the License, or (at your option) any later version. 105bc3cb74SMauro Carvalho Chehab * 115bc3cb74SMauro Carvalho Chehab * Authors: Alan Cox, <alan@lxorguk.ukuu.org.uk> (version 1) 1232590819SMauro Carvalho Chehab * Mauro Carvalho Chehab <mchehab@kernel.org> (version 2) 135bc3cb74SMauro Carvalho Chehab */ 145bc3cb74SMauro Carvalho Chehab 15758d90e1STomasz Figa #include <linux/mm.h> 165bc3cb74SMauro Carvalho Chehab #include <linux/module.h> 175bc3cb74SMauro Carvalho Chehab #include <linux/slab.h> 185bc3cb74SMauro Carvalho Chehab #include <linux/types.h> 195bc3cb74SMauro Carvalho Chehab #include <linux/kernel.h> 205bc3cb74SMauro Carvalho Chehab #include <linux/version.h> 215bc3cb74SMauro Carvalho Chehab 225bc3cb74SMauro Carvalho Chehab #include <linux/videodev2.h> 235bc3cb74SMauro Carvalho Chehab 245bc3cb74SMauro Carvalho Chehab #include <media/v4l2-common.h> 255bc3cb74SMauro Carvalho Chehab #include <media/v4l2-ioctl.h> 265bc3cb74SMauro Carvalho Chehab #include <media/v4l2-ctrls.h> 275bc3cb74SMauro Carvalho Chehab #include <media/v4l2-fh.h> 285bc3cb74SMauro Carvalho Chehab #include <media/v4l2-event.h> 295bc3cb74SMauro Carvalho Chehab #include <media/v4l2-device.h> 30c139990eSJunghak Sung #include <media/videobuf2-v4l2.h> 3177fa4e07SShuah Khan #include <media/v4l2-mc.h> 32d862bc08SHans Verkuil #include <media/v4l2-mem2mem.h> 335bc3cb74SMauro Carvalho Chehab 34aa32f4c0SHans Verkuil #include <trace/events/v4l2.h> 35aa32f4c0SHans Verkuil 365bc3cb74SMauro Carvalho Chehab /* Zero out the end of the struct pointed to by p. Everything after, but 375bc3cb74SMauro Carvalho Chehab * not including, the specified field is cleared. */ 385bc3cb74SMauro Carvalho Chehab #define CLEAR_AFTER_FIELD(p, field) \ 395bc3cb74SMauro Carvalho Chehab memset((u8 *)(p) + offsetof(typeof(*(p)), field) + sizeof((p)->field), \ 405bc3cb74SMauro Carvalho Chehab 0, sizeof(*(p)) - offsetof(typeof(*(p)), field) - sizeof((p)->field)) 415bc3cb74SMauro Carvalho Chehab 4273f35418SHans Verkuil #define is_valid_ioctl(vfd, cmd) test_bit(_IOC_NR(cmd), (vfd)->valid_ioctls) 4373f35418SHans Verkuil 445bc3cb74SMauro Carvalho Chehab struct std_descr { 455bc3cb74SMauro Carvalho Chehab v4l2_std_id std; 465bc3cb74SMauro Carvalho Chehab const char *descr; 475bc3cb74SMauro Carvalho Chehab }; 485bc3cb74SMauro Carvalho Chehab 495bc3cb74SMauro Carvalho Chehab static const struct std_descr standards[] = { 505bc3cb74SMauro Carvalho Chehab { V4L2_STD_NTSC, "NTSC" }, 515bc3cb74SMauro Carvalho Chehab { V4L2_STD_NTSC_M, "NTSC-M" }, 525bc3cb74SMauro Carvalho Chehab { V4L2_STD_NTSC_M_JP, "NTSC-M-JP" }, 535bc3cb74SMauro Carvalho Chehab { V4L2_STD_NTSC_M_KR, "NTSC-M-KR" }, 545bc3cb74SMauro Carvalho Chehab { V4L2_STD_NTSC_443, "NTSC-443" }, 555bc3cb74SMauro Carvalho Chehab { V4L2_STD_PAL, "PAL" }, 565bc3cb74SMauro Carvalho Chehab { V4L2_STD_PAL_BG, "PAL-BG" }, 575bc3cb74SMauro Carvalho Chehab { V4L2_STD_PAL_B, "PAL-B" }, 585bc3cb74SMauro Carvalho Chehab { V4L2_STD_PAL_B1, "PAL-B1" }, 595bc3cb74SMauro Carvalho Chehab { V4L2_STD_PAL_G, "PAL-G" }, 605bc3cb74SMauro Carvalho Chehab { V4L2_STD_PAL_H, "PAL-H" }, 615bc3cb74SMauro Carvalho Chehab { V4L2_STD_PAL_I, "PAL-I" }, 625bc3cb74SMauro Carvalho Chehab { V4L2_STD_PAL_DK, "PAL-DK" }, 635bc3cb74SMauro Carvalho Chehab { V4L2_STD_PAL_D, "PAL-D" }, 645bc3cb74SMauro Carvalho Chehab { V4L2_STD_PAL_D1, "PAL-D1" }, 655bc3cb74SMauro Carvalho Chehab { V4L2_STD_PAL_K, "PAL-K" }, 665bc3cb74SMauro Carvalho Chehab { V4L2_STD_PAL_M, "PAL-M" }, 675bc3cb74SMauro Carvalho Chehab { V4L2_STD_PAL_N, "PAL-N" }, 685bc3cb74SMauro Carvalho Chehab { V4L2_STD_PAL_Nc, "PAL-Nc" }, 695bc3cb74SMauro Carvalho Chehab { V4L2_STD_PAL_60, "PAL-60" }, 705bc3cb74SMauro Carvalho Chehab { V4L2_STD_SECAM, "SECAM" }, 715bc3cb74SMauro Carvalho Chehab { V4L2_STD_SECAM_B, "SECAM-B" }, 725bc3cb74SMauro Carvalho Chehab { V4L2_STD_SECAM_G, "SECAM-G" }, 735bc3cb74SMauro Carvalho Chehab { V4L2_STD_SECAM_H, "SECAM-H" }, 745bc3cb74SMauro Carvalho Chehab { V4L2_STD_SECAM_DK, "SECAM-DK" }, 755bc3cb74SMauro Carvalho Chehab { V4L2_STD_SECAM_D, "SECAM-D" }, 765bc3cb74SMauro Carvalho Chehab { V4L2_STD_SECAM_K, "SECAM-K" }, 775bc3cb74SMauro Carvalho Chehab { V4L2_STD_SECAM_K1, "SECAM-K1" }, 785bc3cb74SMauro Carvalho Chehab { V4L2_STD_SECAM_L, "SECAM-L" }, 795bc3cb74SMauro Carvalho Chehab { V4L2_STD_SECAM_LC, "SECAM-Lc" }, 805bc3cb74SMauro Carvalho Chehab { 0, "Unknown" } 815bc3cb74SMauro Carvalho Chehab }; 825bc3cb74SMauro Carvalho Chehab 835bc3cb74SMauro Carvalho Chehab /* video4linux standard ID conversion to standard name 845bc3cb74SMauro Carvalho Chehab */ 855bc3cb74SMauro Carvalho Chehab const char *v4l2_norm_to_name(v4l2_std_id id) 865bc3cb74SMauro Carvalho Chehab { 875bc3cb74SMauro Carvalho Chehab u32 myid = id; 885bc3cb74SMauro Carvalho Chehab int i; 895bc3cb74SMauro Carvalho Chehab 905bc3cb74SMauro Carvalho Chehab /* HACK: ppc32 architecture doesn't have __ucmpdi2 function to handle 915bc3cb74SMauro Carvalho Chehab 64 bit comparations. So, on that architecture, with some gcc 925bc3cb74SMauro Carvalho Chehab variants, compilation fails. Currently, the max value is 30bit wide. 935bc3cb74SMauro Carvalho Chehab */ 945bc3cb74SMauro Carvalho Chehab BUG_ON(myid != id); 955bc3cb74SMauro Carvalho Chehab 965bc3cb74SMauro Carvalho Chehab for (i = 0; standards[i].std; i++) 975bc3cb74SMauro Carvalho Chehab if (myid == standards[i].std) 985bc3cb74SMauro Carvalho Chehab break; 995bc3cb74SMauro Carvalho Chehab return standards[i].descr; 1005bc3cb74SMauro Carvalho Chehab } 1015bc3cb74SMauro Carvalho Chehab EXPORT_SYMBOL(v4l2_norm_to_name); 1025bc3cb74SMauro Carvalho Chehab 1035bc3cb74SMauro Carvalho Chehab /* Returns frame period for the given standard */ 1045bc3cb74SMauro Carvalho Chehab void v4l2_video_std_frame_period(int id, struct v4l2_fract *frameperiod) 1055bc3cb74SMauro Carvalho Chehab { 1065bc3cb74SMauro Carvalho Chehab if (id & V4L2_STD_525_60) { 1075bc3cb74SMauro Carvalho Chehab frameperiod->numerator = 1001; 1085bc3cb74SMauro Carvalho Chehab frameperiod->denominator = 30000; 1095bc3cb74SMauro Carvalho Chehab } else { 1105bc3cb74SMauro Carvalho Chehab frameperiod->numerator = 1; 1115bc3cb74SMauro Carvalho Chehab frameperiod->denominator = 25; 1125bc3cb74SMauro Carvalho Chehab } 1135bc3cb74SMauro Carvalho Chehab } 1145bc3cb74SMauro Carvalho Chehab EXPORT_SYMBOL(v4l2_video_std_frame_period); 1155bc3cb74SMauro Carvalho Chehab 1165bc3cb74SMauro Carvalho Chehab /* Fill in the fields of a v4l2_standard structure according to the 1175bc3cb74SMauro Carvalho Chehab 'id' and 'transmission' parameters. Returns negative on error. */ 1185bc3cb74SMauro Carvalho Chehab int v4l2_video_std_construct(struct v4l2_standard *vs, 1195bc3cb74SMauro Carvalho Chehab int id, const char *name) 1205bc3cb74SMauro Carvalho Chehab { 1215bc3cb74SMauro Carvalho Chehab vs->id = id; 1225bc3cb74SMauro Carvalho Chehab v4l2_video_std_frame_period(id, &vs->frameperiod); 1235bc3cb74SMauro Carvalho Chehab vs->framelines = (id & V4L2_STD_525_60) ? 525 : 625; 124c0decac1SMauro Carvalho Chehab strscpy(vs->name, name, sizeof(vs->name)); 1255bc3cb74SMauro Carvalho Chehab return 0; 1265bc3cb74SMauro Carvalho Chehab } 1275bc3cb74SMauro Carvalho Chehab EXPORT_SYMBOL(v4l2_video_std_construct); 1285bc3cb74SMauro Carvalho Chehab 129aa2f8871SNiklas Söderlund /* Fill in the fields of a v4l2_standard structure according to the 130aa2f8871SNiklas Söderlund * 'id' and 'vs->index' parameters. Returns negative on error. */ 131aa2f8871SNiklas Söderlund int v4l_video_std_enumstd(struct v4l2_standard *vs, v4l2_std_id id) 132aa2f8871SNiklas Söderlund { 133aa2f8871SNiklas Söderlund v4l2_std_id curr_id = 0; 134aa2f8871SNiklas Söderlund unsigned int index = vs->index, i, j = 0; 135aa2f8871SNiklas Söderlund const char *descr = ""; 136aa2f8871SNiklas Söderlund 137aa2f8871SNiklas Söderlund /* Return -ENODATA if the id for the current input 138aa2f8871SNiklas Söderlund or output is 0, meaning that it doesn't support this API. */ 139aa2f8871SNiklas Söderlund if (id == 0) 140aa2f8871SNiklas Söderlund return -ENODATA; 141aa2f8871SNiklas Söderlund 142aa2f8871SNiklas Söderlund /* Return norm array in a canonical way */ 143aa2f8871SNiklas Söderlund for (i = 0; i <= index && id; i++) { 144aa2f8871SNiklas Söderlund /* last std value in the standards array is 0, so this 145aa2f8871SNiklas Söderlund while always ends there since (id & 0) == 0. */ 146aa2f8871SNiklas Söderlund while ((id & standards[j].std) != standards[j].std) 147aa2f8871SNiklas Söderlund j++; 148aa2f8871SNiklas Söderlund curr_id = standards[j].std; 149aa2f8871SNiklas Söderlund descr = standards[j].descr; 150aa2f8871SNiklas Söderlund j++; 151aa2f8871SNiklas Söderlund if (curr_id == 0) 152aa2f8871SNiklas Söderlund break; 153aa2f8871SNiklas Söderlund if (curr_id != V4L2_STD_PAL && 154aa2f8871SNiklas Söderlund curr_id != V4L2_STD_SECAM && 155aa2f8871SNiklas Söderlund curr_id != V4L2_STD_NTSC) 156aa2f8871SNiklas Söderlund id &= ~curr_id; 157aa2f8871SNiklas Söderlund } 158aa2f8871SNiklas Söderlund if (i <= index) 159aa2f8871SNiklas Söderlund return -EINVAL; 160aa2f8871SNiklas Söderlund 161aa2f8871SNiklas Söderlund v4l2_video_std_construct(vs, curr_id, descr); 162aa2f8871SNiklas Söderlund return 0; 163aa2f8871SNiklas Söderlund } 164aa2f8871SNiklas Söderlund 1655bc3cb74SMauro Carvalho Chehab /* ----------------------------------------------------------------- */ 1665bc3cb74SMauro Carvalho Chehab /* some arrays for pretty-printing debug messages of enum types */ 1675bc3cb74SMauro Carvalho Chehab 1685bc3cb74SMauro Carvalho Chehab const char *v4l2_field_names[] = { 1695bc3cb74SMauro Carvalho Chehab [V4L2_FIELD_ANY] = "any", 1705bc3cb74SMauro Carvalho Chehab [V4L2_FIELD_NONE] = "none", 1715bc3cb74SMauro Carvalho Chehab [V4L2_FIELD_TOP] = "top", 1725bc3cb74SMauro Carvalho Chehab [V4L2_FIELD_BOTTOM] = "bottom", 1735bc3cb74SMauro Carvalho Chehab [V4L2_FIELD_INTERLACED] = "interlaced", 1745bc3cb74SMauro Carvalho Chehab [V4L2_FIELD_SEQ_TB] = "seq-tb", 1755bc3cb74SMauro Carvalho Chehab [V4L2_FIELD_SEQ_BT] = "seq-bt", 1765bc3cb74SMauro Carvalho Chehab [V4L2_FIELD_ALTERNATE] = "alternate", 1775bc3cb74SMauro Carvalho Chehab [V4L2_FIELD_INTERLACED_TB] = "interlaced-tb", 1785bc3cb74SMauro Carvalho Chehab [V4L2_FIELD_INTERLACED_BT] = "interlaced-bt", 1795bc3cb74SMauro Carvalho Chehab }; 1805bc3cb74SMauro Carvalho Chehab EXPORT_SYMBOL(v4l2_field_names); 1815bc3cb74SMauro Carvalho Chehab 1825bc3cb74SMauro Carvalho Chehab const char *v4l2_type_names[] = { 183839aa56dSHans Verkuil [0] = "0", 1845bc3cb74SMauro Carvalho Chehab [V4L2_BUF_TYPE_VIDEO_CAPTURE] = "vid-cap", 1855bc3cb74SMauro Carvalho Chehab [V4L2_BUF_TYPE_VIDEO_OVERLAY] = "vid-overlay", 1865bc3cb74SMauro Carvalho Chehab [V4L2_BUF_TYPE_VIDEO_OUTPUT] = "vid-out", 1875bc3cb74SMauro Carvalho Chehab [V4L2_BUF_TYPE_VBI_CAPTURE] = "vbi-cap", 1885bc3cb74SMauro Carvalho Chehab [V4L2_BUF_TYPE_VBI_OUTPUT] = "vbi-out", 1895bc3cb74SMauro Carvalho Chehab [V4L2_BUF_TYPE_SLICED_VBI_CAPTURE] = "sliced-vbi-cap", 1905bc3cb74SMauro Carvalho Chehab [V4L2_BUF_TYPE_SLICED_VBI_OUTPUT] = "sliced-vbi-out", 1915bc3cb74SMauro Carvalho Chehab [V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY] = "vid-out-overlay", 1925bc3cb74SMauro Carvalho Chehab [V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE] = "vid-cap-mplane", 1935bc3cb74SMauro Carvalho Chehab [V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE] = "vid-out-mplane", 1946f3073b8SAntti Palosaari [V4L2_BUF_TYPE_SDR_CAPTURE] = "sdr-cap", 1959effc72fSAntti Palosaari [V4L2_BUF_TYPE_SDR_OUTPUT] = "sdr-out", 196fb9ffa6aSLaurent Pinchart [V4L2_BUF_TYPE_META_CAPTURE] = "meta-cap", 1975bc3cb74SMauro Carvalho Chehab }; 1985bc3cb74SMauro Carvalho Chehab EXPORT_SYMBOL(v4l2_type_names); 1995bc3cb74SMauro Carvalho Chehab 2005bc3cb74SMauro Carvalho Chehab static const char *v4l2_memory_names[] = { 2015bc3cb74SMauro Carvalho Chehab [V4L2_MEMORY_MMAP] = "mmap", 2025bc3cb74SMauro Carvalho Chehab [V4L2_MEMORY_USERPTR] = "userptr", 2035bc3cb74SMauro Carvalho Chehab [V4L2_MEMORY_OVERLAY] = "overlay", 204051c7788SSumit Semwal [V4L2_MEMORY_DMABUF] = "dmabuf", 2055bc3cb74SMauro Carvalho Chehab }; 2065bc3cb74SMauro Carvalho Chehab 207d9246240SHans Verkuil #define prt_names(a, arr) (((unsigned)(a)) < ARRAY_SIZE(arr) ? arr[a] : "unknown") 2085bc3cb74SMauro Carvalho Chehab 2095bc3cb74SMauro Carvalho Chehab /* ------------------------------------------------------------------ */ 2105bc3cb74SMauro Carvalho Chehab /* debug help functions */ 2115bc3cb74SMauro Carvalho Chehab 2125bc3cb74SMauro Carvalho Chehab static void v4l_print_querycap(const void *arg, bool write_only) 2135bc3cb74SMauro Carvalho Chehab { 2145bc3cb74SMauro Carvalho Chehab const struct v4l2_capability *p = arg; 2155bc3cb74SMauro Carvalho Chehab 2168720427cSMauro Carvalho Chehab pr_cont("driver=%.*s, card=%.*s, bus=%.*s, version=0x%08x, capabilities=0x%08x, device_caps=0x%08x\n", 21727d5a87cSHans Verkuil (int)sizeof(p->driver), p->driver, 21827d5a87cSHans Verkuil (int)sizeof(p->card), p->card, 21927d5a87cSHans Verkuil (int)sizeof(p->bus_info), p->bus_info, 2205bc3cb74SMauro Carvalho Chehab p->version, p->capabilities, p->device_caps); 2215bc3cb74SMauro Carvalho Chehab } 2225bc3cb74SMauro Carvalho Chehab 2235bc3cb74SMauro Carvalho Chehab static void v4l_print_enuminput(const void *arg, bool write_only) 2245bc3cb74SMauro Carvalho Chehab { 2255bc3cb74SMauro Carvalho Chehab const struct v4l2_input *p = arg; 2265bc3cb74SMauro Carvalho Chehab 2278720427cSMauro Carvalho Chehab pr_cont("index=%u, name=%.*s, type=%u, audioset=0x%x, tuner=%u, std=0x%08Lx, status=0x%x, capabilities=0x%x\n", 22827d5a87cSHans Verkuil p->index, (int)sizeof(p->name), p->name, p->type, p->audioset, 22927d5a87cSHans Verkuil p->tuner, (unsigned long long)p->std, p->status, 23027d5a87cSHans Verkuil p->capabilities); 2315bc3cb74SMauro Carvalho Chehab } 2325bc3cb74SMauro Carvalho Chehab 2335bc3cb74SMauro Carvalho Chehab static void v4l_print_enumoutput(const void *arg, bool write_only) 2345bc3cb74SMauro Carvalho Chehab { 2355bc3cb74SMauro Carvalho Chehab const struct v4l2_output *p = arg; 2365bc3cb74SMauro Carvalho Chehab 2378720427cSMauro Carvalho Chehab pr_cont("index=%u, name=%.*s, type=%u, audioset=0x%x, modulator=%u, std=0x%08Lx, capabilities=0x%x\n", 23827d5a87cSHans Verkuil p->index, (int)sizeof(p->name), p->name, p->type, p->audioset, 23927d5a87cSHans Verkuil p->modulator, (unsigned long long)p->std, p->capabilities); 2405bc3cb74SMauro Carvalho Chehab } 2415bc3cb74SMauro Carvalho Chehab 2425bc3cb74SMauro Carvalho Chehab static void v4l_print_audio(const void *arg, bool write_only) 2435bc3cb74SMauro Carvalho Chehab { 2445bc3cb74SMauro Carvalho Chehab const struct v4l2_audio *p = arg; 2455bc3cb74SMauro Carvalho Chehab 2465bc3cb74SMauro Carvalho Chehab if (write_only) 2475bc3cb74SMauro Carvalho Chehab pr_cont("index=%u, mode=0x%x\n", p->index, p->mode); 2485bc3cb74SMauro Carvalho Chehab else 24927d5a87cSHans Verkuil pr_cont("index=%u, name=%.*s, capability=0x%x, mode=0x%x\n", 25027d5a87cSHans Verkuil p->index, (int)sizeof(p->name), p->name, 25127d5a87cSHans Verkuil p->capability, p->mode); 2525bc3cb74SMauro Carvalho Chehab } 2535bc3cb74SMauro Carvalho Chehab 2545bc3cb74SMauro Carvalho Chehab static void v4l_print_audioout(const void *arg, bool write_only) 2555bc3cb74SMauro Carvalho Chehab { 2565bc3cb74SMauro Carvalho Chehab const struct v4l2_audioout *p = arg; 2575bc3cb74SMauro Carvalho Chehab 2585bc3cb74SMauro Carvalho Chehab if (write_only) 2595bc3cb74SMauro Carvalho Chehab pr_cont("index=%u\n", p->index); 2605bc3cb74SMauro Carvalho Chehab else 26127d5a87cSHans Verkuil pr_cont("index=%u, name=%.*s, capability=0x%x, mode=0x%x\n", 26227d5a87cSHans Verkuil p->index, (int)sizeof(p->name), p->name, 26327d5a87cSHans Verkuil p->capability, p->mode); 2645bc3cb74SMauro Carvalho Chehab } 2655bc3cb74SMauro Carvalho Chehab 2665bc3cb74SMauro Carvalho Chehab static void v4l_print_fmtdesc(const void *arg, bool write_only) 2675bc3cb74SMauro Carvalho Chehab { 2685bc3cb74SMauro Carvalho Chehab const struct v4l2_fmtdesc *p = arg; 2695bc3cb74SMauro Carvalho Chehab 27027d5a87cSHans Verkuil pr_cont("index=%u, type=%s, flags=0x%x, pixelformat=%c%c%c%c, description='%.*s'\n", 2715bc3cb74SMauro Carvalho Chehab p->index, prt_names(p->type, v4l2_type_names), 2725bc3cb74SMauro Carvalho Chehab p->flags, (p->pixelformat & 0xff), 2735bc3cb74SMauro Carvalho Chehab (p->pixelformat >> 8) & 0xff, 2745bc3cb74SMauro Carvalho Chehab (p->pixelformat >> 16) & 0xff, 2755bc3cb74SMauro Carvalho Chehab (p->pixelformat >> 24) & 0xff, 27627d5a87cSHans Verkuil (int)sizeof(p->description), p->description); 2775bc3cb74SMauro Carvalho Chehab } 2785bc3cb74SMauro Carvalho Chehab 2795bc3cb74SMauro Carvalho Chehab static void v4l_print_format(const void *arg, bool write_only) 2805bc3cb74SMauro Carvalho Chehab { 2815bc3cb74SMauro Carvalho Chehab const struct v4l2_format *p = arg; 2825bc3cb74SMauro Carvalho Chehab const struct v4l2_pix_format *pix; 2835bc3cb74SMauro Carvalho Chehab const struct v4l2_pix_format_mplane *mp; 2845bc3cb74SMauro Carvalho Chehab const struct v4l2_vbi_format *vbi; 2855bc3cb74SMauro Carvalho Chehab const struct v4l2_sliced_vbi_format *sliced; 2865bc3cb74SMauro Carvalho Chehab const struct v4l2_window *win; 28787185c95SAntti Palosaari const struct v4l2_sdr_format *sdr; 288fb9ffa6aSLaurent Pinchart const struct v4l2_meta_format *meta; 2895bc3cb74SMauro Carvalho Chehab unsigned i; 2905bc3cb74SMauro Carvalho Chehab 2915bc3cb74SMauro Carvalho Chehab pr_cont("type=%s", prt_names(p->type, v4l2_type_names)); 2925bc3cb74SMauro Carvalho Chehab switch (p->type) { 2935bc3cb74SMauro Carvalho Chehab case V4L2_BUF_TYPE_VIDEO_CAPTURE: 2945bc3cb74SMauro Carvalho Chehab case V4L2_BUF_TYPE_VIDEO_OUTPUT: 2955bc3cb74SMauro Carvalho Chehab pix = &p->fmt.pix; 2968720427cSMauro Carvalho Chehab pr_cont(", width=%u, height=%u, pixelformat=%c%c%c%c, field=%s, bytesperline=%u, sizeimage=%u, colorspace=%d, flags=0x%x, ycbcr_enc=%u, quantization=%u, xfer_func=%u\n", 2975bc3cb74SMauro Carvalho Chehab pix->width, pix->height, 2985bc3cb74SMauro Carvalho Chehab (pix->pixelformat & 0xff), 2995bc3cb74SMauro Carvalho Chehab (pix->pixelformat >> 8) & 0xff, 3005bc3cb74SMauro Carvalho Chehab (pix->pixelformat >> 16) & 0xff, 3015bc3cb74SMauro Carvalho Chehab (pix->pixelformat >> 24) & 0xff, 3025bc3cb74SMauro Carvalho Chehab prt_names(pix->field, v4l2_field_names), 3035bc3cb74SMauro Carvalho Chehab pix->bytesperline, pix->sizeimage, 304736d96b5SHans Verkuil pix->colorspace, pix->flags, pix->ycbcr_enc, 30574fdcb2eSHans Verkuil pix->quantization, pix->xfer_func); 3065bc3cb74SMauro Carvalho Chehab break; 3075bc3cb74SMauro Carvalho Chehab case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE: 3085bc3cb74SMauro Carvalho Chehab case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE: 3095bc3cb74SMauro Carvalho Chehab mp = &p->fmt.pix_mp; 3108720427cSMauro Carvalho Chehab pr_cont(", width=%u, height=%u, format=%c%c%c%c, field=%s, colorspace=%d, num_planes=%u, flags=0x%x, ycbcr_enc=%u, quantization=%u, xfer_func=%u\n", 3115bc3cb74SMauro Carvalho Chehab mp->width, mp->height, 3125bc3cb74SMauro Carvalho Chehab (mp->pixelformat & 0xff), 3135bc3cb74SMauro Carvalho Chehab (mp->pixelformat >> 8) & 0xff, 3145bc3cb74SMauro Carvalho Chehab (mp->pixelformat >> 16) & 0xff, 3155bc3cb74SMauro Carvalho Chehab (mp->pixelformat >> 24) & 0xff, 3165bc3cb74SMauro Carvalho Chehab prt_names(mp->field, v4l2_field_names), 317736d96b5SHans Verkuil mp->colorspace, mp->num_planes, mp->flags, 31874fdcb2eSHans Verkuil mp->ycbcr_enc, mp->quantization, mp->xfer_func); 3195bc3cb74SMauro Carvalho Chehab for (i = 0; i < mp->num_planes; i++) 3205bc3cb74SMauro Carvalho Chehab printk(KERN_DEBUG "plane %u: bytesperline=%u sizeimage=%u\n", i, 3215bc3cb74SMauro Carvalho Chehab mp->plane_fmt[i].bytesperline, 3225bc3cb74SMauro Carvalho Chehab mp->plane_fmt[i].sizeimage); 3235bc3cb74SMauro Carvalho Chehab break; 3245bc3cb74SMauro Carvalho Chehab case V4L2_BUF_TYPE_VIDEO_OVERLAY: 3255bc3cb74SMauro Carvalho Chehab case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY: 3265bc3cb74SMauro Carvalho Chehab win = &p->fmt.win; 327560dde24SHans Verkuil /* Note: we can't print the clip list here since the clips 328560dde24SHans Verkuil * pointer is a userspace pointer, not a kernelspace 329560dde24SHans Verkuil * pointer. */ 330560dde24SHans Verkuil pr_cont(", wxh=%dx%d, x,y=%d,%d, field=%s, chromakey=0x%08x, clipcount=%u, clips=%p, bitmap=%p, global_alpha=0x%02x\n", 331560dde24SHans Verkuil win->w.width, win->w.height, win->w.left, win->w.top, 3325bc3cb74SMauro Carvalho Chehab prt_names(win->field, v4l2_field_names), 333560dde24SHans Verkuil win->chromakey, win->clipcount, win->clips, 334560dde24SHans Verkuil win->bitmap, win->global_alpha); 3355bc3cb74SMauro Carvalho Chehab break; 3365bc3cb74SMauro Carvalho Chehab case V4L2_BUF_TYPE_VBI_CAPTURE: 3375bc3cb74SMauro Carvalho Chehab case V4L2_BUF_TYPE_VBI_OUTPUT: 3385bc3cb74SMauro Carvalho Chehab vbi = &p->fmt.vbi; 3398720427cSMauro Carvalho Chehab pr_cont(", sampling_rate=%u, offset=%u, samples_per_line=%u, sample_format=%c%c%c%c, start=%u,%u, count=%u,%u\n", 3405bc3cb74SMauro Carvalho Chehab vbi->sampling_rate, vbi->offset, 3415bc3cb74SMauro Carvalho Chehab vbi->samples_per_line, 3425bc3cb74SMauro Carvalho Chehab (vbi->sample_format & 0xff), 3435bc3cb74SMauro Carvalho Chehab (vbi->sample_format >> 8) & 0xff, 3445bc3cb74SMauro Carvalho Chehab (vbi->sample_format >> 16) & 0xff, 3455bc3cb74SMauro Carvalho Chehab (vbi->sample_format >> 24) & 0xff, 3465bc3cb74SMauro Carvalho Chehab vbi->start[0], vbi->start[1], 3475bc3cb74SMauro Carvalho Chehab vbi->count[0], vbi->count[1]); 3485bc3cb74SMauro Carvalho Chehab break; 3495bc3cb74SMauro Carvalho Chehab case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE: 3505bc3cb74SMauro Carvalho Chehab case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT: 3515bc3cb74SMauro Carvalho Chehab sliced = &p->fmt.sliced; 3525bc3cb74SMauro Carvalho Chehab pr_cont(", service_set=0x%08x, io_size=%d\n", 3535bc3cb74SMauro Carvalho Chehab sliced->service_set, sliced->io_size); 3545bc3cb74SMauro Carvalho Chehab for (i = 0; i < 24; i++) 3555bc3cb74SMauro Carvalho Chehab printk(KERN_DEBUG "line[%02u]=0x%04x, 0x%04x\n", i, 3565bc3cb74SMauro Carvalho Chehab sliced->service_lines[0][i], 3575bc3cb74SMauro Carvalho Chehab sliced->service_lines[1][i]); 3585bc3cb74SMauro Carvalho Chehab break; 359582c52cbSAntti Palosaari case V4L2_BUF_TYPE_SDR_CAPTURE: 3609effc72fSAntti Palosaari case V4L2_BUF_TYPE_SDR_OUTPUT: 361582c52cbSAntti Palosaari sdr = &p->fmt.sdr; 362582c52cbSAntti Palosaari pr_cont(", pixelformat=%c%c%c%c\n", 363582c52cbSAntti Palosaari (sdr->pixelformat >> 0) & 0xff, 364582c52cbSAntti Palosaari (sdr->pixelformat >> 8) & 0xff, 365582c52cbSAntti Palosaari (sdr->pixelformat >> 16) & 0xff, 366582c52cbSAntti Palosaari (sdr->pixelformat >> 24) & 0xff); 367582c52cbSAntti Palosaari break; 368fb9ffa6aSLaurent Pinchart case V4L2_BUF_TYPE_META_CAPTURE: 369fb9ffa6aSLaurent Pinchart meta = &p->fmt.meta; 370fb9ffa6aSLaurent Pinchart pr_cont(", dataformat=%c%c%c%c, buffersize=%u\n", 371fb9ffa6aSLaurent Pinchart (meta->dataformat >> 0) & 0xff, 372fb9ffa6aSLaurent Pinchart (meta->dataformat >> 8) & 0xff, 373fb9ffa6aSLaurent Pinchart (meta->dataformat >> 16) & 0xff, 374fb9ffa6aSLaurent Pinchart (meta->dataformat >> 24) & 0xff, 375fb9ffa6aSLaurent Pinchart meta->buffersize); 376fb9ffa6aSLaurent Pinchart break; 3775bc3cb74SMauro Carvalho Chehab } 3785bc3cb74SMauro Carvalho Chehab } 3795bc3cb74SMauro Carvalho Chehab 3805bc3cb74SMauro Carvalho Chehab static void v4l_print_framebuffer(const void *arg, bool write_only) 3815bc3cb74SMauro Carvalho Chehab { 3825bc3cb74SMauro Carvalho Chehab const struct v4l2_framebuffer *p = arg; 3835bc3cb74SMauro Carvalho Chehab 3848720427cSMauro Carvalho Chehab pr_cont("capability=0x%x, flags=0x%x, base=0x%p, width=%u, height=%u, pixelformat=%c%c%c%c, bytesperline=%u, sizeimage=%u, colorspace=%d\n", 3855bc3cb74SMauro Carvalho Chehab p->capability, p->flags, p->base, 3865bc3cb74SMauro Carvalho Chehab p->fmt.width, p->fmt.height, 3875bc3cb74SMauro Carvalho Chehab (p->fmt.pixelformat & 0xff), 3885bc3cb74SMauro Carvalho Chehab (p->fmt.pixelformat >> 8) & 0xff, 3895bc3cb74SMauro Carvalho Chehab (p->fmt.pixelformat >> 16) & 0xff, 3905bc3cb74SMauro Carvalho Chehab (p->fmt.pixelformat >> 24) & 0xff, 3915bc3cb74SMauro Carvalho Chehab p->fmt.bytesperline, p->fmt.sizeimage, 3925bc3cb74SMauro Carvalho Chehab p->fmt.colorspace); 3935bc3cb74SMauro Carvalho Chehab } 3945bc3cb74SMauro Carvalho Chehab 3955bc3cb74SMauro Carvalho Chehab static void v4l_print_buftype(const void *arg, bool write_only) 3965bc3cb74SMauro Carvalho Chehab { 3975bc3cb74SMauro Carvalho Chehab pr_cont("type=%s\n", prt_names(*(u32 *)arg, v4l2_type_names)); 3985bc3cb74SMauro Carvalho Chehab } 3995bc3cb74SMauro Carvalho Chehab 4005bc3cb74SMauro Carvalho Chehab static void v4l_print_modulator(const void *arg, bool write_only) 4015bc3cb74SMauro Carvalho Chehab { 4025bc3cb74SMauro Carvalho Chehab const struct v4l2_modulator *p = arg; 4035bc3cb74SMauro Carvalho Chehab 4045bc3cb74SMauro Carvalho Chehab if (write_only) 405560dde24SHans Verkuil pr_cont("index=%u, txsubchans=0x%x\n", p->index, p->txsubchans); 4065bc3cb74SMauro Carvalho Chehab else 4078720427cSMauro Carvalho Chehab pr_cont("index=%u, name=%.*s, capability=0x%x, rangelow=%u, rangehigh=%u, txsubchans=0x%x\n", 40827d5a87cSHans Verkuil p->index, (int)sizeof(p->name), p->name, p->capability, 4095bc3cb74SMauro Carvalho Chehab p->rangelow, p->rangehigh, p->txsubchans); 4105bc3cb74SMauro Carvalho Chehab } 4115bc3cb74SMauro Carvalho Chehab 4125bc3cb74SMauro Carvalho Chehab static void v4l_print_tuner(const void *arg, bool write_only) 4135bc3cb74SMauro Carvalho Chehab { 4145bc3cb74SMauro Carvalho Chehab const struct v4l2_tuner *p = arg; 4155bc3cb74SMauro Carvalho Chehab 4165bc3cb74SMauro Carvalho Chehab if (write_only) 4175bc3cb74SMauro Carvalho Chehab pr_cont("index=%u, audmode=%u\n", p->index, p->audmode); 4185bc3cb74SMauro Carvalho Chehab else 4198720427cSMauro Carvalho Chehab pr_cont("index=%u, name=%.*s, type=%u, capability=0x%x, rangelow=%u, rangehigh=%u, signal=%u, afc=%d, rxsubchans=0x%x, audmode=%u\n", 42027d5a87cSHans Verkuil p->index, (int)sizeof(p->name), p->name, p->type, 4215bc3cb74SMauro Carvalho Chehab p->capability, p->rangelow, 4225bc3cb74SMauro Carvalho Chehab p->rangehigh, p->signal, p->afc, 4235bc3cb74SMauro Carvalho Chehab p->rxsubchans, p->audmode); 4245bc3cb74SMauro Carvalho Chehab } 4255bc3cb74SMauro Carvalho Chehab 4265bc3cb74SMauro Carvalho Chehab static void v4l_print_frequency(const void *arg, bool write_only) 4275bc3cb74SMauro Carvalho Chehab { 4285bc3cb74SMauro Carvalho Chehab const struct v4l2_frequency *p = arg; 4295bc3cb74SMauro Carvalho Chehab 4305bc3cb74SMauro Carvalho Chehab pr_cont("tuner=%u, type=%u, frequency=%u\n", 4315bc3cb74SMauro Carvalho Chehab p->tuner, p->type, p->frequency); 4325bc3cb74SMauro Carvalho Chehab } 4335bc3cb74SMauro Carvalho Chehab 4345bc3cb74SMauro Carvalho Chehab static void v4l_print_standard(const void *arg, bool write_only) 4355bc3cb74SMauro Carvalho Chehab { 4365bc3cb74SMauro Carvalho Chehab const struct v4l2_standard *p = arg; 4375bc3cb74SMauro Carvalho Chehab 4388720427cSMauro Carvalho Chehab pr_cont("index=%u, id=0x%Lx, name=%.*s, fps=%u/%u, framelines=%u\n", 4398720427cSMauro Carvalho Chehab p->index, 44027d5a87cSHans Verkuil (unsigned long long)p->id, (int)sizeof(p->name), p->name, 4415bc3cb74SMauro Carvalho Chehab p->frameperiod.numerator, 4425bc3cb74SMauro Carvalho Chehab p->frameperiod.denominator, 4435bc3cb74SMauro Carvalho Chehab p->framelines); 4445bc3cb74SMauro Carvalho Chehab } 4455bc3cb74SMauro Carvalho Chehab 4465bc3cb74SMauro Carvalho Chehab static void v4l_print_std(const void *arg, bool write_only) 4475bc3cb74SMauro Carvalho Chehab { 4485bc3cb74SMauro Carvalho Chehab pr_cont("std=0x%08Lx\n", *(const long long unsigned *)arg); 4495bc3cb74SMauro Carvalho Chehab } 4505bc3cb74SMauro Carvalho Chehab 4515bc3cb74SMauro Carvalho Chehab static void v4l_print_hw_freq_seek(const void *arg, bool write_only) 4525bc3cb74SMauro Carvalho Chehab { 4535bc3cb74SMauro Carvalho Chehab const struct v4l2_hw_freq_seek *p = arg; 4545bc3cb74SMauro Carvalho Chehab 4558720427cSMauro Carvalho Chehab pr_cont("tuner=%u, type=%u, seek_upward=%u, wrap_around=%u, spacing=%u, rangelow=%u, rangehigh=%u\n", 45679e8c7beSMauro Carvalho Chehab p->tuner, p->type, p->seek_upward, p->wrap_around, p->spacing, 45779e8c7beSMauro Carvalho Chehab p->rangelow, p->rangehigh); 4585bc3cb74SMauro Carvalho Chehab } 4595bc3cb74SMauro Carvalho Chehab 4605bc3cb74SMauro Carvalho Chehab static void v4l_print_requestbuffers(const void *arg, bool write_only) 4615bc3cb74SMauro Carvalho Chehab { 4625bc3cb74SMauro Carvalho Chehab const struct v4l2_requestbuffers *p = arg; 4635bc3cb74SMauro Carvalho Chehab 4645bc3cb74SMauro Carvalho Chehab pr_cont("count=%d, type=%s, memory=%s\n", 4655bc3cb74SMauro Carvalho Chehab p->count, 4665bc3cb74SMauro Carvalho Chehab prt_names(p->type, v4l2_type_names), 4675bc3cb74SMauro Carvalho Chehab prt_names(p->memory, v4l2_memory_names)); 4685bc3cb74SMauro Carvalho Chehab } 4695bc3cb74SMauro Carvalho Chehab 4705bc3cb74SMauro Carvalho Chehab static void v4l_print_buffer(const void *arg, bool write_only) 4715bc3cb74SMauro Carvalho Chehab { 4725bc3cb74SMauro Carvalho Chehab const struct v4l2_buffer *p = arg; 4735bc3cb74SMauro Carvalho Chehab const struct v4l2_timecode *tc = &p->timecode; 4745bc3cb74SMauro Carvalho Chehab const struct v4l2_plane *plane; 4755bc3cb74SMauro Carvalho Chehab int i; 4765bc3cb74SMauro Carvalho Chehab 47762fed26fSHans Verkuil pr_cont("%02ld:%02d:%02d.%08ld index=%d, type=%s, request_fd=%d, flags=0x%08x, field=%s, sequence=%d, memory=%s", 4785bc3cb74SMauro Carvalho Chehab p->timestamp.tv_sec / 3600, 4795bc3cb74SMauro Carvalho Chehab (int)(p->timestamp.tv_sec / 60) % 60, 4805bc3cb74SMauro Carvalho Chehab (int)(p->timestamp.tv_sec % 60), 4815bc3cb74SMauro Carvalho Chehab (long)p->timestamp.tv_usec, 4825bc3cb74SMauro Carvalho Chehab p->index, 48362fed26fSHans Verkuil prt_names(p->type, v4l2_type_names), p->request_fd, 4845bc3cb74SMauro Carvalho Chehab p->flags, prt_names(p->field, v4l2_field_names), 4855bc3cb74SMauro Carvalho Chehab p->sequence, prt_names(p->memory, v4l2_memory_names)); 4865bc3cb74SMauro Carvalho Chehab 4875bc3cb74SMauro Carvalho Chehab if (V4L2_TYPE_IS_MULTIPLANAR(p->type) && p->m.planes) { 4885bc3cb74SMauro Carvalho Chehab pr_cont("\n"); 4895bc3cb74SMauro Carvalho Chehab for (i = 0; i < p->length; ++i) { 4905bc3cb74SMauro Carvalho Chehab plane = &p->m.planes[i]; 4915bc3cb74SMauro Carvalho Chehab printk(KERN_DEBUG 4928720427cSMauro Carvalho Chehab "plane %d: bytesused=%d, data_offset=0x%08x, offset/userptr=0x%lx, length=%d\n", 4935bc3cb74SMauro Carvalho Chehab i, plane->bytesused, plane->data_offset, 4945bc3cb74SMauro Carvalho Chehab plane->m.userptr, plane->length); 4955bc3cb74SMauro Carvalho Chehab } 4965bc3cb74SMauro Carvalho Chehab } else { 497560dde24SHans Verkuil pr_cont(", bytesused=%d, offset/userptr=0x%lx, length=%d\n", 4985bc3cb74SMauro Carvalho Chehab p->bytesused, p->m.userptr, p->length); 4995bc3cb74SMauro Carvalho Chehab } 5005bc3cb74SMauro Carvalho Chehab 5018720427cSMauro Carvalho Chehab printk(KERN_DEBUG "timecode=%02d:%02d:%02d type=%d, flags=0x%08x, frames=%d, userbits=0x%08x\n", 5025bc3cb74SMauro Carvalho Chehab tc->hours, tc->minutes, tc->seconds, 5035bc3cb74SMauro Carvalho Chehab tc->type, tc->flags, tc->frames, *(__u32 *)tc->userbits); 5045bc3cb74SMauro Carvalho Chehab } 5055bc3cb74SMauro Carvalho Chehab 506b799d09aSTomasz Stanislawski static void v4l_print_exportbuffer(const void *arg, bool write_only) 507b799d09aSTomasz Stanislawski { 508b799d09aSTomasz Stanislawski const struct v4l2_exportbuffer *p = arg; 509b799d09aSTomasz Stanislawski 510b799d09aSTomasz Stanislawski pr_cont("fd=%d, type=%s, index=%u, plane=%u, flags=0x%08x\n", 511b799d09aSTomasz Stanislawski p->fd, prt_names(p->type, v4l2_type_names), 512b799d09aSTomasz Stanislawski p->index, p->plane, p->flags); 513b799d09aSTomasz Stanislawski } 514b799d09aSTomasz Stanislawski 5155bc3cb74SMauro Carvalho Chehab static void v4l_print_create_buffers(const void *arg, bool write_only) 5165bc3cb74SMauro Carvalho Chehab { 5175bc3cb74SMauro Carvalho Chehab const struct v4l2_create_buffers *p = arg; 5185bc3cb74SMauro Carvalho Chehab 5195bc3cb74SMauro Carvalho Chehab pr_cont("index=%d, count=%d, memory=%s, ", 5205bc3cb74SMauro Carvalho Chehab p->index, p->count, 5215bc3cb74SMauro Carvalho Chehab prt_names(p->memory, v4l2_memory_names)); 5225bc3cb74SMauro Carvalho Chehab v4l_print_format(&p->format, write_only); 5235bc3cb74SMauro Carvalho Chehab } 5245bc3cb74SMauro Carvalho Chehab 5255bc3cb74SMauro Carvalho Chehab static void v4l_print_streamparm(const void *arg, bool write_only) 5265bc3cb74SMauro Carvalho Chehab { 5275bc3cb74SMauro Carvalho Chehab const struct v4l2_streamparm *p = arg; 5285bc3cb74SMauro Carvalho Chehab 5295bc3cb74SMauro Carvalho Chehab pr_cont("type=%s", prt_names(p->type, v4l2_type_names)); 5305bc3cb74SMauro Carvalho Chehab 5315bc3cb74SMauro Carvalho Chehab if (p->type == V4L2_BUF_TYPE_VIDEO_CAPTURE || 5325bc3cb74SMauro Carvalho Chehab p->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) { 5335bc3cb74SMauro Carvalho Chehab const struct v4l2_captureparm *c = &p->parm.capture; 5345bc3cb74SMauro Carvalho Chehab 5358720427cSMauro Carvalho Chehab pr_cont(", capability=0x%x, capturemode=0x%x, timeperframe=%d/%d, extendedmode=%d, readbuffers=%d\n", 5365bc3cb74SMauro Carvalho Chehab c->capability, c->capturemode, 5375bc3cb74SMauro Carvalho Chehab c->timeperframe.numerator, c->timeperframe.denominator, 5385bc3cb74SMauro Carvalho Chehab c->extendedmode, c->readbuffers); 5395bc3cb74SMauro Carvalho Chehab } else if (p->type == V4L2_BUF_TYPE_VIDEO_OUTPUT || 5405bc3cb74SMauro Carvalho Chehab p->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) { 5415bc3cb74SMauro Carvalho Chehab const struct v4l2_outputparm *c = &p->parm.output; 5425bc3cb74SMauro Carvalho Chehab 5438720427cSMauro Carvalho Chehab pr_cont(", capability=0x%x, outputmode=0x%x, timeperframe=%d/%d, extendedmode=%d, writebuffers=%d\n", 5445bc3cb74SMauro Carvalho Chehab c->capability, c->outputmode, 5455bc3cb74SMauro Carvalho Chehab c->timeperframe.numerator, c->timeperframe.denominator, 5465bc3cb74SMauro Carvalho Chehab c->extendedmode, c->writebuffers); 547560dde24SHans Verkuil } else { 548560dde24SHans Verkuil pr_cont("\n"); 5495bc3cb74SMauro Carvalho Chehab } 5505bc3cb74SMauro Carvalho Chehab } 5515bc3cb74SMauro Carvalho Chehab 5525bc3cb74SMauro Carvalho Chehab static void v4l_print_queryctrl(const void *arg, bool write_only) 5535bc3cb74SMauro Carvalho Chehab { 5545bc3cb74SMauro Carvalho Chehab const struct v4l2_queryctrl *p = arg; 5555bc3cb74SMauro Carvalho Chehab 5568720427cSMauro Carvalho Chehab pr_cont("id=0x%x, type=%d, name=%.*s, min/max=%d/%d, step=%d, default=%d, flags=0x%08x\n", 55727d5a87cSHans Verkuil p->id, p->type, (int)sizeof(p->name), p->name, 5585bc3cb74SMauro Carvalho Chehab p->minimum, p->maximum, 5595bc3cb74SMauro Carvalho Chehab p->step, p->default_value, p->flags); 5605bc3cb74SMauro Carvalho Chehab } 5615bc3cb74SMauro Carvalho Chehab 562e6bee368SHans Verkuil static void v4l_print_query_ext_ctrl(const void *arg, bool write_only) 563e6bee368SHans Verkuil { 564e6bee368SHans Verkuil const struct v4l2_query_ext_ctrl *p = arg; 565e6bee368SHans Verkuil 5668720427cSMauro Carvalho Chehab pr_cont("id=0x%x, type=%d, name=%.*s, min/max=%lld/%lld, step=%lld, default=%lld, flags=0x%08x, elem_size=%u, elems=%u, nr_of_dims=%u, dims=%u,%u,%u,%u\n", 567e6bee368SHans Verkuil p->id, p->type, (int)sizeof(p->name), p->name, 568e6bee368SHans Verkuil p->minimum, p->maximum, 569e6bee368SHans Verkuil p->step, p->default_value, p->flags, 570e6bee368SHans Verkuil p->elem_size, p->elems, p->nr_of_dims, 5710176077aSHans Verkuil p->dims[0], p->dims[1], p->dims[2], p->dims[3]); 572e6bee368SHans Verkuil } 573e6bee368SHans Verkuil 5745bc3cb74SMauro Carvalho Chehab static void v4l_print_querymenu(const void *arg, bool write_only) 5755bc3cb74SMauro Carvalho Chehab { 5765bc3cb74SMauro Carvalho Chehab const struct v4l2_querymenu *p = arg; 5775bc3cb74SMauro Carvalho Chehab 5785bc3cb74SMauro Carvalho Chehab pr_cont("id=0x%x, index=%d\n", p->id, p->index); 5795bc3cb74SMauro Carvalho Chehab } 5805bc3cb74SMauro Carvalho Chehab 5815bc3cb74SMauro Carvalho Chehab static void v4l_print_control(const void *arg, bool write_only) 5825bc3cb74SMauro Carvalho Chehab { 5835bc3cb74SMauro Carvalho Chehab const struct v4l2_control *p = arg; 5845bc3cb74SMauro Carvalho Chehab 5855bc3cb74SMauro Carvalho Chehab pr_cont("id=0x%x, value=%d\n", p->id, p->value); 5865bc3cb74SMauro Carvalho Chehab } 5875bc3cb74SMauro Carvalho Chehab 5885bc3cb74SMauro Carvalho Chehab static void v4l_print_ext_controls(const void *arg, bool write_only) 5895bc3cb74SMauro Carvalho Chehab { 5905bc3cb74SMauro Carvalho Chehab const struct v4l2_ext_controls *p = arg; 5915bc3cb74SMauro Carvalho Chehab int i; 5925bc3cb74SMauro Carvalho Chehab 593f23317adSAlexandre Courbot pr_cont("which=0x%x, count=%d, error_idx=%d, request_fd=%d", 594f23317adSAlexandre Courbot p->which, p->count, p->error_idx, p->request_fd); 5955bc3cb74SMauro Carvalho Chehab for (i = 0; i < p->count; i++) { 596017ab36aSHans Verkuil if (!p->controls[i].size) 5975bc3cb74SMauro Carvalho Chehab pr_cont(", id/val=0x%x/0x%x", 5985bc3cb74SMauro Carvalho Chehab p->controls[i].id, p->controls[i].value); 5995bc3cb74SMauro Carvalho Chehab else 6005bc3cb74SMauro Carvalho Chehab pr_cont(", id/size=0x%x/%u", 6015bc3cb74SMauro Carvalho Chehab p->controls[i].id, p->controls[i].size); 6025bc3cb74SMauro Carvalho Chehab } 6035bc3cb74SMauro Carvalho Chehab pr_cont("\n"); 6045bc3cb74SMauro Carvalho Chehab } 6055bc3cb74SMauro Carvalho Chehab 6065bc3cb74SMauro Carvalho Chehab static void v4l_print_cropcap(const void *arg, bool write_only) 6075bc3cb74SMauro Carvalho Chehab { 6085bc3cb74SMauro Carvalho Chehab const struct v4l2_cropcap *p = arg; 6095bc3cb74SMauro Carvalho Chehab 6108720427cSMauro Carvalho Chehab pr_cont("type=%s, bounds wxh=%dx%d, x,y=%d,%d, defrect wxh=%dx%d, x,y=%d,%d, pixelaspect %d/%d\n", 6115bc3cb74SMauro Carvalho Chehab prt_names(p->type, v4l2_type_names), 6125bc3cb74SMauro Carvalho Chehab p->bounds.width, p->bounds.height, 6135bc3cb74SMauro Carvalho Chehab p->bounds.left, p->bounds.top, 6145bc3cb74SMauro Carvalho Chehab p->defrect.width, p->defrect.height, 6155bc3cb74SMauro Carvalho Chehab p->defrect.left, p->defrect.top, 6165bc3cb74SMauro Carvalho Chehab p->pixelaspect.numerator, p->pixelaspect.denominator); 6175bc3cb74SMauro Carvalho Chehab } 6185bc3cb74SMauro Carvalho Chehab 6195bc3cb74SMauro Carvalho Chehab static void v4l_print_crop(const void *arg, bool write_only) 6205bc3cb74SMauro Carvalho Chehab { 6215bc3cb74SMauro Carvalho Chehab const struct v4l2_crop *p = arg; 6225bc3cb74SMauro Carvalho Chehab 6235bc3cb74SMauro Carvalho Chehab pr_cont("type=%s, wxh=%dx%d, x,y=%d,%d\n", 6245bc3cb74SMauro Carvalho Chehab prt_names(p->type, v4l2_type_names), 6255bc3cb74SMauro Carvalho Chehab p->c.width, p->c.height, 6265bc3cb74SMauro Carvalho Chehab p->c.left, p->c.top); 6275bc3cb74SMauro Carvalho Chehab } 6285bc3cb74SMauro Carvalho Chehab 6295bc3cb74SMauro Carvalho Chehab static void v4l_print_selection(const void *arg, bool write_only) 6305bc3cb74SMauro Carvalho Chehab { 6315bc3cb74SMauro Carvalho Chehab const struct v4l2_selection *p = arg; 6325bc3cb74SMauro Carvalho Chehab 6335bc3cb74SMauro Carvalho Chehab pr_cont("type=%s, target=%d, flags=0x%x, wxh=%dx%d, x,y=%d,%d\n", 6345bc3cb74SMauro Carvalho Chehab prt_names(p->type, v4l2_type_names), 6355bc3cb74SMauro Carvalho Chehab p->target, p->flags, 6365bc3cb74SMauro Carvalho Chehab p->r.width, p->r.height, p->r.left, p->r.top); 6375bc3cb74SMauro Carvalho Chehab } 6385bc3cb74SMauro Carvalho Chehab 6395bc3cb74SMauro Carvalho Chehab static void v4l_print_jpegcompression(const void *arg, bool write_only) 6405bc3cb74SMauro Carvalho Chehab { 6415bc3cb74SMauro Carvalho Chehab const struct v4l2_jpegcompression *p = arg; 6425bc3cb74SMauro Carvalho Chehab 6438720427cSMauro Carvalho Chehab pr_cont("quality=%d, APPn=%d, APP_len=%d, COM_len=%d, jpeg_markers=0x%x\n", 6445bc3cb74SMauro Carvalho Chehab p->quality, p->APPn, p->APP_len, 6455bc3cb74SMauro Carvalho Chehab p->COM_len, p->jpeg_markers); 6465bc3cb74SMauro Carvalho Chehab } 6475bc3cb74SMauro Carvalho Chehab 6485bc3cb74SMauro Carvalho Chehab static void v4l_print_enc_idx(const void *arg, bool write_only) 6495bc3cb74SMauro Carvalho Chehab { 6505bc3cb74SMauro Carvalho Chehab const struct v4l2_enc_idx *p = arg; 6515bc3cb74SMauro Carvalho Chehab 6525bc3cb74SMauro Carvalho Chehab pr_cont("entries=%d, entries_cap=%d\n", 6535bc3cb74SMauro Carvalho Chehab p->entries, p->entries_cap); 6545bc3cb74SMauro Carvalho Chehab } 6555bc3cb74SMauro Carvalho Chehab 6565bc3cb74SMauro Carvalho Chehab static void v4l_print_encoder_cmd(const void *arg, bool write_only) 6575bc3cb74SMauro Carvalho Chehab { 6585bc3cb74SMauro Carvalho Chehab const struct v4l2_encoder_cmd *p = arg; 6595bc3cb74SMauro Carvalho Chehab 6605bc3cb74SMauro Carvalho Chehab pr_cont("cmd=%d, flags=0x%x\n", 6615bc3cb74SMauro Carvalho Chehab p->cmd, p->flags); 6625bc3cb74SMauro Carvalho Chehab } 6635bc3cb74SMauro Carvalho Chehab 6645bc3cb74SMauro Carvalho Chehab static void v4l_print_decoder_cmd(const void *arg, bool write_only) 6655bc3cb74SMauro Carvalho Chehab { 6665bc3cb74SMauro Carvalho Chehab const struct v4l2_decoder_cmd *p = arg; 6675bc3cb74SMauro Carvalho Chehab 6685bc3cb74SMauro Carvalho Chehab pr_cont("cmd=%d, flags=0x%x\n", p->cmd, p->flags); 6695bc3cb74SMauro Carvalho Chehab 6705bc3cb74SMauro Carvalho Chehab if (p->cmd == V4L2_DEC_CMD_START) 6715bc3cb74SMauro Carvalho Chehab pr_info("speed=%d, format=%u\n", 6725bc3cb74SMauro Carvalho Chehab p->start.speed, p->start.format); 6735bc3cb74SMauro Carvalho Chehab else if (p->cmd == V4L2_DEC_CMD_STOP) 6745bc3cb74SMauro Carvalho Chehab pr_info("pts=%llu\n", p->stop.pts); 6755bc3cb74SMauro Carvalho Chehab } 6765bc3cb74SMauro Carvalho Chehab 67796b03d2aSHans Verkuil static void v4l_print_dbg_chip_info(const void *arg, bool write_only) 67879b0c640SHans Verkuil { 67996b03d2aSHans Verkuil const struct v4l2_dbg_chip_info *p = arg; 68079b0c640SHans Verkuil 68179b0c640SHans Verkuil pr_cont("type=%u, ", p->match.type); 6823eef2510SHans Verkuil if (p->match.type == V4L2_CHIP_MATCH_I2C_DRIVER) 68379b0c640SHans Verkuil pr_cont("name=%.*s, ", 68479b0c640SHans Verkuil (int)sizeof(p->match.name), p->match.name); 68579b0c640SHans Verkuil else 68679b0c640SHans Verkuil pr_cont("addr=%u, ", p->match.addr); 68779b0c640SHans Verkuil pr_cont("name=%.*s\n", (int)sizeof(p->name), p->name); 68879b0c640SHans Verkuil } 68979b0c640SHans Verkuil 6905bc3cb74SMauro Carvalho Chehab static void v4l_print_dbg_register(const void *arg, bool write_only) 6915bc3cb74SMauro Carvalho Chehab { 6925bc3cb74SMauro Carvalho Chehab const struct v4l2_dbg_register *p = arg; 6935bc3cb74SMauro Carvalho Chehab 6945bc3cb74SMauro Carvalho Chehab pr_cont("type=%u, ", p->match.type); 6953eef2510SHans Verkuil if (p->match.type == V4L2_CHIP_MATCH_I2C_DRIVER) 69627d5a87cSHans Verkuil pr_cont("name=%.*s, ", 69727d5a87cSHans Verkuil (int)sizeof(p->match.name), p->match.name); 6985bc3cb74SMauro Carvalho Chehab else 6995bc3cb74SMauro Carvalho Chehab pr_cont("addr=%u, ", p->match.addr); 7005bc3cb74SMauro Carvalho Chehab pr_cont("reg=0x%llx, val=0x%llx\n", 7015bc3cb74SMauro Carvalho Chehab p->reg, p->val); 7025bc3cb74SMauro Carvalho Chehab } 7035bc3cb74SMauro Carvalho Chehab 7045bc3cb74SMauro Carvalho Chehab static void v4l_print_dv_timings(const void *arg, bool write_only) 7055bc3cb74SMauro Carvalho Chehab { 7065bc3cb74SMauro Carvalho Chehab const struct v4l2_dv_timings *p = arg; 7075bc3cb74SMauro Carvalho Chehab 7085bc3cb74SMauro Carvalho Chehab switch (p->type) { 7095bc3cb74SMauro Carvalho Chehab case V4L2_DV_BT_656_1120: 7108720427cSMauro Carvalho Chehab pr_cont("type=bt-656/1120, interlaced=%u, pixelclock=%llu, width=%u, height=%u, polarities=0x%x, hfrontporch=%u, hsync=%u, hbackporch=%u, vfrontporch=%u, vsync=%u, vbackporch=%u, il_vfrontporch=%u, il_vsync=%u, il_vbackporch=%u, standards=0x%x, flags=0x%x\n", 7115bc3cb74SMauro Carvalho Chehab p->bt.interlaced, p->bt.pixelclock, 7125bc3cb74SMauro Carvalho Chehab p->bt.width, p->bt.height, 7135bc3cb74SMauro Carvalho Chehab p->bt.polarities, p->bt.hfrontporch, 7145bc3cb74SMauro Carvalho Chehab p->bt.hsync, p->bt.hbackporch, 7155bc3cb74SMauro Carvalho Chehab p->bt.vfrontporch, p->bt.vsync, 7165bc3cb74SMauro Carvalho Chehab p->bt.vbackporch, p->bt.il_vfrontporch, 7175bc3cb74SMauro Carvalho Chehab p->bt.il_vsync, p->bt.il_vbackporch, 7185bc3cb74SMauro Carvalho Chehab p->bt.standards, p->bt.flags); 7195bc3cb74SMauro Carvalho Chehab break; 7205bc3cb74SMauro Carvalho Chehab default: 7215bc3cb74SMauro Carvalho Chehab pr_cont("type=%d\n", p->type); 7225bc3cb74SMauro Carvalho Chehab break; 7235bc3cb74SMauro Carvalho Chehab } 7245bc3cb74SMauro Carvalho Chehab } 7255bc3cb74SMauro Carvalho Chehab 7265bc3cb74SMauro Carvalho Chehab static void v4l_print_enum_dv_timings(const void *arg, bool write_only) 7275bc3cb74SMauro Carvalho Chehab { 7285bc3cb74SMauro Carvalho Chehab const struct v4l2_enum_dv_timings *p = arg; 7295bc3cb74SMauro Carvalho Chehab 7305bc3cb74SMauro Carvalho Chehab pr_cont("index=%u, ", p->index); 7315bc3cb74SMauro Carvalho Chehab v4l_print_dv_timings(&p->timings, write_only); 7325bc3cb74SMauro Carvalho Chehab } 7335bc3cb74SMauro Carvalho Chehab 7345bc3cb74SMauro Carvalho Chehab static void v4l_print_dv_timings_cap(const void *arg, bool write_only) 7355bc3cb74SMauro Carvalho Chehab { 7365bc3cb74SMauro Carvalho Chehab const struct v4l2_dv_timings_cap *p = arg; 7375bc3cb74SMauro Carvalho Chehab 7385bc3cb74SMauro Carvalho Chehab switch (p->type) { 7395bc3cb74SMauro Carvalho Chehab case V4L2_DV_BT_656_1120: 7408720427cSMauro Carvalho Chehab pr_cont("type=bt-656/1120, width=%u-%u, height=%u-%u, pixelclock=%llu-%llu, standards=0x%x, capabilities=0x%x\n", 7415bc3cb74SMauro Carvalho Chehab p->bt.min_width, p->bt.max_width, 7425bc3cb74SMauro Carvalho Chehab p->bt.min_height, p->bt.max_height, 7435bc3cb74SMauro Carvalho Chehab p->bt.min_pixelclock, p->bt.max_pixelclock, 7445bc3cb74SMauro Carvalho Chehab p->bt.standards, p->bt.capabilities); 7455bc3cb74SMauro Carvalho Chehab break; 7465bc3cb74SMauro Carvalho Chehab default: 7475bc3cb74SMauro Carvalho Chehab pr_cont("type=%u\n", p->type); 7485bc3cb74SMauro Carvalho Chehab break; 7495bc3cb74SMauro Carvalho Chehab } 7505bc3cb74SMauro Carvalho Chehab } 7515bc3cb74SMauro Carvalho Chehab 7525bc3cb74SMauro Carvalho Chehab static void v4l_print_frmsizeenum(const void *arg, bool write_only) 7535bc3cb74SMauro Carvalho Chehab { 7545bc3cb74SMauro Carvalho Chehab const struct v4l2_frmsizeenum *p = arg; 7555bc3cb74SMauro Carvalho Chehab 7565bc3cb74SMauro Carvalho Chehab pr_cont("index=%u, pixelformat=%c%c%c%c, type=%u", 7575bc3cb74SMauro Carvalho Chehab p->index, 7585bc3cb74SMauro Carvalho Chehab (p->pixel_format & 0xff), 7595bc3cb74SMauro Carvalho Chehab (p->pixel_format >> 8) & 0xff, 7605bc3cb74SMauro Carvalho Chehab (p->pixel_format >> 16) & 0xff, 7615bc3cb74SMauro Carvalho Chehab (p->pixel_format >> 24) & 0xff, 7625bc3cb74SMauro Carvalho Chehab p->type); 7635bc3cb74SMauro Carvalho Chehab switch (p->type) { 7645bc3cb74SMauro Carvalho Chehab case V4L2_FRMSIZE_TYPE_DISCRETE: 765560dde24SHans Verkuil pr_cont(", wxh=%ux%u\n", 7665bc3cb74SMauro Carvalho Chehab p->discrete.width, p->discrete.height); 7675bc3cb74SMauro Carvalho Chehab break; 7685bc3cb74SMauro Carvalho Chehab case V4L2_FRMSIZE_TYPE_STEPWISE: 769560dde24SHans Verkuil pr_cont(", min=%ux%u, max=%ux%u, step=%ux%u\n", 7702489477eSRicardo Ribalda p->stepwise.min_width, 7712489477eSRicardo Ribalda p->stepwise.min_height, 7722489477eSRicardo Ribalda p->stepwise.max_width, 7732489477eSRicardo Ribalda p->stepwise.max_height, 7742489477eSRicardo Ribalda p->stepwise.step_width, 7752489477eSRicardo Ribalda p->stepwise.step_height); 7765bc3cb74SMauro Carvalho Chehab break; 7775bc3cb74SMauro Carvalho Chehab case V4L2_FRMSIZE_TYPE_CONTINUOUS: 7785bc3cb74SMauro Carvalho Chehab /* fall through */ 7795bc3cb74SMauro Carvalho Chehab default: 7805bc3cb74SMauro Carvalho Chehab pr_cont("\n"); 7815bc3cb74SMauro Carvalho Chehab break; 7825bc3cb74SMauro Carvalho Chehab } 7835bc3cb74SMauro Carvalho Chehab } 7845bc3cb74SMauro Carvalho Chehab 7855bc3cb74SMauro Carvalho Chehab static void v4l_print_frmivalenum(const void *arg, bool write_only) 7865bc3cb74SMauro Carvalho Chehab { 7875bc3cb74SMauro Carvalho Chehab const struct v4l2_frmivalenum *p = arg; 7885bc3cb74SMauro Carvalho Chehab 7895bc3cb74SMauro Carvalho Chehab pr_cont("index=%u, pixelformat=%c%c%c%c, wxh=%ux%u, type=%u", 7905bc3cb74SMauro Carvalho Chehab p->index, 7915bc3cb74SMauro Carvalho Chehab (p->pixel_format & 0xff), 7925bc3cb74SMauro Carvalho Chehab (p->pixel_format >> 8) & 0xff, 7935bc3cb74SMauro Carvalho Chehab (p->pixel_format >> 16) & 0xff, 7945bc3cb74SMauro Carvalho Chehab (p->pixel_format >> 24) & 0xff, 7955bc3cb74SMauro Carvalho Chehab p->width, p->height, p->type); 7965bc3cb74SMauro Carvalho Chehab switch (p->type) { 7975bc3cb74SMauro Carvalho Chehab case V4L2_FRMIVAL_TYPE_DISCRETE: 798560dde24SHans Verkuil pr_cont(", fps=%d/%d\n", 7995bc3cb74SMauro Carvalho Chehab p->discrete.numerator, 8005bc3cb74SMauro Carvalho Chehab p->discrete.denominator); 8015bc3cb74SMauro Carvalho Chehab break; 8025bc3cb74SMauro Carvalho Chehab case V4L2_FRMIVAL_TYPE_STEPWISE: 803560dde24SHans Verkuil pr_cont(", min=%d/%d, max=%d/%d, step=%d/%d\n", 8045bc3cb74SMauro Carvalho Chehab p->stepwise.min.numerator, 8055bc3cb74SMauro Carvalho Chehab p->stepwise.min.denominator, 8065bc3cb74SMauro Carvalho Chehab p->stepwise.max.numerator, 8075bc3cb74SMauro Carvalho Chehab p->stepwise.max.denominator, 8085bc3cb74SMauro Carvalho Chehab p->stepwise.step.numerator, 8095bc3cb74SMauro Carvalho Chehab p->stepwise.step.denominator); 8105bc3cb74SMauro Carvalho Chehab break; 8115bc3cb74SMauro Carvalho Chehab case V4L2_FRMIVAL_TYPE_CONTINUOUS: 8125bc3cb74SMauro Carvalho Chehab /* fall through */ 8135bc3cb74SMauro Carvalho Chehab default: 8145bc3cb74SMauro Carvalho Chehab pr_cont("\n"); 8155bc3cb74SMauro Carvalho Chehab break; 8165bc3cb74SMauro Carvalho Chehab } 8175bc3cb74SMauro Carvalho Chehab } 8185bc3cb74SMauro Carvalho Chehab 8195bc3cb74SMauro Carvalho Chehab static void v4l_print_event(const void *arg, bool write_only) 8205bc3cb74SMauro Carvalho Chehab { 8215bc3cb74SMauro Carvalho Chehab const struct v4l2_event *p = arg; 8225bc3cb74SMauro Carvalho Chehab const struct v4l2_event_ctrl *c; 8235bc3cb74SMauro Carvalho Chehab 8248720427cSMauro Carvalho Chehab pr_cont("type=0x%x, pending=%u, sequence=%u, id=%u, timestamp=%lu.%9.9lu\n", 8255bc3cb74SMauro Carvalho Chehab p->type, p->pending, p->sequence, p->id, 8265bc3cb74SMauro Carvalho Chehab p->timestamp.tv_sec, p->timestamp.tv_nsec); 8275bc3cb74SMauro Carvalho Chehab switch (p->type) { 8285bc3cb74SMauro Carvalho Chehab case V4L2_EVENT_VSYNC: 8295bc3cb74SMauro Carvalho Chehab printk(KERN_DEBUG "field=%s\n", 8305bc3cb74SMauro Carvalho Chehab prt_names(p->u.vsync.field, v4l2_field_names)); 8315bc3cb74SMauro Carvalho Chehab break; 8325bc3cb74SMauro Carvalho Chehab case V4L2_EVENT_CTRL: 8335bc3cb74SMauro Carvalho Chehab c = &p->u.ctrl; 8345bc3cb74SMauro Carvalho Chehab printk(KERN_DEBUG "changes=0x%x, type=%u, ", 8355bc3cb74SMauro Carvalho Chehab c->changes, c->type); 8365bc3cb74SMauro Carvalho Chehab if (c->type == V4L2_CTRL_TYPE_INTEGER64) 8375bc3cb74SMauro Carvalho Chehab pr_cont("value64=%lld, ", c->value64); 8385bc3cb74SMauro Carvalho Chehab else 8395bc3cb74SMauro Carvalho Chehab pr_cont("value=%d, ", c->value); 8408720427cSMauro Carvalho Chehab pr_cont("flags=0x%x, minimum=%d, maximum=%d, step=%d, default_value=%d\n", 8415bc3cb74SMauro Carvalho Chehab c->flags, c->minimum, c->maximum, 8425bc3cb74SMauro Carvalho Chehab c->step, c->default_value); 8435bc3cb74SMauro Carvalho Chehab break; 8445bc3cb74SMauro Carvalho Chehab case V4L2_EVENT_FRAME_SYNC: 8455bc3cb74SMauro Carvalho Chehab pr_cont("frame_sequence=%u\n", 8465bc3cb74SMauro Carvalho Chehab p->u.frame_sync.frame_sequence); 8475bc3cb74SMauro Carvalho Chehab break; 8485bc3cb74SMauro Carvalho Chehab } 8495bc3cb74SMauro Carvalho Chehab } 8505bc3cb74SMauro Carvalho Chehab 8515bc3cb74SMauro Carvalho Chehab static void v4l_print_event_subscription(const void *arg, bool write_only) 8525bc3cb74SMauro Carvalho Chehab { 8535bc3cb74SMauro Carvalho Chehab const struct v4l2_event_subscription *p = arg; 8545bc3cb74SMauro Carvalho Chehab 8555bc3cb74SMauro Carvalho Chehab pr_cont("type=0x%x, id=0x%x, flags=0x%x\n", 8565bc3cb74SMauro Carvalho Chehab p->type, p->id, p->flags); 8575bc3cb74SMauro Carvalho Chehab } 8585bc3cb74SMauro Carvalho Chehab 8595bc3cb74SMauro Carvalho Chehab static void v4l_print_sliced_vbi_cap(const void *arg, bool write_only) 8605bc3cb74SMauro Carvalho Chehab { 8615bc3cb74SMauro Carvalho Chehab const struct v4l2_sliced_vbi_cap *p = arg; 8625bc3cb74SMauro Carvalho Chehab int i; 8635bc3cb74SMauro Carvalho Chehab 8645bc3cb74SMauro Carvalho Chehab pr_cont("type=%s, service_set=0x%08x\n", 8655bc3cb74SMauro Carvalho Chehab prt_names(p->type, v4l2_type_names), p->service_set); 8665bc3cb74SMauro Carvalho Chehab for (i = 0; i < 24; i++) 8675bc3cb74SMauro Carvalho Chehab printk(KERN_DEBUG "line[%02u]=0x%04x, 0x%04x\n", i, 8685bc3cb74SMauro Carvalho Chehab p->service_lines[0][i], 8695bc3cb74SMauro Carvalho Chehab p->service_lines[1][i]); 8705bc3cb74SMauro Carvalho Chehab } 8715bc3cb74SMauro Carvalho Chehab 8725bc3cb74SMauro Carvalho Chehab static void v4l_print_freq_band(const void *arg, bool write_only) 8735bc3cb74SMauro Carvalho Chehab { 8745bc3cb74SMauro Carvalho Chehab const struct v4l2_frequency_band *p = arg; 8755bc3cb74SMauro Carvalho Chehab 8768720427cSMauro Carvalho Chehab pr_cont("tuner=%u, type=%u, index=%u, capability=0x%x, rangelow=%u, rangehigh=%u, modulation=0x%x\n", 8775bc3cb74SMauro Carvalho Chehab p->tuner, p->type, p->index, 8785bc3cb74SMauro Carvalho Chehab p->capability, p->rangelow, 8795bc3cb74SMauro Carvalho Chehab p->rangehigh, p->modulation); 8805bc3cb74SMauro Carvalho Chehab } 8815bc3cb74SMauro Carvalho Chehab 882dd519bb3SHans Verkuil static void v4l_print_edid(const void *arg, bool write_only) 883dd519bb3SHans Verkuil { 884dd519bb3SHans Verkuil const struct v4l2_edid *p = arg; 885dd519bb3SHans Verkuil 886dd519bb3SHans Verkuil pr_cont("pad=%u, start_block=%u, blocks=%u\n", 887dd519bb3SHans Verkuil p->pad, p->start_block, p->blocks); 888dd519bb3SHans Verkuil } 889dd519bb3SHans Verkuil 8905bc3cb74SMauro Carvalho Chehab static void v4l_print_u32(const void *arg, bool write_only) 8915bc3cb74SMauro Carvalho Chehab { 8925bc3cb74SMauro Carvalho Chehab pr_cont("value=%u\n", *(const u32 *)arg); 8935bc3cb74SMauro Carvalho Chehab } 8945bc3cb74SMauro Carvalho Chehab 8955bc3cb74SMauro Carvalho Chehab static void v4l_print_newline(const void *arg, bool write_only) 8965bc3cb74SMauro Carvalho Chehab { 8975bc3cb74SMauro Carvalho Chehab pr_cont("\n"); 8985bc3cb74SMauro Carvalho Chehab } 8995bc3cb74SMauro Carvalho Chehab 9005bc3cb74SMauro Carvalho Chehab static void v4l_print_default(const void *arg, bool write_only) 9015bc3cb74SMauro Carvalho Chehab { 9025bc3cb74SMauro Carvalho Chehab pr_cont("driver-specific ioctl\n"); 9035bc3cb74SMauro Carvalho Chehab } 9045bc3cb74SMauro Carvalho Chehab 9055bc3cb74SMauro Carvalho Chehab static int check_ext_ctrls(struct v4l2_ext_controls *c, int allow_priv) 9065bc3cb74SMauro Carvalho Chehab { 9075bc3cb74SMauro Carvalho Chehab __u32 i; 9085bc3cb74SMauro Carvalho Chehab 9095bc3cb74SMauro Carvalho Chehab /* zero the reserved fields */ 910f23317adSAlexandre Courbot c->reserved[0] = 0; 9115bc3cb74SMauro Carvalho Chehab for (i = 0; i < c->count; i++) 9125bc3cb74SMauro Carvalho Chehab c->controls[i].reserved2[0] = 0; 9135bc3cb74SMauro Carvalho Chehab 9145bc3cb74SMauro Carvalho Chehab /* V4L2_CID_PRIVATE_BASE cannot be used as control class 9155bc3cb74SMauro Carvalho Chehab when using extended controls. 9165bc3cb74SMauro Carvalho Chehab Only when passed in through VIDIOC_G_CTRL and VIDIOC_S_CTRL 9175bc3cb74SMauro Carvalho Chehab is it allowed for backwards compatibility. 9185bc3cb74SMauro Carvalho Chehab */ 9190f8017beSRicardo Ribalda if (!allow_priv && c->which == V4L2_CID_PRIVATE_BASE) 9205bc3cb74SMauro Carvalho Chehab return 0; 9210f8017beSRicardo Ribalda if (!c->which) 9229b239b22SHans Verkuil return 1; 9235bc3cb74SMauro Carvalho Chehab /* Check that all controls are from the same control class. */ 9245bc3cb74SMauro Carvalho Chehab for (i = 0; i < c->count; i++) { 9250f8017beSRicardo Ribalda if (V4L2_CTRL_ID2WHICH(c->controls[i].id) != c->which) { 9265bc3cb74SMauro Carvalho Chehab c->error_idx = i; 9275bc3cb74SMauro Carvalho Chehab return 0; 9285bc3cb74SMauro Carvalho Chehab } 9295bc3cb74SMauro Carvalho Chehab } 9305bc3cb74SMauro Carvalho Chehab return 1; 9315bc3cb74SMauro Carvalho Chehab } 9325bc3cb74SMauro Carvalho Chehab 9334b20259fSHans Verkuil static int check_fmt(struct file *file, enum v4l2_buf_type type) 9345bc3cb74SMauro Carvalho Chehab { 9354b20259fSHans Verkuil struct video_device *vfd = video_devdata(file); 9364b20259fSHans Verkuil const struct v4l2_ioctl_ops *ops = vfd->ioctl_ops; 9374b20259fSHans Verkuil bool is_vid = vfd->vfl_type == VFL_TYPE_GRABBER; 9384b20259fSHans Verkuil bool is_vbi = vfd->vfl_type == VFL_TYPE_VBI; 939582c52cbSAntti Palosaari bool is_sdr = vfd->vfl_type == VFL_TYPE_SDR; 940b2fe22d0SNick Dyer bool is_tch = vfd->vfl_type == VFL_TYPE_TOUCH; 9414b20259fSHans Verkuil bool is_rx = vfd->vfl_dir != VFL_DIR_TX; 9424b20259fSHans Verkuil bool is_tx = vfd->vfl_dir != VFL_DIR_RX; 9434b20259fSHans Verkuil 9445bc3cb74SMauro Carvalho Chehab if (ops == NULL) 9455bc3cb74SMauro Carvalho Chehab return -EINVAL; 9465bc3cb74SMauro Carvalho Chehab 9475bc3cb74SMauro Carvalho Chehab switch (type) { 9485bc3cb74SMauro Carvalho Chehab case V4L2_BUF_TYPE_VIDEO_CAPTURE: 949b2fe22d0SNick Dyer if ((is_vid || is_tch) && is_rx && 9504b20259fSHans Verkuil (ops->vidioc_g_fmt_vid_cap || ops->vidioc_g_fmt_vid_cap_mplane)) 9515bc3cb74SMauro Carvalho Chehab return 0; 9525bc3cb74SMauro Carvalho Chehab break; 9535bc3cb74SMauro Carvalho Chehab case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE: 9544b20259fSHans Verkuil if (is_vid && is_rx && ops->vidioc_g_fmt_vid_cap_mplane) 9555bc3cb74SMauro Carvalho Chehab return 0; 9565bc3cb74SMauro Carvalho Chehab break; 9575bc3cb74SMauro Carvalho Chehab case V4L2_BUF_TYPE_VIDEO_OVERLAY: 9584b20259fSHans Verkuil if (is_vid && is_rx && ops->vidioc_g_fmt_vid_overlay) 9595bc3cb74SMauro Carvalho Chehab return 0; 9605bc3cb74SMauro Carvalho Chehab break; 9615bc3cb74SMauro Carvalho Chehab case V4L2_BUF_TYPE_VIDEO_OUTPUT: 9624b20259fSHans Verkuil if (is_vid && is_tx && 9634b20259fSHans Verkuil (ops->vidioc_g_fmt_vid_out || ops->vidioc_g_fmt_vid_out_mplane)) 9645bc3cb74SMauro Carvalho Chehab return 0; 9655bc3cb74SMauro Carvalho Chehab break; 9665bc3cb74SMauro Carvalho Chehab case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE: 9674b20259fSHans Verkuil if (is_vid && is_tx && ops->vidioc_g_fmt_vid_out_mplane) 9685bc3cb74SMauro Carvalho Chehab return 0; 9695bc3cb74SMauro Carvalho Chehab break; 9705bc3cb74SMauro Carvalho Chehab case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY: 9714b20259fSHans Verkuil if (is_vid && is_tx && ops->vidioc_g_fmt_vid_out_overlay) 9725bc3cb74SMauro Carvalho Chehab return 0; 9735bc3cb74SMauro Carvalho Chehab break; 9745bc3cb74SMauro Carvalho Chehab case V4L2_BUF_TYPE_VBI_CAPTURE: 9754b20259fSHans Verkuil if (is_vbi && is_rx && ops->vidioc_g_fmt_vbi_cap) 9765bc3cb74SMauro Carvalho Chehab return 0; 9775bc3cb74SMauro Carvalho Chehab break; 9785bc3cb74SMauro Carvalho Chehab case V4L2_BUF_TYPE_VBI_OUTPUT: 9794b20259fSHans Verkuil if (is_vbi && is_tx && ops->vidioc_g_fmt_vbi_out) 9805bc3cb74SMauro Carvalho Chehab return 0; 9815bc3cb74SMauro Carvalho Chehab break; 9825bc3cb74SMauro Carvalho Chehab case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE: 9834b20259fSHans Verkuil if (is_vbi && is_rx && ops->vidioc_g_fmt_sliced_vbi_cap) 9845bc3cb74SMauro Carvalho Chehab return 0; 9855bc3cb74SMauro Carvalho Chehab break; 9865bc3cb74SMauro Carvalho Chehab case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT: 9874b20259fSHans Verkuil if (is_vbi && is_tx && ops->vidioc_g_fmt_sliced_vbi_out) 9885bc3cb74SMauro Carvalho Chehab return 0; 9895bc3cb74SMauro Carvalho Chehab break; 990582c52cbSAntti Palosaari case V4L2_BUF_TYPE_SDR_CAPTURE: 991582c52cbSAntti Palosaari if (is_sdr && is_rx && ops->vidioc_g_fmt_sdr_cap) 992582c52cbSAntti Palosaari return 0; 993582c52cbSAntti Palosaari break; 9949effc72fSAntti Palosaari case V4L2_BUF_TYPE_SDR_OUTPUT: 9959effc72fSAntti Palosaari if (is_sdr && is_tx && ops->vidioc_g_fmt_sdr_out) 9969effc72fSAntti Palosaari return 0; 9979effc72fSAntti Palosaari break; 998fb9ffa6aSLaurent Pinchart case V4L2_BUF_TYPE_META_CAPTURE: 999fb9ffa6aSLaurent Pinchart if (is_vid && is_rx && ops->vidioc_g_fmt_meta_cap) 1000fb9ffa6aSLaurent Pinchart return 0; 1001fb9ffa6aSLaurent Pinchart break; 1002633c98e5SHans Verkuil default: 10035bc3cb74SMauro Carvalho Chehab break; 10045bc3cb74SMauro Carvalho Chehab } 10055bc3cb74SMauro Carvalho Chehab return -EINVAL; 10065bc3cb74SMauro Carvalho Chehab } 10075bc3cb74SMauro Carvalho Chehab 1008d52e2381SLaurent Pinchart static void v4l_sanitize_format(struct v4l2_format *fmt) 1009d52e2381SLaurent Pinchart { 1010d52e2381SLaurent Pinchart unsigned int offset; 1011d52e2381SLaurent Pinchart 1012d52e2381SLaurent Pinchart /* 1013d52e2381SLaurent Pinchart * The v4l2_pix_format structure has been extended with fields that were 1014d52e2381SLaurent Pinchart * not previously required to be set to zero by applications. The priv 1015d52e2381SLaurent Pinchart * field, when set to a magic value, indicates the the extended fields 1016d52e2381SLaurent Pinchart * are valid. Otherwise they will contain undefined values. To simplify 1017d52e2381SLaurent Pinchart * the API towards drivers zero the extended fields and set the priv 1018d52e2381SLaurent Pinchart * field to the magic value when the extended pixel format structure 1019d52e2381SLaurent Pinchart * isn't used by applications. 1020d52e2381SLaurent Pinchart */ 1021d52e2381SLaurent Pinchart 1022d52e2381SLaurent Pinchart if (fmt->type != V4L2_BUF_TYPE_VIDEO_CAPTURE && 1023d52e2381SLaurent Pinchart fmt->type != V4L2_BUF_TYPE_VIDEO_OUTPUT) 1024d52e2381SLaurent Pinchart return; 1025d52e2381SLaurent Pinchart 1026d52e2381SLaurent Pinchart if (fmt->fmt.pix.priv == V4L2_PIX_FMT_PRIV_MAGIC) 1027d52e2381SLaurent Pinchart return; 1028d52e2381SLaurent Pinchart 1029d52e2381SLaurent Pinchart fmt->fmt.pix.priv = V4L2_PIX_FMT_PRIV_MAGIC; 1030d52e2381SLaurent Pinchart 1031d52e2381SLaurent Pinchart offset = offsetof(struct v4l2_pix_format, priv) 1032d52e2381SLaurent Pinchart + sizeof(fmt->fmt.pix.priv); 1033d52e2381SLaurent Pinchart memset(((void *)&fmt->fmt.pix) + offset, 0, 1034d52e2381SLaurent Pinchart sizeof(fmt->fmt.pix) - offset); 1035d52e2381SLaurent Pinchart } 1036d52e2381SLaurent Pinchart 10375bc3cb74SMauro Carvalho Chehab static int v4l_querycap(const struct v4l2_ioctl_ops *ops, 10385bc3cb74SMauro Carvalho Chehab struct file *file, void *fh, void *arg) 10395bc3cb74SMauro Carvalho Chehab { 10405bc3cb74SMauro Carvalho Chehab struct v4l2_capability *cap = (struct v4l2_capability *)arg; 10417bbe7813SHans Verkuil struct video_device *vfd = video_devdata(file); 1042d52e2381SLaurent Pinchart int ret; 10435bc3cb74SMauro Carvalho Chehab 10445bc3cb74SMauro Carvalho Chehab cap->version = LINUX_VERSION_CODE; 10457bbe7813SHans Verkuil cap->device_caps = vfd->device_caps; 10467bbe7813SHans Verkuil cap->capabilities = vfd->device_caps | V4L2_CAP_DEVICE_CAPS; 1047d52e2381SLaurent Pinchart 1048d52e2381SLaurent Pinchart ret = ops->vidioc_querycap(file, fh, cap); 1049d52e2381SLaurent Pinchart 1050d52e2381SLaurent Pinchart cap->capabilities |= V4L2_CAP_EXT_PIX_FORMAT; 1051454a4e72SHans Verkuil /* 1052454a4e72SHans Verkuil * Drivers MUST fill in device_caps, so check for this and 1053454a4e72SHans Verkuil * warn if it was forgotten. 1054454a4e72SHans Verkuil */ 10556d7570c4SLaura Abbott WARN(!(cap->capabilities & V4L2_CAP_DEVICE_CAPS) || 10566d7570c4SLaura Abbott !cap->device_caps, "Bad caps for driver %s, %x %x", 10576d7570c4SLaura Abbott cap->driver, cap->capabilities, cap->device_caps); 1058796a2bd2SHans Verkuil cap->device_caps |= V4L2_CAP_EXT_PIX_FORMAT; 1059d52e2381SLaurent Pinchart 1060d52e2381SLaurent Pinchart return ret; 10615bc3cb74SMauro Carvalho Chehab } 10625bc3cb74SMauro Carvalho Chehab 10635bc3cb74SMauro Carvalho Chehab static int v4l_s_input(const struct v4l2_ioctl_ops *ops, 10645bc3cb74SMauro Carvalho Chehab struct file *file, void *fh, void *arg) 10655bc3cb74SMauro Carvalho Chehab { 106677fa4e07SShuah Khan struct video_device *vfd = video_devdata(file); 106777fa4e07SShuah Khan int ret; 106877fa4e07SShuah Khan 106977fa4e07SShuah Khan ret = v4l_enable_media_source(vfd); 107077fa4e07SShuah Khan if (ret) 107177fa4e07SShuah Khan return ret; 10725bc3cb74SMauro Carvalho Chehab return ops->vidioc_s_input(file, fh, *(unsigned int *)arg); 10735bc3cb74SMauro Carvalho Chehab } 10745bc3cb74SMauro Carvalho Chehab 10755bc3cb74SMauro Carvalho Chehab static int v4l_s_output(const struct v4l2_ioctl_ops *ops, 10765bc3cb74SMauro Carvalho Chehab struct file *file, void *fh, void *arg) 10775bc3cb74SMauro Carvalho Chehab { 10785bc3cb74SMauro Carvalho Chehab return ops->vidioc_s_output(file, fh, *(unsigned int *)arg); 10795bc3cb74SMauro Carvalho Chehab } 10805bc3cb74SMauro Carvalho Chehab 10815bc3cb74SMauro Carvalho Chehab static int v4l_g_priority(const struct v4l2_ioctl_ops *ops, 10825bc3cb74SMauro Carvalho Chehab struct file *file, void *fh, void *arg) 10835bc3cb74SMauro Carvalho Chehab { 10845bc3cb74SMauro Carvalho Chehab struct video_device *vfd; 10855bc3cb74SMauro Carvalho Chehab u32 *p = arg; 10865bc3cb74SMauro Carvalho Chehab 10875bc3cb74SMauro Carvalho Chehab vfd = video_devdata(file); 108859b702eaSLaurent Pinchart *p = v4l2_prio_max(vfd->prio); 10895bc3cb74SMauro Carvalho Chehab return 0; 10905bc3cb74SMauro Carvalho Chehab } 10915bc3cb74SMauro Carvalho Chehab 10925bc3cb74SMauro Carvalho Chehab static int v4l_s_priority(const struct v4l2_ioctl_ops *ops, 10935bc3cb74SMauro Carvalho Chehab struct file *file, void *fh, void *arg) 10945bc3cb74SMauro Carvalho Chehab { 10955bc3cb74SMauro Carvalho Chehab struct video_device *vfd; 10965bc3cb74SMauro Carvalho Chehab struct v4l2_fh *vfh; 10975bc3cb74SMauro Carvalho Chehab u32 *p = arg; 10985bc3cb74SMauro Carvalho Chehab 10995bc3cb74SMauro Carvalho Chehab vfd = video_devdata(file); 11002438e78aSHans Verkuil if (!test_bit(V4L2_FL_USES_V4L2_FH, &vfd->flags)) 11012438e78aSHans Verkuil return -ENOTTY; 11025bc3cb74SMauro Carvalho Chehab vfh = file->private_data; 110359b702eaSLaurent Pinchart return v4l2_prio_change(vfd->prio, &vfh->prio, *p); 11045bc3cb74SMauro Carvalho Chehab } 11055bc3cb74SMauro Carvalho Chehab 11065bc3cb74SMauro Carvalho Chehab static int v4l_enuminput(const struct v4l2_ioctl_ops *ops, 11075bc3cb74SMauro Carvalho Chehab struct file *file, void *fh, void *arg) 11085bc3cb74SMauro Carvalho Chehab { 110973f35418SHans Verkuil struct video_device *vfd = video_devdata(file); 11105bc3cb74SMauro Carvalho Chehab struct v4l2_input *p = arg; 11115bc3cb74SMauro Carvalho Chehab 11125bc3cb74SMauro Carvalho Chehab /* 111302fa6282SHans Verkuil * We set the flags for CAP_DV_TIMINGS & 11145bc3cb74SMauro Carvalho Chehab * CAP_STD here based on ioctl handler provided by the 11155bc3cb74SMauro Carvalho Chehab * driver. If the driver doesn't support these 11165bc3cb74SMauro Carvalho Chehab * for a specific input, it must override these flags. 11175bc3cb74SMauro Carvalho Chehab */ 111873f35418SHans Verkuil if (is_valid_ioctl(vfd, VIDIOC_S_STD)) 11195bc3cb74SMauro Carvalho Chehab p->capabilities |= V4L2_IN_CAP_STD; 11205bc3cb74SMauro Carvalho Chehab 11215bc3cb74SMauro Carvalho Chehab return ops->vidioc_enum_input(file, fh, p); 11225bc3cb74SMauro Carvalho Chehab } 11235bc3cb74SMauro Carvalho Chehab 11245bc3cb74SMauro Carvalho Chehab static int v4l_enumoutput(const struct v4l2_ioctl_ops *ops, 11255bc3cb74SMauro Carvalho Chehab struct file *file, void *fh, void *arg) 11265bc3cb74SMauro Carvalho Chehab { 112773f35418SHans Verkuil struct video_device *vfd = video_devdata(file); 11285bc3cb74SMauro Carvalho Chehab struct v4l2_output *p = arg; 11295bc3cb74SMauro Carvalho Chehab 11305bc3cb74SMauro Carvalho Chehab /* 113102fa6282SHans Verkuil * We set the flags for CAP_DV_TIMINGS & 11325bc3cb74SMauro Carvalho Chehab * CAP_STD here based on ioctl handler provided by the 11335bc3cb74SMauro Carvalho Chehab * driver. If the driver doesn't support these 11345bc3cb74SMauro Carvalho Chehab * for a specific output, it must override these flags. 11355bc3cb74SMauro Carvalho Chehab */ 113673f35418SHans Verkuil if (is_valid_ioctl(vfd, VIDIOC_S_STD)) 11375bc3cb74SMauro Carvalho Chehab p->capabilities |= V4L2_OUT_CAP_STD; 11385bc3cb74SMauro Carvalho Chehab 11395bc3cb74SMauro Carvalho Chehab return ops->vidioc_enum_output(file, fh, p); 11405bc3cb74SMauro Carvalho Chehab } 11415bc3cb74SMauro Carvalho Chehab 1142ba300204SHans Verkuil static void v4l_fill_fmtdesc(struct v4l2_fmtdesc *fmt) 1143ba300204SHans Verkuil { 1144ba300204SHans Verkuil const unsigned sz = sizeof(fmt->description); 1145ba300204SHans Verkuil const char *descr = NULL; 1146ba300204SHans Verkuil u32 flags = 0; 1147ba300204SHans Verkuil 1148ba300204SHans Verkuil /* 1149ba300204SHans Verkuil * We depart from the normal coding style here since the descriptions 1150ba300204SHans Verkuil * should be aligned so it is easy to see which descriptions will be 1151ba300204SHans Verkuil * longer than 31 characters (the max length for a description). 1152ba300204SHans Verkuil * And frankly, this is easier to read anyway. 1153ba300204SHans Verkuil * 1154ba300204SHans Verkuil * Note that gcc will use O(log N) comparisons to find the right case. 1155ba300204SHans Verkuil */ 1156ba300204SHans Verkuil switch (fmt->pixelformat) { 1157ba300204SHans Verkuil /* Max description length mask: descr = "0123456789012345678901234567890" */ 1158ba300204SHans Verkuil case V4L2_PIX_FMT_RGB332: descr = "8-bit RGB 3-3-2"; break; 1159ba300204SHans Verkuil case V4L2_PIX_FMT_RGB444: descr = "16-bit A/XRGB 4-4-4-4"; break; 1160ba300204SHans Verkuil case V4L2_PIX_FMT_ARGB444: descr = "16-bit ARGB 4-4-4-4"; break; 1161ba300204SHans Verkuil case V4L2_PIX_FMT_XRGB444: descr = "16-bit XRGB 4-4-4-4"; break; 1162ba300204SHans Verkuil case V4L2_PIX_FMT_RGB555: descr = "16-bit A/XRGB 1-5-5-5"; break; 1163ba300204SHans Verkuil case V4L2_PIX_FMT_ARGB555: descr = "16-bit ARGB 1-5-5-5"; break; 1164ba300204SHans Verkuil case V4L2_PIX_FMT_XRGB555: descr = "16-bit XRGB 1-5-5-5"; break; 1165ba300204SHans Verkuil case V4L2_PIX_FMT_RGB565: descr = "16-bit RGB 5-6-5"; break; 1166ba300204SHans Verkuil case V4L2_PIX_FMT_RGB555X: descr = "16-bit A/XRGB 1-5-5-5 BE"; break; 1167ba300204SHans Verkuil case V4L2_PIX_FMT_ARGB555X: descr = "16-bit ARGB 1-5-5-5 BE"; break; 1168ba300204SHans Verkuil case V4L2_PIX_FMT_XRGB555X: descr = "16-bit XRGB 1-5-5-5 BE"; break; 1169ba300204SHans Verkuil case V4L2_PIX_FMT_RGB565X: descr = "16-bit RGB 5-6-5 BE"; break; 1170ba300204SHans Verkuil case V4L2_PIX_FMT_BGR666: descr = "18-bit BGRX 6-6-6-14"; break; 1171ba300204SHans Verkuil case V4L2_PIX_FMT_BGR24: descr = "24-bit BGR 8-8-8"; break; 1172ba300204SHans Verkuil case V4L2_PIX_FMT_RGB24: descr = "24-bit RGB 8-8-8"; break; 1173ba300204SHans Verkuil case V4L2_PIX_FMT_BGR32: descr = "32-bit BGRA/X 8-8-8-8"; break; 1174ba300204SHans Verkuil case V4L2_PIX_FMT_ABGR32: descr = "32-bit BGRA 8-8-8-8"; break; 1175ba300204SHans Verkuil case V4L2_PIX_FMT_XBGR32: descr = "32-bit BGRX 8-8-8-8"; break; 1176ba300204SHans Verkuil case V4L2_PIX_FMT_RGB32: descr = "32-bit A/XRGB 8-8-8-8"; break; 1177ba300204SHans Verkuil case V4L2_PIX_FMT_ARGB32: descr = "32-bit ARGB 8-8-8-8"; break; 1178ba300204SHans Verkuil case V4L2_PIX_FMT_XRGB32: descr = "32-bit XRGB 8-8-8-8"; break; 1179ba300204SHans Verkuil case V4L2_PIX_FMT_GREY: descr = "8-bit Greyscale"; break; 1180ba300204SHans Verkuil case V4L2_PIX_FMT_Y4: descr = "4-bit Greyscale"; break; 1181ba300204SHans Verkuil case V4L2_PIX_FMT_Y6: descr = "6-bit Greyscale"; break; 1182ba300204SHans Verkuil case V4L2_PIX_FMT_Y10: descr = "10-bit Greyscale"; break; 1183ba300204SHans Verkuil case V4L2_PIX_FMT_Y12: descr = "12-bit Greyscale"; break; 1184ba300204SHans Verkuil case V4L2_PIX_FMT_Y16: descr = "16-bit Greyscale"; break; 11852e5e435fSRicardo Ribalda case V4L2_PIX_FMT_Y16_BE: descr = "16-bit Greyscale BE"; break; 1186ba300204SHans Verkuil case V4L2_PIX_FMT_Y10BPACK: descr = "10-bit Greyscale (Packed)"; break; 11876e15bec4STodor Tomov case V4L2_PIX_FMT_Y10P: descr = "10-bit Greyscale (MIPI Packed)"; break; 11885b382290SLaurent Pinchart case V4L2_PIX_FMT_Y8I: descr = "Interleaved 8-bit Greyscale"; break; 11895b382290SLaurent Pinchart case V4L2_PIX_FMT_Y12I: descr = "Interleaved 12-bit Greyscale"; break; 11905b382290SLaurent Pinchart case V4L2_PIX_FMT_Z16: descr = "16-bit Depth"; break; 11915df082e2SEvgeni Raikhel case V4L2_PIX_FMT_INZI: descr = "Planar 10:16 Greyscale Depth"; break; 119292799ef7SSergey Dorodnicov case V4L2_PIX_FMT_CNF4: descr = "4-bit Depth Confidence (Packed)"; break; 1193ba300204SHans Verkuil case V4L2_PIX_FMT_PAL8: descr = "8-bit Palette"; break; 1194ba300204SHans Verkuil case V4L2_PIX_FMT_UV8: descr = "8-bit Chrominance UV 4-4"; break; 1195ba300204SHans Verkuil case V4L2_PIX_FMT_YVU410: descr = "Planar YVU 4:1:0"; break; 1196ba300204SHans Verkuil case V4L2_PIX_FMT_YVU420: descr = "Planar YVU 4:2:0"; break; 1197ba300204SHans Verkuil case V4L2_PIX_FMT_YUYV: descr = "YUYV 4:2:2"; break; 1198ba300204SHans Verkuil case V4L2_PIX_FMT_YYUV: descr = "YYUV 4:2:2"; break; 1199ba300204SHans Verkuil case V4L2_PIX_FMT_YVYU: descr = "YVYU 4:2:2"; break; 1200ba300204SHans Verkuil case V4L2_PIX_FMT_UYVY: descr = "UYVY 4:2:2"; break; 1201ba300204SHans Verkuil case V4L2_PIX_FMT_VYUY: descr = "VYUY 4:2:2"; break; 1202fcbafafbSPhilipp Zabel case V4L2_PIX_FMT_YUV422P: descr = "Planar YUV 4:2:2"; break; 1203ba300204SHans Verkuil case V4L2_PIX_FMT_YUV411P: descr = "Planar YUV 4:1:1"; break; 1204ba300204SHans Verkuil case V4L2_PIX_FMT_Y41P: descr = "YUV 4:1:1 (Packed)"; break; 1205ba300204SHans Verkuil case V4L2_PIX_FMT_YUV444: descr = "16-bit A/XYUV 4-4-4-4"; break; 1206ba300204SHans Verkuil case V4L2_PIX_FMT_YUV555: descr = "16-bit A/XYUV 1-5-5-5"; break; 1207ba300204SHans Verkuil case V4L2_PIX_FMT_YUV565: descr = "16-bit YUV 5-6-5"; break; 1208ba300204SHans Verkuil case V4L2_PIX_FMT_YUV32: descr = "32-bit A/XYUV 8-8-8-8"; break; 1209ba300204SHans Verkuil case V4L2_PIX_FMT_YUV410: descr = "Planar YUV 4:1:0"; break; 1210ba300204SHans Verkuil case V4L2_PIX_FMT_YUV420: descr = "Planar YUV 4:2:0"; break; 1211ba300204SHans Verkuil case V4L2_PIX_FMT_HI240: descr = "8-bit Dithered RGB (BTTV)"; break; 1212ba300204SHans Verkuil case V4L2_PIX_FMT_HM12: descr = "YUV 4:2:0 (16x16 Macroblocks)"; break; 1213ba300204SHans Verkuil case V4L2_PIX_FMT_M420: descr = "YUV 4:2:0 (M420)"; break; 1214ba300204SHans Verkuil case V4L2_PIX_FMT_NV12: descr = "Y/CbCr 4:2:0"; break; 1215ba300204SHans Verkuil case V4L2_PIX_FMT_NV21: descr = "Y/CrCb 4:2:0"; break; 1216ba300204SHans Verkuil case V4L2_PIX_FMT_NV16: descr = "Y/CbCr 4:2:2"; break; 1217ba300204SHans Verkuil case V4L2_PIX_FMT_NV61: descr = "Y/CrCb 4:2:2"; break; 1218ba300204SHans Verkuil case V4L2_PIX_FMT_NV24: descr = "Y/CbCr 4:4:4"; break; 1219ba300204SHans Verkuil case V4L2_PIX_FMT_NV42: descr = "Y/CrCb 4:4:4"; break; 1220ba300204SHans Verkuil case V4L2_PIX_FMT_NV12M: descr = "Y/CbCr 4:2:0 (N-C)"; break; 1221ba300204SHans Verkuil case V4L2_PIX_FMT_NV21M: descr = "Y/CrCb 4:2:0 (N-C)"; break; 1222ba300204SHans Verkuil case V4L2_PIX_FMT_NV16M: descr = "Y/CbCr 4:2:2 (N-C)"; break; 1223ba300204SHans Verkuil case V4L2_PIX_FMT_NV61M: descr = "Y/CrCb 4:2:2 (N-C)"; break; 1224ba300204SHans Verkuil case V4L2_PIX_FMT_NV12MT: descr = "Y/CbCr 4:2:0 (64x32 MB, N-C)"; break; 1225ba300204SHans Verkuil case V4L2_PIX_FMT_NV12MT_16X16: descr = "Y/CbCr 4:2:0 (16x16 MB, N-C)"; break; 1226ba300204SHans Verkuil case V4L2_PIX_FMT_YUV420M: descr = "Planar YUV 4:2:0 (N-C)"; break; 1227ba300204SHans Verkuil case V4L2_PIX_FMT_YVU420M: descr = "Planar YVU 4:2:0 (N-C)"; break; 1228d65fae92SLaurent Pinchart case V4L2_PIX_FMT_YUV422M: descr = "Planar YUV 4:2:2 (N-C)"; break; 1229d65fae92SLaurent Pinchart case V4L2_PIX_FMT_YVU422M: descr = "Planar YVU 4:2:2 (N-C)"; break; 1230d65fae92SLaurent Pinchart case V4L2_PIX_FMT_YUV444M: descr = "Planar YUV 4:4:4 (N-C)"; break; 1231d65fae92SLaurent Pinchart case V4L2_PIX_FMT_YVU444M: descr = "Planar YVU 4:4:4 (N-C)"; break; 1232ba300204SHans Verkuil case V4L2_PIX_FMT_SBGGR8: descr = "8-bit Bayer BGBG/GRGR"; break; 1233ba300204SHans Verkuil case V4L2_PIX_FMT_SGBRG8: descr = "8-bit Bayer GBGB/RGRG"; break; 1234ba300204SHans Verkuil case V4L2_PIX_FMT_SGRBG8: descr = "8-bit Bayer GRGR/BGBG"; break; 1235ba300204SHans Verkuil case V4L2_PIX_FMT_SRGGB8: descr = "8-bit Bayer RGRG/GBGB"; break; 1236ba300204SHans Verkuil case V4L2_PIX_FMT_SBGGR10: descr = "10-bit Bayer BGBG/GRGR"; break; 1237ba300204SHans Verkuil case V4L2_PIX_FMT_SGBRG10: descr = "10-bit Bayer GBGB/RGRG"; break; 1238ba300204SHans Verkuil case V4L2_PIX_FMT_SGRBG10: descr = "10-bit Bayer GRGR/BGBG"; break; 1239ba300204SHans Verkuil case V4L2_PIX_FMT_SRGGB10: descr = "10-bit Bayer RGRG/GBGB"; break; 1240ba300204SHans Verkuil case V4L2_PIX_FMT_SBGGR10P: descr = "10-bit Bayer BGBG/GRGR Packed"; break; 1241ba300204SHans Verkuil case V4L2_PIX_FMT_SGBRG10P: descr = "10-bit Bayer GBGB/RGRG Packed"; break; 1242ba300204SHans Verkuil case V4L2_PIX_FMT_SGRBG10P: descr = "10-bit Bayer GRGR/BGBG Packed"; break; 1243ba300204SHans Verkuil case V4L2_PIX_FMT_SRGGB10P: descr = "10-bit Bayer RGRG/GBGB Packed"; break; 1244e8391b76SYong Zhi case V4L2_PIX_FMT_IPU3_SBGGR10: descr = "10-bit bayer BGGR IPU3 Packed"; break; 1245e8391b76SYong Zhi case V4L2_PIX_FMT_IPU3_SGBRG10: descr = "10-bit bayer GBRG IPU3 Packed"; break; 1246e8391b76SYong Zhi case V4L2_PIX_FMT_IPU3_SGRBG10: descr = "10-bit bayer GRBG IPU3 Packed"; break; 1247e8391b76SYong Zhi case V4L2_PIX_FMT_IPU3_SRGGB10: descr = "10-bit bayer RGGB IPU3 Packed"; break; 1248ba300204SHans Verkuil case V4L2_PIX_FMT_SBGGR10ALAW8: descr = "8-bit Bayer BGBG/GRGR (A-law)"; break; 1249ba300204SHans Verkuil case V4L2_PIX_FMT_SGBRG10ALAW8: descr = "8-bit Bayer GBGB/RGRG (A-law)"; break; 1250ba300204SHans Verkuil case V4L2_PIX_FMT_SGRBG10ALAW8: descr = "8-bit Bayer GRGR/BGBG (A-law)"; break; 1251ba300204SHans Verkuil case V4L2_PIX_FMT_SRGGB10ALAW8: descr = "8-bit Bayer RGRG/GBGB (A-law)"; break; 1252ba300204SHans Verkuil case V4L2_PIX_FMT_SBGGR10DPCM8: descr = "8-bit Bayer BGBG/GRGR (DPCM)"; break; 1253ba300204SHans Verkuil case V4L2_PIX_FMT_SGBRG10DPCM8: descr = "8-bit Bayer GBGB/RGRG (DPCM)"; break; 1254ba300204SHans Verkuil case V4L2_PIX_FMT_SGRBG10DPCM8: descr = "8-bit Bayer GRGR/BGBG (DPCM)"; break; 1255ba300204SHans Verkuil case V4L2_PIX_FMT_SRGGB10DPCM8: descr = "8-bit Bayer RGRG/GBGB (DPCM)"; break; 1256d1b3437eSSakari Ailus case V4L2_PIX_FMT_SBGGR12: descr = "12-bit Bayer BGBG/GRGR"; break; 1257d1b3437eSSakari Ailus case V4L2_PIX_FMT_SGBRG12: descr = "12-bit Bayer GBGB/RGRG"; break; 1258d1b3437eSSakari Ailus case V4L2_PIX_FMT_SGRBG12: descr = "12-bit Bayer GRGR/BGBG"; break; 1259d1b3437eSSakari Ailus case V4L2_PIX_FMT_SRGGB12: descr = "12-bit Bayer RGRG/GBGB"; break; 1260d1b3437eSSakari Ailus case V4L2_PIX_FMT_SBGGR12P: descr = "12-bit Bayer BGBG/GRGR Packed"; break; 1261d1b3437eSSakari Ailus case V4L2_PIX_FMT_SGBRG12P: descr = "12-bit Bayer GBGB/RGRG Packed"; break; 1262d1b3437eSSakari Ailus case V4L2_PIX_FMT_SGRBG12P: descr = "12-bit Bayer GRGR/BGBG Packed"; break; 1263d1b3437eSSakari Ailus case V4L2_PIX_FMT_SRGGB12P: descr = "12-bit Bayer RGRG/GBGB Packed"; break; 126483b15832SSakari Ailus case V4L2_PIX_FMT_SBGGR14P: descr = "14-bit Bayer BGBG/GRGR Packed"; break; 126583b15832SSakari Ailus case V4L2_PIX_FMT_SGBRG14P: descr = "14-bit Bayer GBGB/RGRG Packed"; break; 126683b15832SSakari Ailus case V4L2_PIX_FMT_SGRBG14P: descr = "14-bit Bayer GRGR/BGBG Packed"; break; 126783b15832SSakari Ailus case V4L2_PIX_FMT_SRGGB14P: descr = "14-bit Bayer RGRG/GBGB Packed"; break; 1268b9a4b13cSSakari Ailus case V4L2_PIX_FMT_SBGGR16: descr = "16-bit Bayer BGBG/GRGR"; break; 1269b9a4b13cSSakari Ailus case V4L2_PIX_FMT_SGBRG16: descr = "16-bit Bayer GBGB/RGRG"; break; 1270b9a4b13cSSakari Ailus case V4L2_PIX_FMT_SGRBG16: descr = "16-bit Bayer GRGR/BGBG"; break; 1271b9a4b13cSSakari Ailus case V4L2_PIX_FMT_SRGGB16: descr = "16-bit Bayer RGRG/GBGB"; break; 127299b74277SMauro Carvalho Chehab case V4L2_PIX_FMT_SN9C20X_I420: descr = "GSPCA SN9C20X I420"; break; 1273ba300204SHans Verkuil case V4L2_PIX_FMT_SPCA501: descr = "GSPCA SPCA501"; break; 1274ba300204SHans Verkuil case V4L2_PIX_FMT_SPCA505: descr = "GSPCA SPCA505"; break; 1275ba300204SHans Verkuil case V4L2_PIX_FMT_SPCA508: descr = "GSPCA SPCA508"; break; 1276ba300204SHans Verkuil case V4L2_PIX_FMT_STV0680: descr = "GSPCA STV0680"; break; 1277ba300204SHans Verkuil case V4L2_PIX_FMT_TM6000: descr = "A/V + VBI Mux Packet"; break; 1278ba300204SHans Verkuil case V4L2_PIX_FMT_CIT_YYVYUY: descr = "GSPCA CIT YYVYUY"; break; 1279ba300204SHans Verkuil case V4L2_PIX_FMT_KONICA420: descr = "GSPCA KONICA420"; break; 128066b2ab27SRicardo Ribalda Delgado case V4L2_PIX_FMT_HSV24: descr = "24-bit HSV 8-8-8"; break; 128166b2ab27SRicardo Ribalda Delgado case V4L2_PIX_FMT_HSV32: descr = "32-bit XHSV 8-8-8-8"; break; 128248fc10aaSAntti Palosaari case V4L2_SDR_FMT_CU8: descr = "Complex U8"; break; 128348fc10aaSAntti Palosaari case V4L2_SDR_FMT_CU16LE: descr = "Complex U16LE"; break; 1284ba300204SHans Verkuil case V4L2_SDR_FMT_CS8: descr = "Complex S8"; break; 1285ba300204SHans Verkuil case V4L2_SDR_FMT_CS14LE: descr = "Complex S14LE"; break; 1286ba300204SHans Verkuil case V4L2_SDR_FMT_RU12LE: descr = "Real U12LE"; break; 1287c28f2118SRamesh Shanmugasundaram case V4L2_SDR_FMT_PCU16BE: descr = "Planar Complex U16BE"; break; 1288c28f2118SRamesh Shanmugasundaram case V4L2_SDR_FMT_PCU18BE: descr = "Planar Complex U18BE"; break; 1289c28f2118SRamesh Shanmugasundaram case V4L2_SDR_FMT_PCU20BE: descr = "Planar Complex U20BE"; break; 1290b2fe22d0SNick Dyer case V4L2_TCH_FMT_DELTA_TD16: descr = "16-bit signed deltas"; break; 1291b2fe22d0SNick Dyer case V4L2_TCH_FMT_DELTA_TD08: descr = "8-bit signed deltas"; break; 1292b2fe22d0SNick Dyer case V4L2_TCH_FMT_TU16: descr = "16-bit unsigned touch data"; break; 1293b2fe22d0SNick Dyer case V4L2_TCH_FMT_TU08: descr = "8-bit unsigned touch data"; break; 129414d66538SLaurent Pinchart case V4L2_META_FMT_VSP1_HGO: descr = "R-Car VSP1 1-D Histogram"; break; 12955deb1c04SNiklas Söderlund case V4L2_META_FMT_VSP1_HGT: descr = "R-Car VSP1 2-D Histogram"; break; 1296563a01e1SGuennadi Liakhovetski case V4L2_META_FMT_UVC: descr = "UVC payload header metadata"; break; 1297ba300204SHans Verkuil 1298ba300204SHans Verkuil default: 1299ba300204SHans Verkuil /* Compressed formats */ 1300ba300204SHans Verkuil flags = V4L2_FMT_FLAG_COMPRESSED; 1301ba300204SHans Verkuil switch (fmt->pixelformat) { 1302ba300204SHans Verkuil /* Max description length mask: descr = "0123456789012345678901234567890" */ 1303ba300204SHans Verkuil case V4L2_PIX_FMT_MJPEG: descr = "Motion-JPEG"; break; 1304ba300204SHans Verkuil case V4L2_PIX_FMT_JPEG: descr = "JFIF JPEG"; break; 1305ba300204SHans Verkuil case V4L2_PIX_FMT_DV: descr = "1394"; break; 1306ba300204SHans Verkuil case V4L2_PIX_FMT_MPEG: descr = "MPEG-1/2/4"; break; 1307ba300204SHans Verkuil case V4L2_PIX_FMT_H264: descr = "H.264"; break; 1308ba300204SHans Verkuil case V4L2_PIX_FMT_H264_NO_SC: descr = "H.264 (No Start Codes)"; break; 1309ba300204SHans Verkuil case V4L2_PIX_FMT_H264_MVC: descr = "H.264 MVC"; break; 1310ba300204SHans Verkuil case V4L2_PIX_FMT_H263: descr = "H.263"; break; 1311ba300204SHans Verkuil case V4L2_PIX_FMT_MPEG1: descr = "MPEG-1 ES"; break; 1312ba300204SHans Verkuil case V4L2_PIX_FMT_MPEG2: descr = "MPEG-2 ES"; break; 1313c27bb30eSPaul Kocialkowski case V4L2_PIX_FMT_MPEG2_SLICE: descr = "MPEG-2 Parsed Slice Data"; break; 1314ba300204SHans Verkuil case V4L2_PIX_FMT_MPEG4: descr = "MPEG-4 part 2 ES"; break; 1315ba300204SHans Verkuil case V4L2_PIX_FMT_XVID: descr = "Xvid"; break; 1316ba300204SHans Verkuil case V4L2_PIX_FMT_VC1_ANNEX_G: descr = "VC-1 (SMPTE 412M Annex G)"; break; 1317ba300204SHans Verkuil case V4L2_PIX_FMT_VC1_ANNEX_L: descr = "VC-1 (SMPTE 412M Annex L)"; break; 1318ba300204SHans Verkuil case V4L2_PIX_FMT_VP8: descr = "VP8"; break; 1319fa14a564SWu-Cheng Li case V4L2_PIX_FMT_VP9: descr = "VP9"; break; 13201c791727SSmitha T Murthy case V4L2_PIX_FMT_HEVC: descr = "HEVC"; break; /* aka H.265 */ 132162c3fce0SHans Verkuil case V4L2_PIX_FMT_FWHT: descr = "FWHT"; break; /* used in vicodec */ 1322ba300204SHans Verkuil case V4L2_PIX_FMT_CPIA1: descr = "GSPCA CPiA YUV"; break; 1323ba300204SHans Verkuil case V4L2_PIX_FMT_WNVA: descr = "WNVA"; break; 1324ba300204SHans Verkuil case V4L2_PIX_FMT_SN9C10X: descr = "GSPCA SN9C10X"; break; 1325ba300204SHans Verkuil case V4L2_PIX_FMT_PWC1: descr = "Raw Philips Webcam Type (Old)"; break; 1326ba300204SHans Verkuil case V4L2_PIX_FMT_PWC2: descr = "Raw Philips Webcam Type (New)"; break; 1327ba300204SHans Verkuil case V4L2_PIX_FMT_ET61X251: descr = "GSPCA ET61X251"; break; 1328ba300204SHans Verkuil case V4L2_PIX_FMT_SPCA561: descr = "GSPCA SPCA561"; break; 1329ba300204SHans Verkuil case V4L2_PIX_FMT_PAC207: descr = "GSPCA PAC207"; break; 1330ba300204SHans Verkuil case V4L2_PIX_FMT_MR97310A: descr = "GSPCA MR97310A"; break; 1331ba300204SHans Verkuil case V4L2_PIX_FMT_JL2005BCD: descr = "GSPCA JL2005BCD"; break; 1332ba300204SHans Verkuil case V4L2_PIX_FMT_SN9C2028: descr = "GSPCA SN9C2028"; break; 1333ba300204SHans Verkuil case V4L2_PIX_FMT_SQ905C: descr = "GSPCA SQ905C"; break; 1334ba300204SHans Verkuil case V4L2_PIX_FMT_PJPG: descr = "GSPCA PJPG"; break; 1335ba300204SHans Verkuil case V4L2_PIX_FMT_OV511: descr = "GSPCA OV511"; break; 1336ba300204SHans Verkuil case V4L2_PIX_FMT_OV518: descr = "GSPCA OV518"; break; 1337ba300204SHans Verkuil case V4L2_PIX_FMT_JPGL: descr = "JPEG Lite"; break; 1338ba300204SHans Verkuil case V4L2_PIX_FMT_SE401: descr = "GSPCA SE401"; break; 1339ba300204SHans Verkuil case V4L2_PIX_FMT_S5C_UYVY_JPG: descr = "S5C73MX interleaved UYVY/JPEG"; break; 1340d4de6634STiffany Lin case V4L2_PIX_FMT_MT21C: descr = "Mediatek Compressed Format"; break; 134136cf35b7SPaul Kocialkowski case V4L2_PIX_FMT_SUNXI_TILED_NV12: descr = "Sunxi Tiled NV12 Format"; break; 1342ba300204SHans Verkuil default: 1343ba300204SHans Verkuil if (fmt->description[0]) 1344ba300204SHans Verkuil return; 1345c2286cc0SSakari Ailus WARN(1, "Unknown pixelformat 0x%08x\n", fmt->pixelformat); 1346ba300204SHans Verkuil flags = 0; 1347ba300204SHans Verkuil snprintf(fmt->description, sz, "%c%c%c%c%s", 1348ba300204SHans Verkuil (char)(fmt->pixelformat & 0x7f), 1349ba300204SHans Verkuil (char)((fmt->pixelformat >> 8) & 0x7f), 1350ba300204SHans Verkuil (char)((fmt->pixelformat >> 16) & 0x7f), 1351ba300204SHans Verkuil (char)((fmt->pixelformat >> 24) & 0x7f), 1352ba300204SHans Verkuil (fmt->pixelformat & (1 << 31)) ? "-BE" : ""); 1353ba300204SHans Verkuil break; 1354ba300204SHans Verkuil } 1355ba300204SHans Verkuil } 1356ba300204SHans Verkuil 1357ba300204SHans Verkuil if (descr) 1358c0decac1SMauro Carvalho Chehab WARN_ON(strscpy(fmt->description, descr, sz) >= sz); 1359ba300204SHans Verkuil fmt->flags = flags; 1360ba300204SHans Verkuil } 1361ba300204SHans Verkuil 13625bc3cb74SMauro Carvalho Chehab static int v4l_enum_fmt(const struct v4l2_ioctl_ops *ops, 13635bc3cb74SMauro Carvalho Chehab struct file *file, void *fh, void *arg) 13645bc3cb74SMauro Carvalho Chehab { 13655bc3cb74SMauro Carvalho Chehab struct v4l2_fmtdesc *p = arg; 1366b2469c81SHans Verkuil int ret = check_fmt(file, p->type); 1367b2469c81SHans Verkuil 1368b2469c81SHans Verkuil if (ret) 1369b2469c81SHans Verkuil return ret; 1370b2469c81SHans Verkuil ret = -EINVAL; 13715bc3cb74SMauro Carvalho Chehab 13725bc3cb74SMauro Carvalho Chehab switch (p->type) { 13735bc3cb74SMauro Carvalho Chehab case V4L2_BUF_TYPE_VIDEO_CAPTURE: 1374b2469c81SHans Verkuil if (unlikely(!ops->vidioc_enum_fmt_vid_cap)) 13755bc3cb74SMauro Carvalho Chehab break; 1376ba300204SHans Verkuil ret = ops->vidioc_enum_fmt_vid_cap(file, fh, arg); 1377ba300204SHans Verkuil break; 13785bc3cb74SMauro Carvalho Chehab case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE: 1379b2469c81SHans Verkuil if (unlikely(!ops->vidioc_enum_fmt_vid_cap_mplane)) 13805bc3cb74SMauro Carvalho Chehab break; 1381ba300204SHans Verkuil ret = ops->vidioc_enum_fmt_vid_cap_mplane(file, fh, arg); 1382ba300204SHans Verkuil break; 13835bc3cb74SMauro Carvalho Chehab case V4L2_BUF_TYPE_VIDEO_OVERLAY: 1384b2469c81SHans Verkuil if (unlikely(!ops->vidioc_enum_fmt_vid_overlay)) 13855bc3cb74SMauro Carvalho Chehab break; 1386ba300204SHans Verkuil ret = ops->vidioc_enum_fmt_vid_overlay(file, fh, arg); 1387ba300204SHans Verkuil break; 13885bc3cb74SMauro Carvalho Chehab case V4L2_BUF_TYPE_VIDEO_OUTPUT: 1389b2469c81SHans Verkuil if (unlikely(!ops->vidioc_enum_fmt_vid_out)) 13905bc3cb74SMauro Carvalho Chehab break; 1391ba300204SHans Verkuil ret = ops->vidioc_enum_fmt_vid_out(file, fh, arg); 1392ba300204SHans Verkuil break; 13935bc3cb74SMauro Carvalho Chehab case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE: 1394b2469c81SHans Verkuil if (unlikely(!ops->vidioc_enum_fmt_vid_out_mplane)) 13955bc3cb74SMauro Carvalho Chehab break; 1396ba300204SHans Verkuil ret = ops->vidioc_enum_fmt_vid_out_mplane(file, fh, arg); 1397ba300204SHans Verkuil break; 1398582c52cbSAntti Palosaari case V4L2_BUF_TYPE_SDR_CAPTURE: 1399b2469c81SHans Verkuil if (unlikely(!ops->vidioc_enum_fmt_sdr_cap)) 1400582c52cbSAntti Palosaari break; 1401ba300204SHans Verkuil ret = ops->vidioc_enum_fmt_sdr_cap(file, fh, arg); 1402ba300204SHans Verkuil break; 14039effc72fSAntti Palosaari case V4L2_BUF_TYPE_SDR_OUTPUT: 1404b2469c81SHans Verkuil if (unlikely(!ops->vidioc_enum_fmt_sdr_out)) 14059effc72fSAntti Palosaari break; 14069effc72fSAntti Palosaari ret = ops->vidioc_enum_fmt_sdr_out(file, fh, arg); 14079effc72fSAntti Palosaari break; 1408fb9ffa6aSLaurent Pinchart case V4L2_BUF_TYPE_META_CAPTURE: 1409b2469c81SHans Verkuil if (unlikely(!ops->vidioc_enum_fmt_meta_cap)) 1410fb9ffa6aSLaurent Pinchart break; 1411fb9ffa6aSLaurent Pinchart ret = ops->vidioc_enum_fmt_meta_cap(file, fh, arg); 1412fb9ffa6aSLaurent Pinchart break; 14135bc3cb74SMauro Carvalho Chehab } 1414ba300204SHans Verkuil if (ret == 0) 1415ba300204SHans Verkuil v4l_fill_fmtdesc(p); 1416ba300204SHans Verkuil return ret; 14175bc3cb74SMauro Carvalho Chehab } 14185bc3cb74SMauro Carvalho Chehab 14195bc3cb74SMauro Carvalho Chehab static int v4l_g_fmt(const struct v4l2_ioctl_ops *ops, 14205bc3cb74SMauro Carvalho Chehab struct file *file, void *fh, void *arg) 14215bc3cb74SMauro Carvalho Chehab { 14225bc3cb74SMauro Carvalho Chehab struct v4l2_format *p = arg; 1423b2469c81SHans Verkuil int ret = check_fmt(file, p->type); 1424b2469c81SHans Verkuil 1425b2469c81SHans Verkuil if (ret) 1426b2469c81SHans Verkuil return ret; 1427d52e2381SLaurent Pinchart 1428e5ce558aSHans Verkuil /* 1429e5ce558aSHans Verkuil * fmt can't be cleared for these overlay types due to the 'clips' 1430e5ce558aSHans Verkuil * 'clipcount' and 'bitmap' pointers in struct v4l2_window. 1431e5ce558aSHans Verkuil * Those are provided by the user. So handle these two overlay types 1432e5ce558aSHans Verkuil * first, and then just do a simple memset for the other types. 1433e5ce558aSHans Verkuil */ 1434e5ce558aSHans Verkuil switch (p->type) { 1435e5ce558aSHans Verkuil case V4L2_BUF_TYPE_VIDEO_OVERLAY: 1436e5ce558aSHans Verkuil case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY: { 14374d1afa51SHans Verkuil struct v4l2_clip __user *clips = p->fmt.win.clips; 1438e5ce558aSHans Verkuil u32 clipcount = p->fmt.win.clipcount; 14394d1afa51SHans Verkuil void __user *bitmap = p->fmt.win.bitmap; 1440e5ce558aSHans Verkuil 1441e5ce558aSHans Verkuil memset(&p->fmt, 0, sizeof(p->fmt)); 1442e5ce558aSHans Verkuil p->fmt.win.clips = clips; 1443e5ce558aSHans Verkuil p->fmt.win.clipcount = clipcount; 1444e5ce558aSHans Verkuil p->fmt.win.bitmap = bitmap; 1445e5ce558aSHans Verkuil break; 1446e5ce558aSHans Verkuil } 1447e5ce558aSHans Verkuil default: 1448e5ce558aSHans Verkuil memset(&p->fmt, 0, sizeof(p->fmt)); 1449e5ce558aSHans Verkuil break; 1450e5ce558aSHans Verkuil } 1451e5ce558aSHans Verkuil 14525bc3cb74SMauro Carvalho Chehab switch (p->type) { 14535bc3cb74SMauro Carvalho Chehab case V4L2_BUF_TYPE_VIDEO_CAPTURE: 1454b2469c81SHans Verkuil if (unlikely(!ops->vidioc_g_fmt_vid_cap)) 14555bc3cb74SMauro Carvalho Chehab break; 145648f2650aSHans Verkuil p->fmt.pix.priv = V4L2_PIX_FMT_PRIV_MAGIC; 1457d52e2381SLaurent Pinchart ret = ops->vidioc_g_fmt_vid_cap(file, fh, arg); 145848f2650aSHans Verkuil /* just in case the driver zeroed it again */ 1459d52e2381SLaurent Pinchart p->fmt.pix.priv = V4L2_PIX_FMT_PRIV_MAGIC; 1460d52e2381SLaurent Pinchart return ret; 14615bc3cb74SMauro Carvalho Chehab case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE: 14625bc3cb74SMauro Carvalho Chehab return ops->vidioc_g_fmt_vid_cap_mplane(file, fh, arg); 14635bc3cb74SMauro Carvalho Chehab case V4L2_BUF_TYPE_VIDEO_OVERLAY: 14645bc3cb74SMauro Carvalho Chehab return ops->vidioc_g_fmt_vid_overlay(file, fh, arg); 14654b20259fSHans Verkuil case V4L2_BUF_TYPE_VBI_CAPTURE: 14664b20259fSHans Verkuil return ops->vidioc_g_fmt_vbi_cap(file, fh, arg); 14674b20259fSHans Verkuil case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE: 14684b20259fSHans Verkuil return ops->vidioc_g_fmt_sliced_vbi_cap(file, fh, arg); 14695bc3cb74SMauro Carvalho Chehab case V4L2_BUF_TYPE_VIDEO_OUTPUT: 1470b2469c81SHans Verkuil if (unlikely(!ops->vidioc_g_fmt_vid_out)) 14715bc3cb74SMauro Carvalho Chehab break; 147248f2650aSHans Verkuil p->fmt.pix.priv = V4L2_PIX_FMT_PRIV_MAGIC; 1473d52e2381SLaurent Pinchart ret = ops->vidioc_g_fmt_vid_out(file, fh, arg); 147448f2650aSHans Verkuil /* just in case the driver zeroed it again */ 1475d52e2381SLaurent Pinchart p->fmt.pix.priv = V4L2_PIX_FMT_PRIV_MAGIC; 1476d52e2381SLaurent Pinchart return ret; 14775bc3cb74SMauro Carvalho Chehab case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE: 14785bc3cb74SMauro Carvalho Chehab return ops->vidioc_g_fmt_vid_out_mplane(file, fh, arg); 14795bc3cb74SMauro Carvalho Chehab case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY: 14805bc3cb74SMauro Carvalho Chehab return ops->vidioc_g_fmt_vid_out_overlay(file, fh, arg); 14815bc3cb74SMauro Carvalho Chehab case V4L2_BUF_TYPE_VBI_OUTPUT: 14825bc3cb74SMauro Carvalho Chehab return ops->vidioc_g_fmt_vbi_out(file, fh, arg); 14835bc3cb74SMauro Carvalho Chehab case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT: 14845bc3cb74SMauro Carvalho Chehab return ops->vidioc_g_fmt_sliced_vbi_out(file, fh, arg); 1485582c52cbSAntti Palosaari case V4L2_BUF_TYPE_SDR_CAPTURE: 1486582c52cbSAntti Palosaari return ops->vidioc_g_fmt_sdr_cap(file, fh, arg); 14879effc72fSAntti Palosaari case V4L2_BUF_TYPE_SDR_OUTPUT: 14889effc72fSAntti Palosaari return ops->vidioc_g_fmt_sdr_out(file, fh, arg); 1489fb9ffa6aSLaurent Pinchart case V4L2_BUF_TYPE_META_CAPTURE: 1490fb9ffa6aSLaurent Pinchart return ops->vidioc_g_fmt_meta_cap(file, fh, arg); 14915bc3cb74SMauro Carvalho Chehab } 14925bc3cb74SMauro Carvalho Chehab return -EINVAL; 14935bc3cb74SMauro Carvalho Chehab } 14945bc3cb74SMauro Carvalho Chehab 1495b2fe22d0SNick Dyer static void v4l_pix_format_touch(struct v4l2_pix_format *p) 1496b2fe22d0SNick Dyer { 1497b2fe22d0SNick Dyer /* 1498b2fe22d0SNick Dyer * The v4l2_pix_format structure contains fields that make no sense for 1499b2fe22d0SNick Dyer * touch. Set them to default values in this case. 1500b2fe22d0SNick Dyer */ 1501b2fe22d0SNick Dyer 1502b2fe22d0SNick Dyer p->field = V4L2_FIELD_NONE; 1503b2fe22d0SNick Dyer p->colorspace = V4L2_COLORSPACE_RAW; 1504b2fe22d0SNick Dyer p->flags = 0; 1505b2fe22d0SNick Dyer p->ycbcr_enc = 0; 1506b2fe22d0SNick Dyer p->quantization = 0; 1507b2fe22d0SNick Dyer p->xfer_func = 0; 1508b2fe22d0SNick Dyer } 1509b2fe22d0SNick Dyer 15105bc3cb74SMauro Carvalho Chehab static int v4l_s_fmt(const struct v4l2_ioctl_ops *ops, 15115bc3cb74SMauro Carvalho Chehab struct file *file, void *fh, void *arg) 15125bc3cb74SMauro Carvalho Chehab { 15135bc3cb74SMauro Carvalho Chehab struct v4l2_format *p = arg; 15144b20259fSHans Verkuil struct video_device *vfd = video_devdata(file); 1515b2469c81SHans Verkuil int ret = check_fmt(file, p->type); 15164e1e0eb0SEzequiel Garcia unsigned int i; 1517b2469c81SHans Verkuil 1518b2469c81SHans Verkuil if (ret) 1519b2469c81SHans Verkuil return ret; 15205bc3cb74SMauro Carvalho Chehab 152177fa4e07SShuah Khan ret = v4l_enable_media_source(vfd); 152277fa4e07SShuah Khan if (ret) 152377fa4e07SShuah Khan return ret; 1524d52e2381SLaurent Pinchart v4l_sanitize_format(p); 1525d52e2381SLaurent Pinchart 15265bc3cb74SMauro Carvalho Chehab switch (p->type) { 15275bc3cb74SMauro Carvalho Chehab case V4L2_BUF_TYPE_VIDEO_CAPTURE: 1528b2469c81SHans Verkuil if (unlikely(!ops->vidioc_s_fmt_vid_cap)) 15295bc3cb74SMauro Carvalho Chehab break; 15305bc3cb74SMauro Carvalho Chehab CLEAR_AFTER_FIELD(p, fmt.pix); 153148f2650aSHans Verkuil ret = ops->vidioc_s_fmt_vid_cap(file, fh, arg); 153248f2650aSHans Verkuil /* just in case the driver zeroed it again */ 153348f2650aSHans Verkuil p->fmt.pix.priv = V4L2_PIX_FMT_PRIV_MAGIC; 1534b2469c81SHans Verkuil if (vfd->vfl_type == VFL_TYPE_TOUCH) 1535b2fe22d0SNick Dyer v4l_pix_format_touch(&p->fmt.pix); 153648f2650aSHans Verkuil return ret; 15375bc3cb74SMauro Carvalho Chehab case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE: 1538b2469c81SHans Verkuil if (unlikely(!ops->vidioc_s_fmt_vid_cap_mplane)) 15395bc3cb74SMauro Carvalho Chehab break; 1540c49148e8SLaurent Pinchart CLEAR_AFTER_FIELD(p, fmt.pix_mp.xfer_func); 15414e1e0eb0SEzequiel Garcia for (i = 0; i < p->fmt.pix_mp.num_planes; i++) 15424e1e0eb0SEzequiel Garcia CLEAR_AFTER_FIELD(p, fmt.pix_mp.plane_fmt[i].bytesperline); 15435bc3cb74SMauro Carvalho Chehab return ops->vidioc_s_fmt_vid_cap_mplane(file, fh, arg); 15445bc3cb74SMauro Carvalho Chehab case V4L2_BUF_TYPE_VIDEO_OVERLAY: 1545b2469c81SHans Verkuil if (unlikely(!ops->vidioc_s_fmt_vid_overlay)) 15465bc3cb74SMauro Carvalho Chehab break; 15475bc3cb74SMauro Carvalho Chehab CLEAR_AFTER_FIELD(p, fmt.win); 15485bc3cb74SMauro Carvalho Chehab return ops->vidioc_s_fmt_vid_overlay(file, fh, arg); 15494b20259fSHans Verkuil case V4L2_BUF_TYPE_VBI_CAPTURE: 1550b2469c81SHans Verkuil if (unlikely(!ops->vidioc_s_fmt_vbi_cap)) 15514b20259fSHans Verkuil break; 15524b20259fSHans Verkuil CLEAR_AFTER_FIELD(p, fmt.vbi); 15534b20259fSHans Verkuil return ops->vidioc_s_fmt_vbi_cap(file, fh, arg); 15544b20259fSHans Verkuil case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE: 1555b2469c81SHans Verkuil if (unlikely(!ops->vidioc_s_fmt_sliced_vbi_cap)) 15564b20259fSHans Verkuil break; 15574b20259fSHans Verkuil CLEAR_AFTER_FIELD(p, fmt.sliced); 15584b20259fSHans Verkuil return ops->vidioc_s_fmt_sliced_vbi_cap(file, fh, arg); 15595bc3cb74SMauro Carvalho Chehab case V4L2_BUF_TYPE_VIDEO_OUTPUT: 1560b2469c81SHans Verkuil if (unlikely(!ops->vidioc_s_fmt_vid_out)) 15615bc3cb74SMauro Carvalho Chehab break; 15625bc3cb74SMauro Carvalho Chehab CLEAR_AFTER_FIELD(p, fmt.pix); 156348f2650aSHans Verkuil ret = ops->vidioc_s_fmt_vid_out(file, fh, arg); 156448f2650aSHans Verkuil /* just in case the driver zeroed it again */ 156548f2650aSHans Verkuil p->fmt.pix.priv = V4L2_PIX_FMT_PRIV_MAGIC; 156648f2650aSHans Verkuil return ret; 15675bc3cb74SMauro Carvalho Chehab case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE: 1568b2469c81SHans Verkuil if (unlikely(!ops->vidioc_s_fmt_vid_out_mplane)) 15695bc3cb74SMauro Carvalho Chehab break; 1570c49148e8SLaurent Pinchart CLEAR_AFTER_FIELD(p, fmt.pix_mp.xfer_func); 15714e1e0eb0SEzequiel Garcia for (i = 0; i < p->fmt.pix_mp.num_planes; i++) 15724e1e0eb0SEzequiel Garcia CLEAR_AFTER_FIELD(p, fmt.pix_mp.plane_fmt[i].bytesperline); 15735bc3cb74SMauro Carvalho Chehab return ops->vidioc_s_fmt_vid_out_mplane(file, fh, arg); 15745bc3cb74SMauro Carvalho Chehab case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY: 1575b2469c81SHans Verkuil if (unlikely(!ops->vidioc_s_fmt_vid_out_overlay)) 15765bc3cb74SMauro Carvalho Chehab break; 15775bc3cb74SMauro Carvalho Chehab CLEAR_AFTER_FIELD(p, fmt.win); 15785bc3cb74SMauro Carvalho Chehab return ops->vidioc_s_fmt_vid_out_overlay(file, fh, arg); 15795bc3cb74SMauro Carvalho Chehab case V4L2_BUF_TYPE_VBI_OUTPUT: 1580b2469c81SHans Verkuil if (unlikely(!ops->vidioc_s_fmt_vbi_out)) 15815bc3cb74SMauro Carvalho Chehab break; 15825bc3cb74SMauro Carvalho Chehab CLEAR_AFTER_FIELD(p, fmt.vbi); 15835bc3cb74SMauro Carvalho Chehab return ops->vidioc_s_fmt_vbi_out(file, fh, arg); 15845bc3cb74SMauro Carvalho Chehab case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT: 1585b2469c81SHans Verkuil if (unlikely(!ops->vidioc_s_fmt_sliced_vbi_out)) 15865bc3cb74SMauro Carvalho Chehab break; 15875bc3cb74SMauro Carvalho Chehab CLEAR_AFTER_FIELD(p, fmt.sliced); 15885bc3cb74SMauro Carvalho Chehab return ops->vidioc_s_fmt_sliced_vbi_out(file, fh, arg); 1589582c52cbSAntti Palosaari case V4L2_BUF_TYPE_SDR_CAPTURE: 1590b2469c81SHans Verkuil if (unlikely(!ops->vidioc_s_fmt_sdr_cap)) 1591582c52cbSAntti Palosaari break; 1592582c52cbSAntti Palosaari CLEAR_AFTER_FIELD(p, fmt.sdr); 1593582c52cbSAntti Palosaari return ops->vidioc_s_fmt_sdr_cap(file, fh, arg); 15949effc72fSAntti Palosaari case V4L2_BUF_TYPE_SDR_OUTPUT: 1595b2469c81SHans Verkuil if (unlikely(!ops->vidioc_s_fmt_sdr_out)) 15969effc72fSAntti Palosaari break; 15979effc72fSAntti Palosaari CLEAR_AFTER_FIELD(p, fmt.sdr); 15989effc72fSAntti Palosaari return ops->vidioc_s_fmt_sdr_out(file, fh, arg); 1599fb9ffa6aSLaurent Pinchart case V4L2_BUF_TYPE_META_CAPTURE: 1600b2469c81SHans Verkuil if (unlikely(!ops->vidioc_s_fmt_meta_cap)) 1601fb9ffa6aSLaurent Pinchart break; 1602fb9ffa6aSLaurent Pinchart CLEAR_AFTER_FIELD(p, fmt.meta); 1603fb9ffa6aSLaurent Pinchart return ops->vidioc_s_fmt_meta_cap(file, fh, arg); 16045bc3cb74SMauro Carvalho Chehab } 16055bc3cb74SMauro Carvalho Chehab return -EINVAL; 16065bc3cb74SMauro Carvalho Chehab } 16075bc3cb74SMauro Carvalho Chehab 16085bc3cb74SMauro Carvalho Chehab static int v4l_try_fmt(const struct v4l2_ioctl_ops *ops, 16095bc3cb74SMauro Carvalho Chehab struct file *file, void *fh, void *arg) 16105bc3cb74SMauro Carvalho Chehab { 16115bc3cb74SMauro Carvalho Chehab struct v4l2_format *p = arg; 1612b2469c81SHans Verkuil int ret = check_fmt(file, p->type); 16134e1e0eb0SEzequiel Garcia unsigned int i; 1614b2469c81SHans Verkuil 1615b2469c81SHans Verkuil if (ret) 1616b2469c81SHans Verkuil return ret; 16175bc3cb74SMauro Carvalho Chehab 1618d52e2381SLaurent Pinchart v4l_sanitize_format(p); 1619d52e2381SLaurent Pinchart 16205bc3cb74SMauro Carvalho Chehab switch (p->type) { 16215bc3cb74SMauro Carvalho Chehab case V4L2_BUF_TYPE_VIDEO_CAPTURE: 1622b2469c81SHans Verkuil if (unlikely(!ops->vidioc_try_fmt_vid_cap)) 16235bc3cb74SMauro Carvalho Chehab break; 16245bc3cb74SMauro Carvalho Chehab CLEAR_AFTER_FIELD(p, fmt.pix); 162548f2650aSHans Verkuil ret = ops->vidioc_try_fmt_vid_cap(file, fh, arg); 162648f2650aSHans Verkuil /* just in case the driver zeroed it again */ 162748f2650aSHans Verkuil p->fmt.pix.priv = V4L2_PIX_FMT_PRIV_MAGIC; 162848f2650aSHans Verkuil return ret; 16295bc3cb74SMauro Carvalho Chehab case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE: 1630b2469c81SHans Verkuil if (unlikely(!ops->vidioc_try_fmt_vid_cap_mplane)) 16315bc3cb74SMauro Carvalho Chehab break; 1632c49148e8SLaurent Pinchart CLEAR_AFTER_FIELD(p, fmt.pix_mp.xfer_func); 16334e1e0eb0SEzequiel Garcia for (i = 0; i < p->fmt.pix_mp.num_planes; i++) 16344e1e0eb0SEzequiel Garcia CLEAR_AFTER_FIELD(p, fmt.pix_mp.plane_fmt[i].bytesperline); 16355bc3cb74SMauro Carvalho Chehab return ops->vidioc_try_fmt_vid_cap_mplane(file, fh, arg); 16365bc3cb74SMauro Carvalho Chehab case V4L2_BUF_TYPE_VIDEO_OVERLAY: 1637b2469c81SHans Verkuil if (unlikely(!ops->vidioc_try_fmt_vid_overlay)) 16385bc3cb74SMauro Carvalho Chehab break; 16395bc3cb74SMauro Carvalho Chehab CLEAR_AFTER_FIELD(p, fmt.win); 16405bc3cb74SMauro Carvalho Chehab return ops->vidioc_try_fmt_vid_overlay(file, fh, arg); 16414b20259fSHans Verkuil case V4L2_BUF_TYPE_VBI_CAPTURE: 1642b2469c81SHans Verkuil if (unlikely(!ops->vidioc_try_fmt_vbi_cap)) 16434b20259fSHans Verkuil break; 16444b20259fSHans Verkuil CLEAR_AFTER_FIELD(p, fmt.vbi); 16454b20259fSHans Verkuil return ops->vidioc_try_fmt_vbi_cap(file, fh, arg); 16464b20259fSHans Verkuil case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE: 1647b2469c81SHans Verkuil if (unlikely(!ops->vidioc_try_fmt_sliced_vbi_cap)) 16484b20259fSHans Verkuil break; 16494b20259fSHans Verkuil CLEAR_AFTER_FIELD(p, fmt.sliced); 16504b20259fSHans Verkuil return ops->vidioc_try_fmt_sliced_vbi_cap(file, fh, arg); 16515bc3cb74SMauro Carvalho Chehab case V4L2_BUF_TYPE_VIDEO_OUTPUT: 1652b2469c81SHans Verkuil if (unlikely(!ops->vidioc_try_fmt_vid_out)) 16535bc3cb74SMauro Carvalho Chehab break; 16545bc3cb74SMauro Carvalho Chehab CLEAR_AFTER_FIELD(p, fmt.pix); 165548f2650aSHans Verkuil ret = ops->vidioc_try_fmt_vid_out(file, fh, arg); 165648f2650aSHans Verkuil /* just in case the driver zeroed it again */ 165748f2650aSHans Verkuil p->fmt.pix.priv = V4L2_PIX_FMT_PRIV_MAGIC; 165848f2650aSHans Verkuil return ret; 16595bc3cb74SMauro Carvalho Chehab case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE: 1660b2469c81SHans Verkuil if (unlikely(!ops->vidioc_try_fmt_vid_out_mplane)) 16615bc3cb74SMauro Carvalho Chehab break; 1662c49148e8SLaurent Pinchart CLEAR_AFTER_FIELD(p, fmt.pix_mp.xfer_func); 16634e1e0eb0SEzequiel Garcia for (i = 0; i < p->fmt.pix_mp.num_planes; i++) 16644e1e0eb0SEzequiel Garcia CLEAR_AFTER_FIELD(p, fmt.pix_mp.plane_fmt[i].bytesperline); 16655bc3cb74SMauro Carvalho Chehab return ops->vidioc_try_fmt_vid_out_mplane(file, fh, arg); 16665bc3cb74SMauro Carvalho Chehab case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY: 1667b2469c81SHans Verkuil if (unlikely(!ops->vidioc_try_fmt_vid_out_overlay)) 16685bc3cb74SMauro Carvalho Chehab break; 16695bc3cb74SMauro Carvalho Chehab CLEAR_AFTER_FIELD(p, fmt.win); 16705bc3cb74SMauro Carvalho Chehab return ops->vidioc_try_fmt_vid_out_overlay(file, fh, arg); 16715bc3cb74SMauro Carvalho Chehab case V4L2_BUF_TYPE_VBI_OUTPUT: 1672b2469c81SHans Verkuil if (unlikely(!ops->vidioc_try_fmt_vbi_out)) 16735bc3cb74SMauro Carvalho Chehab break; 16745bc3cb74SMauro Carvalho Chehab CLEAR_AFTER_FIELD(p, fmt.vbi); 16755bc3cb74SMauro Carvalho Chehab return ops->vidioc_try_fmt_vbi_out(file, fh, arg); 16765bc3cb74SMauro Carvalho Chehab case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT: 1677b2469c81SHans Verkuil if (unlikely(!ops->vidioc_try_fmt_sliced_vbi_out)) 16785bc3cb74SMauro Carvalho Chehab break; 16795bc3cb74SMauro Carvalho Chehab CLEAR_AFTER_FIELD(p, fmt.sliced); 16805bc3cb74SMauro Carvalho Chehab return ops->vidioc_try_fmt_sliced_vbi_out(file, fh, arg); 1681582c52cbSAntti Palosaari case V4L2_BUF_TYPE_SDR_CAPTURE: 1682b2469c81SHans Verkuil if (unlikely(!ops->vidioc_try_fmt_sdr_cap)) 1683582c52cbSAntti Palosaari break; 1684582c52cbSAntti Palosaari CLEAR_AFTER_FIELD(p, fmt.sdr); 1685582c52cbSAntti Palosaari return ops->vidioc_try_fmt_sdr_cap(file, fh, arg); 16869effc72fSAntti Palosaari case V4L2_BUF_TYPE_SDR_OUTPUT: 1687b2469c81SHans Verkuil if (unlikely(!ops->vidioc_try_fmt_sdr_out)) 16889effc72fSAntti Palosaari break; 16899effc72fSAntti Palosaari CLEAR_AFTER_FIELD(p, fmt.sdr); 16909effc72fSAntti Palosaari return ops->vidioc_try_fmt_sdr_out(file, fh, arg); 1691fb9ffa6aSLaurent Pinchart case V4L2_BUF_TYPE_META_CAPTURE: 1692b2469c81SHans Verkuil if (unlikely(!ops->vidioc_try_fmt_meta_cap)) 1693fb9ffa6aSLaurent Pinchart break; 1694fb9ffa6aSLaurent Pinchart CLEAR_AFTER_FIELD(p, fmt.meta); 1695fb9ffa6aSLaurent Pinchart return ops->vidioc_try_fmt_meta_cap(file, fh, arg); 16965bc3cb74SMauro Carvalho Chehab } 16975bc3cb74SMauro Carvalho Chehab return -EINVAL; 16985bc3cb74SMauro Carvalho Chehab } 16995bc3cb74SMauro Carvalho Chehab 17005bc3cb74SMauro Carvalho Chehab static int v4l_streamon(const struct v4l2_ioctl_ops *ops, 17015bc3cb74SMauro Carvalho Chehab struct file *file, void *fh, void *arg) 17025bc3cb74SMauro Carvalho Chehab { 17035bc3cb74SMauro Carvalho Chehab return ops->vidioc_streamon(file, fh, *(unsigned int *)arg); 17045bc3cb74SMauro Carvalho Chehab } 17055bc3cb74SMauro Carvalho Chehab 17065bc3cb74SMauro Carvalho Chehab static int v4l_streamoff(const struct v4l2_ioctl_ops *ops, 17075bc3cb74SMauro Carvalho Chehab struct file *file, void *fh, void *arg) 17085bc3cb74SMauro Carvalho Chehab { 17095bc3cb74SMauro Carvalho Chehab return ops->vidioc_streamoff(file, fh, *(unsigned int *)arg); 17105bc3cb74SMauro Carvalho Chehab } 17115bc3cb74SMauro Carvalho Chehab 17125bc3cb74SMauro Carvalho Chehab static int v4l_g_tuner(const struct v4l2_ioctl_ops *ops, 17135bc3cb74SMauro Carvalho Chehab struct file *file, void *fh, void *arg) 17145bc3cb74SMauro Carvalho Chehab { 17155bc3cb74SMauro Carvalho Chehab struct video_device *vfd = video_devdata(file); 17165bc3cb74SMauro Carvalho Chehab struct v4l2_tuner *p = arg; 17175bc3cb74SMauro Carvalho Chehab int err; 17185bc3cb74SMauro Carvalho Chehab 17195bc3cb74SMauro Carvalho Chehab p->type = (vfd->vfl_type == VFL_TYPE_RADIO) ? 17205bc3cb74SMauro Carvalho Chehab V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV; 17215bc3cb74SMauro Carvalho Chehab err = ops->vidioc_g_tuner(file, fh, p); 17225bc3cb74SMauro Carvalho Chehab if (!err) 17235bc3cb74SMauro Carvalho Chehab p->capability |= V4L2_TUNER_CAP_FREQ_BANDS; 17245bc3cb74SMauro Carvalho Chehab return err; 17255bc3cb74SMauro Carvalho Chehab } 17265bc3cb74SMauro Carvalho Chehab 17275bc3cb74SMauro Carvalho Chehab static int v4l_s_tuner(const struct v4l2_ioctl_ops *ops, 17285bc3cb74SMauro Carvalho Chehab struct file *file, void *fh, void *arg) 17295bc3cb74SMauro Carvalho Chehab { 17305bc3cb74SMauro Carvalho Chehab struct video_device *vfd = video_devdata(file); 17315bc3cb74SMauro Carvalho Chehab struct v4l2_tuner *p = arg; 173277fa4e07SShuah Khan int ret; 17335bc3cb74SMauro Carvalho Chehab 173477fa4e07SShuah Khan ret = v4l_enable_media_source(vfd); 173577fa4e07SShuah Khan if (ret) 173677fa4e07SShuah Khan return ret; 17375bc3cb74SMauro Carvalho Chehab p->type = (vfd->vfl_type == VFL_TYPE_RADIO) ? 17385bc3cb74SMauro Carvalho Chehab V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV; 17395bc3cb74SMauro Carvalho Chehab return ops->vidioc_s_tuner(file, fh, p); 17405bc3cb74SMauro Carvalho Chehab } 17415bc3cb74SMauro Carvalho Chehab 17425bc3cb74SMauro Carvalho Chehab static int v4l_g_modulator(const struct v4l2_ioctl_ops *ops, 17435bc3cb74SMauro Carvalho Chehab struct file *file, void *fh, void *arg) 17445bc3cb74SMauro Carvalho Chehab { 17454124a3c4SAntti Palosaari struct video_device *vfd = video_devdata(file); 17465bc3cb74SMauro Carvalho Chehab struct v4l2_modulator *p = arg; 17475bc3cb74SMauro Carvalho Chehab int err; 17485bc3cb74SMauro Carvalho Chehab 17494124a3c4SAntti Palosaari if (vfd->vfl_type == VFL_TYPE_RADIO) 17504124a3c4SAntti Palosaari p->type = V4L2_TUNER_RADIO; 17514124a3c4SAntti Palosaari 17525bc3cb74SMauro Carvalho Chehab err = ops->vidioc_g_modulator(file, fh, p); 17535bc3cb74SMauro Carvalho Chehab if (!err) 17545bc3cb74SMauro Carvalho Chehab p->capability |= V4L2_TUNER_CAP_FREQ_BANDS; 17555bc3cb74SMauro Carvalho Chehab return err; 17565bc3cb74SMauro Carvalho Chehab } 17575bc3cb74SMauro Carvalho Chehab 17584124a3c4SAntti Palosaari static int v4l_s_modulator(const struct v4l2_ioctl_ops *ops, 17594124a3c4SAntti Palosaari struct file *file, void *fh, void *arg) 17604124a3c4SAntti Palosaari { 17614124a3c4SAntti Palosaari struct video_device *vfd = video_devdata(file); 17624124a3c4SAntti Palosaari struct v4l2_modulator *p = arg; 17634124a3c4SAntti Palosaari 17644124a3c4SAntti Palosaari if (vfd->vfl_type == VFL_TYPE_RADIO) 17654124a3c4SAntti Palosaari p->type = V4L2_TUNER_RADIO; 17664124a3c4SAntti Palosaari 17674124a3c4SAntti Palosaari return ops->vidioc_s_modulator(file, fh, p); 17684124a3c4SAntti Palosaari } 17694124a3c4SAntti Palosaari 17705bc3cb74SMauro Carvalho Chehab static int v4l_g_frequency(const struct v4l2_ioctl_ops *ops, 17715bc3cb74SMauro Carvalho Chehab struct file *file, void *fh, void *arg) 17725bc3cb74SMauro Carvalho Chehab { 17735bc3cb74SMauro Carvalho Chehab struct video_device *vfd = video_devdata(file); 17745bc3cb74SMauro Carvalho Chehab struct v4l2_frequency *p = arg; 17755bc3cb74SMauro Carvalho Chehab 177684099a28SAntti Palosaari if (vfd->vfl_type == VFL_TYPE_SDR) 1777f3c3ececSAntti Palosaari p->type = V4L2_TUNER_SDR; 177884099a28SAntti Palosaari else 17795bc3cb74SMauro Carvalho Chehab p->type = (vfd->vfl_type == VFL_TYPE_RADIO) ? 17805bc3cb74SMauro Carvalho Chehab V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV; 17815bc3cb74SMauro Carvalho Chehab return ops->vidioc_g_frequency(file, fh, p); 17825bc3cb74SMauro Carvalho Chehab } 17835bc3cb74SMauro Carvalho Chehab 17845bc3cb74SMauro Carvalho Chehab static int v4l_s_frequency(const struct v4l2_ioctl_ops *ops, 17855bc3cb74SMauro Carvalho Chehab struct file *file, void *fh, void *arg) 17865bc3cb74SMauro Carvalho Chehab { 17875bc3cb74SMauro Carvalho Chehab struct video_device *vfd = video_devdata(file); 1788b530a447SHans Verkuil const struct v4l2_frequency *p = arg; 17895bc3cb74SMauro Carvalho Chehab enum v4l2_tuner_type type; 179077fa4e07SShuah Khan int ret; 17915bc3cb74SMauro Carvalho Chehab 179277fa4e07SShuah Khan ret = v4l_enable_media_source(vfd); 179377fa4e07SShuah Khan if (ret) 179477fa4e07SShuah Khan return ret; 179584099a28SAntti Palosaari if (vfd->vfl_type == VFL_TYPE_SDR) { 1796f3c3ececSAntti Palosaari if (p->type != V4L2_TUNER_SDR && p->type != V4L2_TUNER_RF) 179784099a28SAntti Palosaari return -EINVAL; 179884099a28SAntti Palosaari } else { 17995bc3cb74SMauro Carvalho Chehab type = (vfd->vfl_type == VFL_TYPE_RADIO) ? 18005bc3cb74SMauro Carvalho Chehab V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV; 180184099a28SAntti Palosaari if (type != p->type) 18025bc3cb74SMauro Carvalho Chehab return -EINVAL; 180384099a28SAntti Palosaari } 18045bc3cb74SMauro Carvalho Chehab return ops->vidioc_s_frequency(file, fh, p); 18055bc3cb74SMauro Carvalho Chehab } 18065bc3cb74SMauro Carvalho Chehab 18075bc3cb74SMauro Carvalho Chehab static int v4l_enumstd(const struct v4l2_ioctl_ops *ops, 18085bc3cb74SMauro Carvalho Chehab struct file *file, void *fh, void *arg) 18095bc3cb74SMauro Carvalho Chehab { 18105bc3cb74SMauro Carvalho Chehab struct video_device *vfd = video_devdata(file); 18115bc3cb74SMauro Carvalho Chehab struct v4l2_standard *p = arg; 18125bc3cb74SMauro Carvalho Chehab 1813aa2f8871SNiklas Söderlund return v4l_video_std_enumstd(p, vfd->tvnorms); 18145bc3cb74SMauro Carvalho Chehab } 18155bc3cb74SMauro Carvalho Chehab 18165bc3cb74SMauro Carvalho Chehab static int v4l_s_std(const struct v4l2_ioctl_ops *ops, 18175bc3cb74SMauro Carvalho Chehab struct file *file, void *fh, void *arg) 18185bc3cb74SMauro Carvalho Chehab { 18195bc3cb74SMauro Carvalho Chehab struct video_device *vfd = video_devdata(file); 1820314527acSHans Verkuil v4l2_std_id id = *(v4l2_std_id *)arg, norm; 182177fa4e07SShuah Khan int ret; 18225bc3cb74SMauro Carvalho Chehab 182377fa4e07SShuah Khan ret = v4l_enable_media_source(vfd); 182477fa4e07SShuah Khan if (ret) 182577fa4e07SShuah Khan return ret; 1826314527acSHans Verkuil norm = id & vfd->tvnorms; 18275bc3cb74SMauro Carvalho Chehab if (vfd->tvnorms && !norm) /* Check if std is supported */ 18285bc3cb74SMauro Carvalho Chehab return -EINVAL; 18295bc3cb74SMauro Carvalho Chehab 18305bc3cb74SMauro Carvalho Chehab /* Calls the specific handler */ 1831ca371575SHans Verkuil return ops->vidioc_s_std(file, fh, norm); 18325bc3cb74SMauro Carvalho Chehab } 18335bc3cb74SMauro Carvalho Chehab 18345bc3cb74SMauro Carvalho Chehab static int v4l_querystd(const struct v4l2_ioctl_ops *ops, 18355bc3cb74SMauro Carvalho Chehab struct file *file, void *fh, void *arg) 18365bc3cb74SMauro Carvalho Chehab { 18375bc3cb74SMauro Carvalho Chehab struct video_device *vfd = video_devdata(file); 18385bc3cb74SMauro Carvalho Chehab v4l2_std_id *p = arg; 183977fa4e07SShuah Khan int ret; 18405bc3cb74SMauro Carvalho Chehab 184177fa4e07SShuah Khan ret = v4l_enable_media_source(vfd); 184277fa4e07SShuah Khan if (ret) 184377fa4e07SShuah Khan return ret; 18445bc3cb74SMauro Carvalho Chehab /* 18451a2c6866SHans Verkuil * If no signal is detected, then the driver should return 18461a2c6866SHans Verkuil * V4L2_STD_UNKNOWN. Otherwise it should return tvnorms with 18471a2c6866SHans Verkuil * any standards that do not apply removed. 18481a2c6866SHans Verkuil * 18495bc3cb74SMauro Carvalho Chehab * This means that tuners, audio and video decoders can join 18505bc3cb74SMauro Carvalho Chehab * their efforts to improve the standards detection. 18515bc3cb74SMauro Carvalho Chehab */ 18525bc3cb74SMauro Carvalho Chehab *p = vfd->tvnorms; 18535bc3cb74SMauro Carvalho Chehab return ops->vidioc_querystd(file, fh, arg); 18545bc3cb74SMauro Carvalho Chehab } 18555bc3cb74SMauro Carvalho Chehab 18565bc3cb74SMauro Carvalho Chehab static int v4l_s_hw_freq_seek(const struct v4l2_ioctl_ops *ops, 18575bc3cb74SMauro Carvalho Chehab struct file *file, void *fh, void *arg) 18585bc3cb74SMauro Carvalho Chehab { 18595bc3cb74SMauro Carvalho Chehab struct video_device *vfd = video_devdata(file); 18605bc3cb74SMauro Carvalho Chehab struct v4l2_hw_freq_seek *p = arg; 18615bc3cb74SMauro Carvalho Chehab enum v4l2_tuner_type type; 186277fa4e07SShuah Khan int ret; 18635bc3cb74SMauro Carvalho Chehab 186477fa4e07SShuah Khan ret = v4l_enable_media_source(vfd); 186577fa4e07SShuah Khan if (ret) 186677fa4e07SShuah Khan return ret; 186784099a28SAntti Palosaari /* s_hw_freq_seek is not supported for SDR for now */ 186884099a28SAntti Palosaari if (vfd->vfl_type == VFL_TYPE_SDR) 186984099a28SAntti Palosaari return -EINVAL; 187084099a28SAntti Palosaari 18715bc3cb74SMauro Carvalho Chehab type = (vfd->vfl_type == VFL_TYPE_RADIO) ? 18725bc3cb74SMauro Carvalho Chehab V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV; 18735bc3cb74SMauro Carvalho Chehab if (p->type != type) 18745bc3cb74SMauro Carvalho Chehab return -EINVAL; 18755bc3cb74SMauro Carvalho Chehab return ops->vidioc_s_hw_freq_seek(file, fh, p); 18765bc3cb74SMauro Carvalho Chehab } 18775bc3cb74SMauro Carvalho Chehab 1878737c097bSHans Verkuil static int v4l_overlay(const struct v4l2_ioctl_ops *ops, 1879737c097bSHans Verkuil struct file *file, void *fh, void *arg) 1880737c097bSHans Verkuil { 1881737c097bSHans Verkuil return ops->vidioc_overlay(file, fh, *(unsigned int *)arg); 1882737c097bSHans Verkuil } 1883737c097bSHans Verkuil 18845bc3cb74SMauro Carvalho Chehab static int v4l_reqbufs(const struct v4l2_ioctl_ops *ops, 18855bc3cb74SMauro Carvalho Chehab struct file *file, void *fh, void *arg) 18865bc3cb74SMauro Carvalho Chehab { 18875bc3cb74SMauro Carvalho Chehab struct v4l2_requestbuffers *p = arg; 18884b20259fSHans Verkuil int ret = check_fmt(file, p->type); 18895bc3cb74SMauro Carvalho Chehab 18905bc3cb74SMauro Carvalho Chehab if (ret) 18915bc3cb74SMauro Carvalho Chehab return ret; 18925bc3cb74SMauro Carvalho Chehab 1893e5079cf1SHans Verkuil CLEAR_AFTER_FIELD(p, capabilities); 18945bc3cb74SMauro Carvalho Chehab 18955bc3cb74SMauro Carvalho Chehab return ops->vidioc_reqbufs(file, fh, p); 18965bc3cb74SMauro Carvalho Chehab } 18975bc3cb74SMauro Carvalho Chehab 18985bc3cb74SMauro Carvalho Chehab static int v4l_querybuf(const struct v4l2_ioctl_ops *ops, 18995bc3cb74SMauro Carvalho Chehab struct file *file, void *fh, void *arg) 19005bc3cb74SMauro Carvalho Chehab { 19015bc3cb74SMauro Carvalho Chehab struct v4l2_buffer *p = arg; 19024b20259fSHans Verkuil int ret = check_fmt(file, p->type); 19035bc3cb74SMauro Carvalho Chehab 19045bc3cb74SMauro Carvalho Chehab return ret ? ret : ops->vidioc_querybuf(file, fh, p); 19055bc3cb74SMauro Carvalho Chehab } 19065bc3cb74SMauro Carvalho Chehab 19075bc3cb74SMauro Carvalho Chehab static int v4l_qbuf(const struct v4l2_ioctl_ops *ops, 19085bc3cb74SMauro Carvalho Chehab struct file *file, void *fh, void *arg) 19095bc3cb74SMauro Carvalho Chehab { 19105bc3cb74SMauro Carvalho Chehab struct v4l2_buffer *p = arg; 19114b20259fSHans Verkuil int ret = check_fmt(file, p->type); 19125bc3cb74SMauro Carvalho Chehab 19135bc3cb74SMauro Carvalho Chehab return ret ? ret : ops->vidioc_qbuf(file, fh, p); 19145bc3cb74SMauro Carvalho Chehab } 19155bc3cb74SMauro Carvalho Chehab 19165bc3cb74SMauro Carvalho Chehab static int v4l_dqbuf(const struct v4l2_ioctl_ops *ops, 19175bc3cb74SMauro Carvalho Chehab struct file *file, void *fh, void *arg) 19185bc3cb74SMauro Carvalho Chehab { 19195bc3cb74SMauro Carvalho Chehab struct v4l2_buffer *p = arg; 19204b20259fSHans Verkuil int ret = check_fmt(file, p->type); 19215bc3cb74SMauro Carvalho Chehab 19225bc3cb74SMauro Carvalho Chehab return ret ? ret : ops->vidioc_dqbuf(file, fh, p); 19235bc3cb74SMauro Carvalho Chehab } 19245bc3cb74SMauro Carvalho Chehab 19255bc3cb74SMauro Carvalho Chehab static int v4l_create_bufs(const struct v4l2_ioctl_ops *ops, 19265bc3cb74SMauro Carvalho Chehab struct file *file, void *fh, void *arg) 19275bc3cb74SMauro Carvalho Chehab { 19285bc3cb74SMauro Carvalho Chehab struct v4l2_create_buffers *create = arg; 19294b20259fSHans Verkuil int ret = check_fmt(file, create->format.type); 19305bc3cb74SMauro Carvalho Chehab 1931d52e2381SLaurent Pinchart if (ret) 1932d52e2381SLaurent Pinchart return ret; 1933d52e2381SLaurent Pinchart 1934e5079cf1SHans Verkuil CLEAR_AFTER_FIELD(create, capabilities); 19355d351251SHans Verkuil 1936d52e2381SLaurent Pinchart v4l_sanitize_format(&create->format); 1937d52e2381SLaurent Pinchart 1938d52e2381SLaurent Pinchart ret = ops->vidioc_create_bufs(file, fh, create); 1939d52e2381SLaurent Pinchart 1940d52e2381SLaurent Pinchart if (create->format.type == V4L2_BUF_TYPE_VIDEO_CAPTURE || 1941d52e2381SLaurent Pinchart create->format.type == V4L2_BUF_TYPE_VIDEO_OUTPUT) 1942d52e2381SLaurent Pinchart create->format.fmt.pix.priv = V4L2_PIX_FMT_PRIV_MAGIC; 1943d52e2381SLaurent Pinchart 1944d52e2381SLaurent Pinchart return ret; 19455bc3cb74SMauro Carvalho Chehab } 19465bc3cb74SMauro Carvalho Chehab 19475bc3cb74SMauro Carvalho Chehab static int v4l_prepare_buf(const struct v4l2_ioctl_ops *ops, 19485bc3cb74SMauro Carvalho Chehab struct file *file, void *fh, void *arg) 19495bc3cb74SMauro Carvalho Chehab { 19505bc3cb74SMauro Carvalho Chehab struct v4l2_buffer *b = arg; 19514b20259fSHans Verkuil int ret = check_fmt(file, b->type); 19525bc3cb74SMauro Carvalho Chehab 19535bc3cb74SMauro Carvalho Chehab return ret ? ret : ops->vidioc_prepare_buf(file, fh, b); 19545bc3cb74SMauro Carvalho Chehab } 19555bc3cb74SMauro Carvalho Chehab 19565bc3cb74SMauro Carvalho Chehab static int v4l_g_parm(const struct v4l2_ioctl_ops *ops, 19575bc3cb74SMauro Carvalho Chehab struct file *file, void *fh, void *arg) 19585bc3cb74SMauro Carvalho Chehab { 19595bc3cb74SMauro Carvalho Chehab struct v4l2_streamparm *p = arg; 19605bc3cb74SMauro Carvalho Chehab v4l2_std_id std; 19614b20259fSHans Verkuil int ret = check_fmt(file, p->type); 19625bc3cb74SMauro Carvalho Chehab 19635bc3cb74SMauro Carvalho Chehab if (ret) 19645bc3cb74SMauro Carvalho Chehab return ret; 19655bc3cb74SMauro Carvalho Chehab if (ops->vidioc_g_parm) 19665bc3cb74SMauro Carvalho Chehab return ops->vidioc_g_parm(file, fh, p); 19675bc3cb74SMauro Carvalho Chehab if (p->type != V4L2_BUF_TYPE_VIDEO_CAPTURE && 19685bc3cb74SMauro Carvalho Chehab p->type != V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) 19695bc3cb74SMauro Carvalho Chehab return -EINVAL; 19705bc3cb74SMauro Carvalho Chehab p->parm.capture.readbuffers = 2; 19715bc3cb74SMauro Carvalho Chehab ret = ops->vidioc_g_std(file, fh, &std); 19725bc3cb74SMauro Carvalho Chehab if (ret == 0) 1973ca371575SHans Verkuil v4l2_video_std_frame_period(std, &p->parm.capture.timeperframe); 19745bc3cb74SMauro Carvalho Chehab return ret; 19755bc3cb74SMauro Carvalho Chehab } 19765bc3cb74SMauro Carvalho Chehab 19775bc3cb74SMauro Carvalho Chehab static int v4l_s_parm(const struct v4l2_ioctl_ops *ops, 19785bc3cb74SMauro Carvalho Chehab struct file *file, void *fh, void *arg) 19795bc3cb74SMauro Carvalho Chehab { 19805bc3cb74SMauro Carvalho Chehab struct v4l2_streamparm *p = arg; 19814b20259fSHans Verkuil int ret = check_fmt(file, p->type); 19825bc3cb74SMauro Carvalho Chehab 19838a7c5594SHans Verkuil if (ret) 19848a7c5594SHans Verkuil return ret; 19858a7c5594SHans Verkuil 19868a7c5594SHans Verkuil /* Note: extendedmode is never used in drivers */ 19878a7c5594SHans Verkuil if (V4L2_TYPE_IS_OUTPUT(p->type)) { 19888a7c5594SHans Verkuil memset(p->parm.output.reserved, 0, 19898a7c5594SHans Verkuil sizeof(p->parm.output.reserved)); 19908a7c5594SHans Verkuil p->parm.output.extendedmode = 0; 19918a7c5594SHans Verkuil p->parm.output.outputmode &= V4L2_MODE_HIGHQUALITY; 19928a7c5594SHans Verkuil } else { 19938a7c5594SHans Verkuil memset(p->parm.capture.reserved, 0, 19948a7c5594SHans Verkuil sizeof(p->parm.capture.reserved)); 19958a7c5594SHans Verkuil p->parm.capture.extendedmode = 0; 19968a7c5594SHans Verkuil p->parm.capture.capturemode &= V4L2_MODE_HIGHQUALITY; 19978a7c5594SHans Verkuil } 19988a7c5594SHans Verkuil return ops->vidioc_s_parm(file, fh, p); 19995bc3cb74SMauro Carvalho Chehab } 20005bc3cb74SMauro Carvalho Chehab 20015bc3cb74SMauro Carvalho Chehab static int v4l_queryctrl(const struct v4l2_ioctl_ops *ops, 20025bc3cb74SMauro Carvalho Chehab struct file *file, void *fh, void *arg) 20035bc3cb74SMauro Carvalho Chehab { 20045bc3cb74SMauro Carvalho Chehab struct video_device *vfd = video_devdata(file); 20055bc3cb74SMauro Carvalho Chehab struct v4l2_queryctrl *p = arg; 20065bc3cb74SMauro Carvalho Chehab struct v4l2_fh *vfh = 20075bc3cb74SMauro Carvalho Chehab test_bit(V4L2_FL_USES_V4L2_FH, &vfd->flags) ? fh : NULL; 20085bc3cb74SMauro Carvalho Chehab 20095bc3cb74SMauro Carvalho Chehab if (vfh && vfh->ctrl_handler) 20105bc3cb74SMauro Carvalho Chehab return v4l2_queryctrl(vfh->ctrl_handler, p); 20115bc3cb74SMauro Carvalho Chehab if (vfd->ctrl_handler) 20125bc3cb74SMauro Carvalho Chehab return v4l2_queryctrl(vfd->ctrl_handler, p); 20135bc3cb74SMauro Carvalho Chehab if (ops->vidioc_queryctrl) 20145bc3cb74SMauro Carvalho Chehab return ops->vidioc_queryctrl(file, fh, p); 20155bc3cb74SMauro Carvalho Chehab return -ENOTTY; 20165bc3cb74SMauro Carvalho Chehab } 20175bc3cb74SMauro Carvalho Chehab 2018e6bee368SHans Verkuil static int v4l_query_ext_ctrl(const struct v4l2_ioctl_ops *ops, 2019e6bee368SHans Verkuil struct file *file, void *fh, void *arg) 2020e6bee368SHans Verkuil { 2021e6bee368SHans Verkuil struct video_device *vfd = video_devdata(file); 2022e6bee368SHans Verkuil struct v4l2_query_ext_ctrl *p = arg; 2023e6bee368SHans Verkuil struct v4l2_fh *vfh = 2024e6bee368SHans Verkuil test_bit(V4L2_FL_USES_V4L2_FH, &vfd->flags) ? fh : NULL; 2025e6bee368SHans Verkuil 2026e6bee368SHans Verkuil if (vfh && vfh->ctrl_handler) 2027e6bee368SHans Verkuil return v4l2_query_ext_ctrl(vfh->ctrl_handler, p); 2028e6bee368SHans Verkuil if (vfd->ctrl_handler) 2029e6bee368SHans Verkuil return v4l2_query_ext_ctrl(vfd->ctrl_handler, p); 2030e6bee368SHans Verkuil if (ops->vidioc_query_ext_ctrl) 2031e6bee368SHans Verkuil return ops->vidioc_query_ext_ctrl(file, fh, p); 2032e6bee368SHans Verkuil return -ENOTTY; 2033e6bee368SHans Verkuil } 2034e6bee368SHans Verkuil 20355bc3cb74SMauro Carvalho Chehab static int v4l_querymenu(const struct v4l2_ioctl_ops *ops, 20365bc3cb74SMauro Carvalho Chehab struct file *file, void *fh, void *arg) 20375bc3cb74SMauro Carvalho Chehab { 20385bc3cb74SMauro Carvalho Chehab struct video_device *vfd = video_devdata(file); 20395bc3cb74SMauro Carvalho Chehab struct v4l2_querymenu *p = arg; 20405bc3cb74SMauro Carvalho Chehab struct v4l2_fh *vfh = 20415bc3cb74SMauro Carvalho Chehab test_bit(V4L2_FL_USES_V4L2_FH, &vfd->flags) ? fh : NULL; 20425bc3cb74SMauro Carvalho Chehab 20435bc3cb74SMauro Carvalho Chehab if (vfh && vfh->ctrl_handler) 20445bc3cb74SMauro Carvalho Chehab return v4l2_querymenu(vfh->ctrl_handler, p); 20455bc3cb74SMauro Carvalho Chehab if (vfd->ctrl_handler) 20465bc3cb74SMauro Carvalho Chehab return v4l2_querymenu(vfd->ctrl_handler, p); 20475bc3cb74SMauro Carvalho Chehab if (ops->vidioc_querymenu) 20485bc3cb74SMauro Carvalho Chehab return ops->vidioc_querymenu(file, fh, p); 20495bc3cb74SMauro Carvalho Chehab return -ENOTTY; 20505bc3cb74SMauro Carvalho Chehab } 20515bc3cb74SMauro Carvalho Chehab 20525bc3cb74SMauro Carvalho Chehab static int v4l_g_ctrl(const struct v4l2_ioctl_ops *ops, 20535bc3cb74SMauro Carvalho Chehab struct file *file, void *fh, void *arg) 20545bc3cb74SMauro Carvalho Chehab { 20555bc3cb74SMauro Carvalho Chehab struct video_device *vfd = video_devdata(file); 20565bc3cb74SMauro Carvalho Chehab struct v4l2_control *p = arg; 20575bc3cb74SMauro Carvalho Chehab struct v4l2_fh *vfh = 20585bc3cb74SMauro Carvalho Chehab test_bit(V4L2_FL_USES_V4L2_FH, &vfd->flags) ? fh : NULL; 20595bc3cb74SMauro Carvalho Chehab struct v4l2_ext_controls ctrls; 20605bc3cb74SMauro Carvalho Chehab struct v4l2_ext_control ctrl; 20615bc3cb74SMauro Carvalho Chehab 20625bc3cb74SMauro Carvalho Chehab if (vfh && vfh->ctrl_handler) 20635bc3cb74SMauro Carvalho Chehab return v4l2_g_ctrl(vfh->ctrl_handler, p); 20645bc3cb74SMauro Carvalho Chehab if (vfd->ctrl_handler) 20655bc3cb74SMauro Carvalho Chehab return v4l2_g_ctrl(vfd->ctrl_handler, p); 20665bc3cb74SMauro Carvalho Chehab if (ops->vidioc_g_ctrl) 20675bc3cb74SMauro Carvalho Chehab return ops->vidioc_g_ctrl(file, fh, p); 20685bc3cb74SMauro Carvalho Chehab if (ops->vidioc_g_ext_ctrls == NULL) 20695bc3cb74SMauro Carvalho Chehab return -ENOTTY; 20705bc3cb74SMauro Carvalho Chehab 20710f8017beSRicardo Ribalda ctrls.which = V4L2_CTRL_ID2WHICH(p->id); 20725bc3cb74SMauro Carvalho Chehab ctrls.count = 1; 20735bc3cb74SMauro Carvalho Chehab ctrls.controls = &ctrl; 20745bc3cb74SMauro Carvalho Chehab ctrl.id = p->id; 20755bc3cb74SMauro Carvalho Chehab ctrl.value = p->value; 20765bc3cb74SMauro Carvalho Chehab if (check_ext_ctrls(&ctrls, 1)) { 20775bc3cb74SMauro Carvalho Chehab int ret = ops->vidioc_g_ext_ctrls(file, fh, &ctrls); 20785bc3cb74SMauro Carvalho Chehab 20795bc3cb74SMauro Carvalho Chehab if (ret == 0) 20805bc3cb74SMauro Carvalho Chehab p->value = ctrl.value; 20815bc3cb74SMauro Carvalho Chehab return ret; 20825bc3cb74SMauro Carvalho Chehab } 20835bc3cb74SMauro Carvalho Chehab return -EINVAL; 20845bc3cb74SMauro Carvalho Chehab } 20855bc3cb74SMauro Carvalho Chehab 20865bc3cb74SMauro Carvalho Chehab static int v4l_s_ctrl(const struct v4l2_ioctl_ops *ops, 20875bc3cb74SMauro Carvalho Chehab struct file *file, void *fh, void *arg) 20885bc3cb74SMauro Carvalho Chehab { 20895bc3cb74SMauro Carvalho Chehab struct video_device *vfd = video_devdata(file); 20905bc3cb74SMauro Carvalho Chehab struct v4l2_control *p = arg; 20915bc3cb74SMauro Carvalho Chehab struct v4l2_fh *vfh = 20925bc3cb74SMauro Carvalho Chehab test_bit(V4L2_FL_USES_V4L2_FH, &vfd->flags) ? fh : NULL; 20935bc3cb74SMauro Carvalho Chehab struct v4l2_ext_controls ctrls; 20945bc3cb74SMauro Carvalho Chehab struct v4l2_ext_control ctrl; 20955bc3cb74SMauro Carvalho Chehab 20965bc3cb74SMauro Carvalho Chehab if (vfh && vfh->ctrl_handler) 20975bc3cb74SMauro Carvalho Chehab return v4l2_s_ctrl(vfh, vfh->ctrl_handler, p); 20985bc3cb74SMauro Carvalho Chehab if (vfd->ctrl_handler) 20995bc3cb74SMauro Carvalho Chehab return v4l2_s_ctrl(NULL, vfd->ctrl_handler, p); 21005bc3cb74SMauro Carvalho Chehab if (ops->vidioc_s_ctrl) 21015bc3cb74SMauro Carvalho Chehab return ops->vidioc_s_ctrl(file, fh, p); 21025bc3cb74SMauro Carvalho Chehab if (ops->vidioc_s_ext_ctrls == NULL) 21035bc3cb74SMauro Carvalho Chehab return -ENOTTY; 21045bc3cb74SMauro Carvalho Chehab 21050f8017beSRicardo Ribalda ctrls.which = V4L2_CTRL_ID2WHICH(p->id); 21065bc3cb74SMauro Carvalho Chehab ctrls.count = 1; 21075bc3cb74SMauro Carvalho Chehab ctrls.controls = &ctrl; 21085bc3cb74SMauro Carvalho Chehab ctrl.id = p->id; 21095bc3cb74SMauro Carvalho Chehab ctrl.value = p->value; 21105bc3cb74SMauro Carvalho Chehab if (check_ext_ctrls(&ctrls, 1)) 21115bc3cb74SMauro Carvalho Chehab return ops->vidioc_s_ext_ctrls(file, fh, &ctrls); 21125bc3cb74SMauro Carvalho Chehab return -EINVAL; 21135bc3cb74SMauro Carvalho Chehab } 21145bc3cb74SMauro Carvalho Chehab 21155bc3cb74SMauro Carvalho Chehab static int v4l_g_ext_ctrls(const struct v4l2_ioctl_ops *ops, 21165bc3cb74SMauro Carvalho Chehab struct file *file, void *fh, void *arg) 21175bc3cb74SMauro Carvalho Chehab { 21185bc3cb74SMauro Carvalho Chehab struct video_device *vfd = video_devdata(file); 21195bc3cb74SMauro Carvalho Chehab struct v4l2_ext_controls *p = arg; 21205bc3cb74SMauro Carvalho Chehab struct v4l2_fh *vfh = 21215bc3cb74SMauro Carvalho Chehab test_bit(V4L2_FL_USES_V4L2_FH, &vfd->flags) ? fh : NULL; 21225bc3cb74SMauro Carvalho Chehab 21235bc3cb74SMauro Carvalho Chehab p->error_idx = p->count; 21245bc3cb74SMauro Carvalho Chehab if (vfh && vfh->ctrl_handler) 2125c41e9cffSHans Verkuil return v4l2_g_ext_ctrls(vfh->ctrl_handler, vfd->v4l2_dev->mdev, p); 21265bc3cb74SMauro Carvalho Chehab if (vfd->ctrl_handler) 2127c41e9cffSHans Verkuil return v4l2_g_ext_ctrls(vfd->ctrl_handler, vfd->v4l2_dev->mdev, p); 21285bc3cb74SMauro Carvalho Chehab if (ops->vidioc_g_ext_ctrls == NULL) 21295bc3cb74SMauro Carvalho Chehab return -ENOTTY; 21305bc3cb74SMauro Carvalho Chehab return check_ext_ctrls(p, 0) ? ops->vidioc_g_ext_ctrls(file, fh, p) : 21315bc3cb74SMauro Carvalho Chehab -EINVAL; 21325bc3cb74SMauro Carvalho Chehab } 21335bc3cb74SMauro Carvalho Chehab 21345bc3cb74SMauro Carvalho Chehab static int v4l_s_ext_ctrls(const struct v4l2_ioctl_ops *ops, 21355bc3cb74SMauro Carvalho Chehab struct file *file, void *fh, void *arg) 21365bc3cb74SMauro Carvalho Chehab { 21375bc3cb74SMauro Carvalho Chehab struct video_device *vfd = video_devdata(file); 21385bc3cb74SMauro Carvalho Chehab struct v4l2_ext_controls *p = arg; 21395bc3cb74SMauro Carvalho Chehab struct v4l2_fh *vfh = 21405bc3cb74SMauro Carvalho Chehab test_bit(V4L2_FL_USES_V4L2_FH, &vfd->flags) ? fh : NULL; 21415bc3cb74SMauro Carvalho Chehab 21425bc3cb74SMauro Carvalho Chehab p->error_idx = p->count; 21435bc3cb74SMauro Carvalho Chehab if (vfh && vfh->ctrl_handler) 2144c41e9cffSHans Verkuil return v4l2_s_ext_ctrls(vfh, vfh->ctrl_handler, vfd->v4l2_dev->mdev, p); 21455bc3cb74SMauro Carvalho Chehab if (vfd->ctrl_handler) 2146c41e9cffSHans Verkuil return v4l2_s_ext_ctrls(NULL, vfd->ctrl_handler, vfd->v4l2_dev->mdev, p); 21475bc3cb74SMauro Carvalho Chehab if (ops->vidioc_s_ext_ctrls == NULL) 21485bc3cb74SMauro Carvalho Chehab return -ENOTTY; 21495bc3cb74SMauro Carvalho Chehab return check_ext_ctrls(p, 0) ? ops->vidioc_s_ext_ctrls(file, fh, p) : 21505bc3cb74SMauro Carvalho Chehab -EINVAL; 21515bc3cb74SMauro Carvalho Chehab } 21525bc3cb74SMauro Carvalho Chehab 21535bc3cb74SMauro Carvalho Chehab static int v4l_try_ext_ctrls(const struct v4l2_ioctl_ops *ops, 21545bc3cb74SMauro Carvalho Chehab struct file *file, void *fh, void *arg) 21555bc3cb74SMauro Carvalho Chehab { 21565bc3cb74SMauro Carvalho Chehab struct video_device *vfd = video_devdata(file); 21575bc3cb74SMauro Carvalho Chehab struct v4l2_ext_controls *p = arg; 21585bc3cb74SMauro Carvalho Chehab struct v4l2_fh *vfh = 21595bc3cb74SMauro Carvalho Chehab test_bit(V4L2_FL_USES_V4L2_FH, &vfd->flags) ? fh : NULL; 21605bc3cb74SMauro Carvalho Chehab 21615bc3cb74SMauro Carvalho Chehab p->error_idx = p->count; 21625bc3cb74SMauro Carvalho Chehab if (vfh && vfh->ctrl_handler) 2163c41e9cffSHans Verkuil return v4l2_try_ext_ctrls(vfh->ctrl_handler, vfd->v4l2_dev->mdev, p); 21645bc3cb74SMauro Carvalho Chehab if (vfd->ctrl_handler) 2165c41e9cffSHans Verkuil return v4l2_try_ext_ctrls(vfd->ctrl_handler, vfd->v4l2_dev->mdev, p); 21665bc3cb74SMauro Carvalho Chehab if (ops->vidioc_try_ext_ctrls == NULL) 21675bc3cb74SMauro Carvalho Chehab return -ENOTTY; 21685bc3cb74SMauro Carvalho Chehab return check_ext_ctrls(p, 0) ? ops->vidioc_try_ext_ctrls(file, fh, p) : 21695bc3cb74SMauro Carvalho Chehab -EINVAL; 21705bc3cb74SMauro Carvalho Chehab } 21715bc3cb74SMauro Carvalho Chehab 2172eaec420fSHans Verkuil /* 2173eaec420fSHans Verkuil * The selection API specified originally that the _MPLANE buffer types 2174eaec420fSHans Verkuil * shouldn't be used. The reasons for this are lost in the mists of time 2175eaec420fSHans Verkuil * (or just really crappy memories). Regardless, this is really annoying 2176eaec420fSHans Verkuil * for userspace. So to keep things simple we map _MPLANE buffer types 2177eaec420fSHans Verkuil * to their 'regular' counterparts before calling the driver. And we 2178eaec420fSHans Verkuil * restore it afterwards. This way applications can use either buffer 2179eaec420fSHans Verkuil * type and drivers don't need to check for both. 2180eaec420fSHans Verkuil */ 2181eaec420fSHans Verkuil static int v4l_g_selection(const struct v4l2_ioctl_ops *ops, 2182eaec420fSHans Verkuil struct file *file, void *fh, void *arg) 2183eaec420fSHans Verkuil { 2184eaec420fSHans Verkuil struct v4l2_selection *p = arg; 2185eaec420fSHans Verkuil u32 old_type = p->type; 2186eaec420fSHans Verkuil int ret; 2187eaec420fSHans Verkuil 2188eaec420fSHans Verkuil if (p->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) 2189eaec420fSHans Verkuil p->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 2190eaec420fSHans Verkuil else if (p->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) 2191eaec420fSHans Verkuil p->type = V4L2_BUF_TYPE_VIDEO_OUTPUT; 2192eaec420fSHans Verkuil ret = ops->vidioc_g_selection(file, fh, p); 2193eaec420fSHans Verkuil p->type = old_type; 2194eaec420fSHans Verkuil return ret; 2195eaec420fSHans Verkuil } 2196eaec420fSHans Verkuil 2197eaec420fSHans Verkuil static int v4l_s_selection(const struct v4l2_ioctl_ops *ops, 2198eaec420fSHans Verkuil struct file *file, void *fh, void *arg) 2199eaec420fSHans Verkuil { 2200eaec420fSHans Verkuil struct v4l2_selection *p = arg; 2201eaec420fSHans Verkuil u32 old_type = p->type; 2202eaec420fSHans Verkuil int ret; 2203eaec420fSHans Verkuil 2204eaec420fSHans Verkuil if (p->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) 2205eaec420fSHans Verkuil p->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 2206eaec420fSHans Verkuil else if (p->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) 2207eaec420fSHans Verkuil p->type = V4L2_BUF_TYPE_VIDEO_OUTPUT; 2208eaec420fSHans Verkuil ret = ops->vidioc_s_selection(file, fh, p); 2209eaec420fSHans Verkuil p->type = old_type; 2210eaec420fSHans Verkuil return ret; 2211eaec420fSHans Verkuil } 2212eaec420fSHans Verkuil 22135bc3cb74SMauro Carvalho Chehab static int v4l_g_crop(const struct v4l2_ioctl_ops *ops, 22145bc3cb74SMauro Carvalho Chehab struct file *file, void *fh, void *arg) 22155bc3cb74SMauro Carvalho Chehab { 22168cbd94bdSHans Verkuil struct video_device *vfd = video_devdata(file); 22175bc3cb74SMauro Carvalho Chehab struct v4l2_crop *p = arg; 22185bc3cb74SMauro Carvalho Chehab struct v4l2_selection s = { 22195bc3cb74SMauro Carvalho Chehab .type = p->type, 22205bc3cb74SMauro Carvalho Chehab }; 22215bc3cb74SMauro Carvalho Chehab int ret; 22225bc3cb74SMauro Carvalho Chehab 22235bc3cb74SMauro Carvalho Chehab /* simulate capture crop using selection api */ 22245bc3cb74SMauro Carvalho Chehab 22255bc3cb74SMauro Carvalho Chehab /* crop means compose for output devices */ 22265bc3cb74SMauro Carvalho Chehab if (V4L2_TYPE_IS_OUTPUT(p->type)) 22275b79da06SHans Verkuil s.target = V4L2_SEL_TGT_COMPOSE; 22285bc3cb74SMauro Carvalho Chehab else 22295b79da06SHans Verkuil s.target = V4L2_SEL_TGT_CROP; 22305bc3cb74SMauro Carvalho Chehab 22318cbd94bdSHans Verkuil if (test_bit(V4L2_FL_QUIRK_INVERTED_CROP, &vfd->flags)) 22328cbd94bdSHans Verkuil s.target = s.target == V4L2_SEL_TGT_COMPOSE ? 22338cbd94bdSHans Verkuil V4L2_SEL_TGT_CROP : V4L2_SEL_TGT_COMPOSE; 22348cbd94bdSHans Verkuil 2235eaec420fSHans Verkuil ret = v4l_g_selection(ops, file, fh, &s); 22365bc3cb74SMauro Carvalho Chehab 22375bc3cb74SMauro Carvalho Chehab /* copying results to old structure on success */ 22385bc3cb74SMauro Carvalho Chehab if (!ret) 22395bc3cb74SMauro Carvalho Chehab p->c = s.r; 22405bc3cb74SMauro Carvalho Chehab return ret; 22415bc3cb74SMauro Carvalho Chehab } 22425bc3cb74SMauro Carvalho Chehab 22435bc3cb74SMauro Carvalho Chehab static int v4l_s_crop(const struct v4l2_ioctl_ops *ops, 22445bc3cb74SMauro Carvalho Chehab struct file *file, void *fh, void *arg) 22455bc3cb74SMauro Carvalho Chehab { 22468cbd94bdSHans Verkuil struct video_device *vfd = video_devdata(file); 22475bc3cb74SMauro Carvalho Chehab struct v4l2_crop *p = arg; 22485bc3cb74SMauro Carvalho Chehab struct v4l2_selection s = { 22495bc3cb74SMauro Carvalho Chehab .type = p->type, 22505bc3cb74SMauro Carvalho Chehab .r = p->c, 22515bc3cb74SMauro Carvalho Chehab }; 22525bc3cb74SMauro Carvalho Chehab 22535bc3cb74SMauro Carvalho Chehab /* simulate capture crop using selection api */ 22545bc3cb74SMauro Carvalho Chehab 22555bc3cb74SMauro Carvalho Chehab /* crop means compose for output devices */ 22565bc3cb74SMauro Carvalho Chehab if (V4L2_TYPE_IS_OUTPUT(p->type)) 22575b79da06SHans Verkuil s.target = V4L2_SEL_TGT_COMPOSE; 22585bc3cb74SMauro Carvalho Chehab else 22595b79da06SHans Verkuil s.target = V4L2_SEL_TGT_CROP; 22605bc3cb74SMauro Carvalho Chehab 22618cbd94bdSHans Verkuil if (test_bit(V4L2_FL_QUIRK_INVERTED_CROP, &vfd->flags)) 22628cbd94bdSHans Verkuil s.target = s.target == V4L2_SEL_TGT_COMPOSE ? 22638cbd94bdSHans Verkuil V4L2_SEL_TGT_CROP : V4L2_SEL_TGT_COMPOSE; 22648cbd94bdSHans Verkuil 2265eaec420fSHans Verkuil return v4l_s_selection(ops, file, fh, &s); 22665bc3cb74SMauro Carvalho Chehab } 22675bc3cb74SMauro Carvalho Chehab 22685bc3cb74SMauro Carvalho Chehab static int v4l_cropcap(const struct v4l2_ioctl_ops *ops, 22695bc3cb74SMauro Carvalho Chehab struct file *file, void *fh, void *arg) 22705bc3cb74SMauro Carvalho Chehab { 22718cbd94bdSHans Verkuil struct video_device *vfd = video_devdata(file); 22725bc3cb74SMauro Carvalho Chehab struct v4l2_cropcap *p = arg; 22735bc3cb74SMauro Carvalho Chehab struct v4l2_selection s = { .type = p->type }; 227495dd7b7eSHans Verkuil int ret = 0; 227595dd7b7eSHans Verkuil 227695dd7b7eSHans Verkuil /* setting trivial pixelaspect */ 227795dd7b7eSHans Verkuil p->pixelaspect.numerator = 1; 227895dd7b7eSHans Verkuil p->pixelaspect.denominator = 1; 227995dd7b7eSHans Verkuil 22805200ab6aSHans Verkuil if (s.type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) 22815200ab6aSHans Verkuil s.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 22825200ab6aSHans Verkuil else if (s.type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) 22835200ab6aSHans Verkuil s.type = V4L2_BUF_TYPE_VIDEO_OUTPUT; 22845200ab6aSHans Verkuil 228595dd7b7eSHans Verkuil /* 228695dd7b7eSHans Verkuil * The determine_valid_ioctls() call already should ensure 228795dd7b7eSHans Verkuil * that this can never happen, but just in case... 228895dd7b7eSHans Verkuil */ 22895200ab6aSHans Verkuil if (WARN_ON(!ops->vidioc_g_selection)) 229095dd7b7eSHans Verkuil return -ENOTTY; 229195dd7b7eSHans Verkuil 22925200ab6aSHans Verkuil if (ops->vidioc_g_pixelaspect) 22935200ab6aSHans Verkuil ret = ops->vidioc_g_pixelaspect(file, fh, s.type, 22945200ab6aSHans Verkuil &p->pixelaspect); 229595dd7b7eSHans Verkuil 229695dd7b7eSHans Verkuil /* 229795dd7b7eSHans Verkuil * Ignore ENOTTY or ENOIOCTLCMD error returns, just use the 229895dd7b7eSHans Verkuil * square pixel aspect ratio in that case. 229995dd7b7eSHans Verkuil */ 230095dd7b7eSHans Verkuil if (ret && ret != -ENOTTY && ret != -ENOIOCTLCMD) 230195dd7b7eSHans Verkuil return ret; 230295dd7b7eSHans Verkuil 230395dd7b7eSHans Verkuil /* Use g_selection() to fill in the bounds and defrect rectangles */ 23045bc3cb74SMauro Carvalho Chehab 23055bc3cb74SMauro Carvalho Chehab /* obtaining bounds */ 23065bc3cb74SMauro Carvalho Chehab if (V4L2_TYPE_IS_OUTPUT(p->type)) 23075bc3cb74SMauro Carvalho Chehab s.target = V4L2_SEL_TGT_COMPOSE_BOUNDS; 23085bc3cb74SMauro Carvalho Chehab else 23095bc3cb74SMauro Carvalho Chehab s.target = V4L2_SEL_TGT_CROP_BOUNDS; 23105bc3cb74SMauro Carvalho Chehab 23118cbd94bdSHans Verkuil if (test_bit(V4L2_FL_QUIRK_INVERTED_CROP, &vfd->flags)) 23128cbd94bdSHans Verkuil s.target = s.target == V4L2_SEL_TGT_COMPOSE_BOUNDS ? 23138cbd94bdSHans Verkuil V4L2_SEL_TGT_CROP_BOUNDS : V4L2_SEL_TGT_COMPOSE_BOUNDS; 23148cbd94bdSHans Verkuil 2315eaec420fSHans Verkuil ret = v4l_g_selection(ops, file, fh, &s); 23165bc3cb74SMauro Carvalho Chehab if (ret) 23175bc3cb74SMauro Carvalho Chehab return ret; 23185bc3cb74SMauro Carvalho Chehab p->bounds = s.r; 23195bc3cb74SMauro Carvalho Chehab 23205bc3cb74SMauro Carvalho Chehab /* obtaining defrect */ 23218cbd94bdSHans Verkuil if (s.target == V4L2_SEL_TGT_COMPOSE_BOUNDS) 23225bc3cb74SMauro Carvalho Chehab s.target = V4L2_SEL_TGT_COMPOSE_DEFAULT; 23235bc3cb74SMauro Carvalho Chehab else 23245bc3cb74SMauro Carvalho Chehab s.target = V4L2_SEL_TGT_CROP_DEFAULT; 23255bc3cb74SMauro Carvalho Chehab 2326eaec420fSHans Verkuil ret = v4l_g_selection(ops, file, fh, &s); 23275bc3cb74SMauro Carvalho Chehab if (ret) 23285bc3cb74SMauro Carvalho Chehab return ret; 23295bc3cb74SMauro Carvalho Chehab p->defrect = s.r; 23309409945cSHans Verkuil 23315bc3cb74SMauro Carvalho Chehab return 0; 23325bc3cb74SMauro Carvalho Chehab } 23335bc3cb74SMauro Carvalho Chehab 23345bc3cb74SMauro Carvalho Chehab static int v4l_log_status(const struct v4l2_ioctl_ops *ops, 23355bc3cb74SMauro Carvalho Chehab struct file *file, void *fh, void *arg) 23365bc3cb74SMauro Carvalho Chehab { 23375bc3cb74SMauro Carvalho Chehab struct video_device *vfd = video_devdata(file); 23385bc3cb74SMauro Carvalho Chehab int ret; 23395bc3cb74SMauro Carvalho Chehab 23405bc3cb74SMauro Carvalho Chehab if (vfd->v4l2_dev) 23415bc3cb74SMauro Carvalho Chehab pr_info("%s: ================= START STATUS =================\n", 23425bc3cb74SMauro Carvalho Chehab vfd->v4l2_dev->name); 23435bc3cb74SMauro Carvalho Chehab ret = ops->vidioc_log_status(file, fh); 23445bc3cb74SMauro Carvalho Chehab if (vfd->v4l2_dev) 23455bc3cb74SMauro Carvalho Chehab pr_info("%s: ================== END STATUS ==================\n", 23465bc3cb74SMauro Carvalho Chehab vfd->v4l2_dev->name); 23475bc3cb74SMauro Carvalho Chehab return ret; 23485bc3cb74SMauro Carvalho Chehab } 23495bc3cb74SMauro Carvalho Chehab 23505bc3cb74SMauro Carvalho Chehab static int v4l_dbg_g_register(const struct v4l2_ioctl_ops *ops, 23515bc3cb74SMauro Carvalho Chehab struct file *file, void *fh, void *arg) 23525bc3cb74SMauro Carvalho Chehab { 23535bc3cb74SMauro Carvalho Chehab #ifdef CONFIG_VIDEO_ADV_DEBUG 23545bc3cb74SMauro Carvalho Chehab struct v4l2_dbg_register *p = arg; 235579b0c640SHans Verkuil struct video_device *vfd = video_devdata(file); 235679b0c640SHans Verkuil struct v4l2_subdev *sd; 235779b0c640SHans Verkuil int idx = 0; 23585bc3cb74SMauro Carvalho Chehab 23595bc3cb74SMauro Carvalho Chehab if (!capable(CAP_SYS_ADMIN)) 23605bc3cb74SMauro Carvalho Chehab return -EPERM; 23613eef2510SHans Verkuil if (p->match.type == V4L2_CHIP_MATCH_SUBDEV) { 236279b0c640SHans Verkuil if (vfd->v4l2_dev == NULL) 236379b0c640SHans Verkuil return -EINVAL; 23643eef2510SHans Verkuil v4l2_device_for_each_subdev(sd, vfd->v4l2_dev) 23653eef2510SHans Verkuil if (p->match.addr == idx++) 236679b0c640SHans Verkuil return v4l2_subdev_call(sd, core, g_register, p); 236779b0c640SHans Verkuil return -EINVAL; 236879b0c640SHans Verkuil } 2369191b79b0SHans Verkuil if (ops->vidioc_g_register && p->match.type == V4L2_CHIP_MATCH_BRIDGE && 2370191b79b0SHans Verkuil (ops->vidioc_g_chip_info || p->match.addr == 0)) 23715bc3cb74SMauro Carvalho Chehab return ops->vidioc_g_register(file, fh, p); 237279b0c640SHans Verkuil return -EINVAL; 23735bc3cb74SMauro Carvalho Chehab #else 23745bc3cb74SMauro Carvalho Chehab return -ENOTTY; 23755bc3cb74SMauro Carvalho Chehab #endif 23765bc3cb74SMauro Carvalho Chehab } 23775bc3cb74SMauro Carvalho Chehab 23785bc3cb74SMauro Carvalho Chehab static int v4l_dbg_s_register(const struct v4l2_ioctl_ops *ops, 23795bc3cb74SMauro Carvalho Chehab struct file *file, void *fh, void *arg) 23805bc3cb74SMauro Carvalho Chehab { 23815bc3cb74SMauro Carvalho Chehab #ifdef CONFIG_VIDEO_ADV_DEBUG 2382977ba3b1SHans Verkuil const struct v4l2_dbg_register *p = arg; 238379b0c640SHans Verkuil struct video_device *vfd = video_devdata(file); 238479b0c640SHans Verkuil struct v4l2_subdev *sd; 238579b0c640SHans Verkuil int idx = 0; 23865bc3cb74SMauro Carvalho Chehab 23875bc3cb74SMauro Carvalho Chehab if (!capable(CAP_SYS_ADMIN)) 23885bc3cb74SMauro Carvalho Chehab return -EPERM; 23893eef2510SHans Verkuil if (p->match.type == V4L2_CHIP_MATCH_SUBDEV) { 239079b0c640SHans Verkuil if (vfd->v4l2_dev == NULL) 239179b0c640SHans Verkuil return -EINVAL; 23923eef2510SHans Verkuil v4l2_device_for_each_subdev(sd, vfd->v4l2_dev) 23933eef2510SHans Verkuil if (p->match.addr == idx++) 239479b0c640SHans Verkuil return v4l2_subdev_call(sd, core, s_register, p); 239579b0c640SHans Verkuil return -EINVAL; 239679b0c640SHans Verkuil } 2397191b79b0SHans Verkuil if (ops->vidioc_s_register && p->match.type == V4L2_CHIP_MATCH_BRIDGE && 2398191b79b0SHans Verkuil (ops->vidioc_g_chip_info || p->match.addr == 0)) 23995bc3cb74SMauro Carvalho Chehab return ops->vidioc_s_register(file, fh, p); 240079b0c640SHans Verkuil return -EINVAL; 24015bc3cb74SMauro Carvalho Chehab #else 24025bc3cb74SMauro Carvalho Chehab return -ENOTTY; 24035bc3cb74SMauro Carvalho Chehab #endif 24045bc3cb74SMauro Carvalho Chehab } 24055bc3cb74SMauro Carvalho Chehab 240696b03d2aSHans Verkuil static int v4l_dbg_g_chip_info(const struct v4l2_ioctl_ops *ops, 240779b0c640SHans Verkuil struct file *file, void *fh, void *arg) 240879b0c640SHans Verkuil { 2409cd634f1bSHans Verkuil #ifdef CONFIG_VIDEO_ADV_DEBUG 241079b0c640SHans Verkuil struct video_device *vfd = video_devdata(file); 241196b03d2aSHans Verkuil struct v4l2_dbg_chip_info *p = arg; 241279b0c640SHans Verkuil struct v4l2_subdev *sd; 241379b0c640SHans Verkuil int idx = 0; 241479b0c640SHans Verkuil 241579b0c640SHans Verkuil switch (p->match.type) { 241679b0c640SHans Verkuil case V4L2_CHIP_MATCH_BRIDGE: 241779b0c640SHans Verkuil if (ops->vidioc_s_register) 241879b0c640SHans Verkuil p->flags |= V4L2_CHIP_FL_WRITABLE; 241979b0c640SHans Verkuil if (ops->vidioc_g_register) 242079b0c640SHans Verkuil p->flags |= V4L2_CHIP_FL_READABLE; 2421c0decac1SMauro Carvalho Chehab strscpy(p->name, vfd->v4l2_dev->name, sizeof(p->name)); 242296b03d2aSHans Verkuil if (ops->vidioc_g_chip_info) 242396b03d2aSHans Verkuil return ops->vidioc_g_chip_info(file, fh, arg); 24240f0fe4b9SHans Verkuil if (p->match.addr) 24250f0fe4b9SHans Verkuil return -EINVAL; 242679b0c640SHans Verkuil return 0; 242779b0c640SHans Verkuil 24283eef2510SHans Verkuil case V4L2_CHIP_MATCH_SUBDEV: 242979b0c640SHans Verkuil if (vfd->v4l2_dev == NULL) 243079b0c640SHans Verkuil break; 243179b0c640SHans Verkuil v4l2_device_for_each_subdev(sd, vfd->v4l2_dev) { 24323eef2510SHans Verkuil if (p->match.addr != idx++) 24333eef2510SHans Verkuil continue; 243479b0c640SHans Verkuil if (sd->ops->core && sd->ops->core->s_register) 243579b0c640SHans Verkuil p->flags |= V4L2_CHIP_FL_WRITABLE; 243679b0c640SHans Verkuil if (sd->ops->core && sd->ops->core->g_register) 243779b0c640SHans Verkuil p->flags |= V4L2_CHIP_FL_READABLE; 2438c0decac1SMauro Carvalho Chehab strscpy(p->name, sd->name, sizeof(p->name)); 243979b0c640SHans Verkuil return 0; 244079b0c640SHans Verkuil } 244179b0c640SHans Verkuil break; 244279b0c640SHans Verkuil } 244379b0c640SHans Verkuil return -EINVAL; 2444cd634f1bSHans Verkuil #else 2445cd634f1bSHans Verkuil return -ENOTTY; 2446cd634f1bSHans Verkuil #endif 244779b0c640SHans Verkuil } 244879b0c640SHans Verkuil 24495bc3cb74SMauro Carvalho Chehab static int v4l_dqevent(const struct v4l2_ioctl_ops *ops, 24505bc3cb74SMauro Carvalho Chehab struct file *file, void *fh, void *arg) 24515bc3cb74SMauro Carvalho Chehab { 24525bc3cb74SMauro Carvalho Chehab return v4l2_event_dequeue(fh, arg, file->f_flags & O_NONBLOCK); 24535bc3cb74SMauro Carvalho Chehab } 24545bc3cb74SMauro Carvalho Chehab 24555bc3cb74SMauro Carvalho Chehab static int v4l_subscribe_event(const struct v4l2_ioctl_ops *ops, 24565bc3cb74SMauro Carvalho Chehab struct file *file, void *fh, void *arg) 24575bc3cb74SMauro Carvalho Chehab { 24585bc3cb74SMauro Carvalho Chehab return ops->vidioc_subscribe_event(fh, arg); 24595bc3cb74SMauro Carvalho Chehab } 24605bc3cb74SMauro Carvalho Chehab 24615bc3cb74SMauro Carvalho Chehab static int v4l_unsubscribe_event(const struct v4l2_ioctl_ops *ops, 24625bc3cb74SMauro Carvalho Chehab struct file *file, void *fh, void *arg) 24635bc3cb74SMauro Carvalho Chehab { 24645bc3cb74SMauro Carvalho Chehab return ops->vidioc_unsubscribe_event(fh, arg); 24655bc3cb74SMauro Carvalho Chehab } 24665bc3cb74SMauro Carvalho Chehab 24675bc3cb74SMauro Carvalho Chehab static int v4l_g_sliced_vbi_cap(const struct v4l2_ioctl_ops *ops, 24685bc3cb74SMauro Carvalho Chehab struct file *file, void *fh, void *arg) 24695bc3cb74SMauro Carvalho Chehab { 24705bc3cb74SMauro Carvalho Chehab struct v4l2_sliced_vbi_cap *p = arg; 24714b20259fSHans Verkuil int ret = check_fmt(file, p->type); 24724b20259fSHans Verkuil 24734b20259fSHans Verkuil if (ret) 24744b20259fSHans Verkuil return ret; 24755bc3cb74SMauro Carvalho Chehab 24765bc3cb74SMauro Carvalho Chehab /* Clear up to type, everything after type is zeroed already */ 24775bc3cb74SMauro Carvalho Chehab memset(p, 0, offsetof(struct v4l2_sliced_vbi_cap, type)); 24785bc3cb74SMauro Carvalho Chehab 24795bc3cb74SMauro Carvalho Chehab return ops->vidioc_g_sliced_vbi_cap(file, fh, p); 24805bc3cb74SMauro Carvalho Chehab } 24815bc3cb74SMauro Carvalho Chehab 24825bc3cb74SMauro Carvalho Chehab static int v4l_enum_freq_bands(const struct v4l2_ioctl_ops *ops, 24835bc3cb74SMauro Carvalho Chehab struct file *file, void *fh, void *arg) 24845bc3cb74SMauro Carvalho Chehab { 24855bc3cb74SMauro Carvalho Chehab struct video_device *vfd = video_devdata(file); 24865bc3cb74SMauro Carvalho Chehab struct v4l2_frequency_band *p = arg; 24875bc3cb74SMauro Carvalho Chehab enum v4l2_tuner_type type; 24885bc3cb74SMauro Carvalho Chehab int err; 24895bc3cb74SMauro Carvalho Chehab 249084099a28SAntti Palosaari if (vfd->vfl_type == VFL_TYPE_SDR) { 2491f3c3ececSAntti Palosaari if (p->type != V4L2_TUNER_SDR && p->type != V4L2_TUNER_RF) 249284099a28SAntti Palosaari return -EINVAL; 249384099a28SAntti Palosaari type = p->type; 249484099a28SAntti Palosaari } else { 24955bc3cb74SMauro Carvalho Chehab type = (vfd->vfl_type == VFL_TYPE_RADIO) ? 24965bc3cb74SMauro Carvalho Chehab V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV; 24975bc3cb74SMauro Carvalho Chehab if (type != p->type) 24985bc3cb74SMauro Carvalho Chehab return -EINVAL; 249984099a28SAntti Palosaari } 2500a7f404afSHans Verkuil if (ops->vidioc_enum_freq_bands) { 2501a7f404afSHans Verkuil err = ops->vidioc_enum_freq_bands(file, fh, p); 2502a7f404afSHans Verkuil if (err != -ENOTTY) 2503a7f404afSHans Verkuil return err; 2504a7f404afSHans Verkuil } 250573f35418SHans Verkuil if (is_valid_ioctl(vfd, VIDIOC_G_TUNER)) { 25065bc3cb74SMauro Carvalho Chehab struct v4l2_tuner t = { 25075bc3cb74SMauro Carvalho Chehab .index = p->tuner, 25085bc3cb74SMauro Carvalho Chehab .type = type, 25095bc3cb74SMauro Carvalho Chehab }; 25105bc3cb74SMauro Carvalho Chehab 251179e8c7beSMauro Carvalho Chehab if (p->index) 251279e8c7beSMauro Carvalho Chehab return -EINVAL; 25135bc3cb74SMauro Carvalho Chehab err = ops->vidioc_g_tuner(file, fh, &t); 25145bc3cb74SMauro Carvalho Chehab if (err) 25155bc3cb74SMauro Carvalho Chehab return err; 25165bc3cb74SMauro Carvalho Chehab p->capability = t.capability | V4L2_TUNER_CAP_FREQ_BANDS; 25175bc3cb74SMauro Carvalho Chehab p->rangelow = t.rangelow; 25185bc3cb74SMauro Carvalho Chehab p->rangehigh = t.rangehigh; 25195bc3cb74SMauro Carvalho Chehab p->modulation = (type == V4L2_TUNER_RADIO) ? 25205bc3cb74SMauro Carvalho Chehab V4L2_BAND_MODULATION_FM : V4L2_BAND_MODULATION_VSB; 25215bc3cb74SMauro Carvalho Chehab return 0; 25225bc3cb74SMauro Carvalho Chehab } 252373f35418SHans Verkuil if (is_valid_ioctl(vfd, VIDIOC_G_MODULATOR)) { 25245bc3cb74SMauro Carvalho Chehab struct v4l2_modulator m = { 25255bc3cb74SMauro Carvalho Chehab .index = p->tuner, 25265bc3cb74SMauro Carvalho Chehab }; 25275bc3cb74SMauro Carvalho Chehab 25285bc3cb74SMauro Carvalho Chehab if (type != V4L2_TUNER_RADIO) 25295bc3cb74SMauro Carvalho Chehab return -EINVAL; 253079e8c7beSMauro Carvalho Chehab if (p->index) 253179e8c7beSMauro Carvalho Chehab return -EINVAL; 25325bc3cb74SMauro Carvalho Chehab err = ops->vidioc_g_modulator(file, fh, &m); 25335bc3cb74SMauro Carvalho Chehab if (err) 25345bc3cb74SMauro Carvalho Chehab return err; 25355bc3cb74SMauro Carvalho Chehab p->capability = m.capability | V4L2_TUNER_CAP_FREQ_BANDS; 25365bc3cb74SMauro Carvalho Chehab p->rangelow = m.rangelow; 25375bc3cb74SMauro Carvalho Chehab p->rangehigh = m.rangehigh; 25385bc3cb74SMauro Carvalho Chehab p->modulation = (type == V4L2_TUNER_RADIO) ? 25395bc3cb74SMauro Carvalho Chehab V4L2_BAND_MODULATION_FM : V4L2_BAND_MODULATION_VSB; 25405bc3cb74SMauro Carvalho Chehab return 0; 25415bc3cb74SMauro Carvalho Chehab } 25425bc3cb74SMauro Carvalho Chehab return -ENOTTY; 25435bc3cb74SMauro Carvalho Chehab } 25445bc3cb74SMauro Carvalho Chehab 25455bc3cb74SMauro Carvalho Chehab struct v4l2_ioctl_info { 25465bc3cb74SMauro Carvalho Chehab unsigned int ioctl; 25475bc3cb74SMauro Carvalho Chehab u32 flags; 25485bc3cb74SMauro Carvalho Chehab const char * const name; 25493ad3b7a2SSami Tolvanen int (*func)(const struct v4l2_ioctl_ops *ops, struct file *file, 25503ad3b7a2SSami Tolvanen void *fh, void *p); 25515bc3cb74SMauro Carvalho Chehab void (*debug)(const void *arg, bool write_only); 25525bc3cb74SMauro Carvalho Chehab }; 25535bc3cb74SMauro Carvalho Chehab 25545bc3cb74SMauro Carvalho Chehab /* This control needs a priority check */ 25555bc3cb74SMauro Carvalho Chehab #define INFO_FL_PRIO (1 << 0) 25565bc3cb74SMauro Carvalho Chehab /* This control can be valid if the filehandle passes a control handler. */ 25575bc3cb74SMauro Carvalho Chehab #define INFO_FL_CTRL (1 << 1) 25585bc3cb74SMauro Carvalho Chehab /* Queuing ioctl */ 25593ad3b7a2SSami Tolvanen #define INFO_FL_QUEUE (1 << 2) 2560043f77edSHans Verkuil /* Always copy back result, even on error */ 25613ad3b7a2SSami Tolvanen #define INFO_FL_ALWAYS_COPY (1 << 3) 25625bc3cb74SMauro Carvalho Chehab /* Zero struct from after the field to the end */ 25635bc3cb74SMauro Carvalho Chehab #define INFO_FL_CLEAR(v4l2_struct, field) \ 25645bc3cb74SMauro Carvalho Chehab ((offsetof(struct v4l2_struct, field) + \ 25655bc3cb74SMauro Carvalho Chehab sizeof(((struct v4l2_struct *)0)->field)) << 16) 25665bc3cb74SMauro Carvalho Chehab #define INFO_FL_CLEAR_MASK (_IOC_SIZEMASK << 16) 25675bc3cb74SMauro Carvalho Chehab 25683ad3b7a2SSami Tolvanen #define DEFINE_V4L_STUB_FUNC(_vidioc) \ 25693ad3b7a2SSami Tolvanen static int v4l_stub_ ## _vidioc( \ 25703ad3b7a2SSami Tolvanen const struct v4l2_ioctl_ops *ops, \ 25713ad3b7a2SSami Tolvanen struct file *file, void *fh, void *p) \ 25723ad3b7a2SSami Tolvanen { \ 25733ad3b7a2SSami Tolvanen return ops->vidioc_ ## _vidioc(file, fh, p); \ 25743ad3b7a2SSami Tolvanen } 25753ad3b7a2SSami Tolvanen 25763ad3b7a2SSami Tolvanen #define IOCTL_INFO(_ioctl, _func, _debug, _flags) \ 25775bc3cb74SMauro Carvalho Chehab [_IOC_NR(_ioctl)] = { \ 25785bc3cb74SMauro Carvalho Chehab .ioctl = _ioctl, \ 25793ad3b7a2SSami Tolvanen .flags = _flags, \ 25805bc3cb74SMauro Carvalho Chehab .name = #_ioctl, \ 25813ad3b7a2SSami Tolvanen .func = _func, \ 25825bc3cb74SMauro Carvalho Chehab .debug = _debug, \ 25835bc3cb74SMauro Carvalho Chehab } 25845bc3cb74SMauro Carvalho Chehab 25853ad3b7a2SSami Tolvanen DEFINE_V4L_STUB_FUNC(g_fbuf) 25863ad3b7a2SSami Tolvanen DEFINE_V4L_STUB_FUNC(s_fbuf) 25873ad3b7a2SSami Tolvanen DEFINE_V4L_STUB_FUNC(expbuf) 25883ad3b7a2SSami Tolvanen DEFINE_V4L_STUB_FUNC(g_std) 25893ad3b7a2SSami Tolvanen DEFINE_V4L_STUB_FUNC(g_audio) 25903ad3b7a2SSami Tolvanen DEFINE_V4L_STUB_FUNC(s_audio) 25913ad3b7a2SSami Tolvanen DEFINE_V4L_STUB_FUNC(g_input) 25923ad3b7a2SSami Tolvanen DEFINE_V4L_STUB_FUNC(g_edid) 25933ad3b7a2SSami Tolvanen DEFINE_V4L_STUB_FUNC(s_edid) 25943ad3b7a2SSami Tolvanen DEFINE_V4L_STUB_FUNC(g_output) 25953ad3b7a2SSami Tolvanen DEFINE_V4L_STUB_FUNC(g_audout) 25963ad3b7a2SSami Tolvanen DEFINE_V4L_STUB_FUNC(s_audout) 25973ad3b7a2SSami Tolvanen DEFINE_V4L_STUB_FUNC(g_jpegcomp) 25983ad3b7a2SSami Tolvanen DEFINE_V4L_STUB_FUNC(s_jpegcomp) 25993ad3b7a2SSami Tolvanen DEFINE_V4L_STUB_FUNC(enumaudio) 26003ad3b7a2SSami Tolvanen DEFINE_V4L_STUB_FUNC(enumaudout) 26013ad3b7a2SSami Tolvanen DEFINE_V4L_STUB_FUNC(enum_framesizes) 26023ad3b7a2SSami Tolvanen DEFINE_V4L_STUB_FUNC(enum_frameintervals) 26033ad3b7a2SSami Tolvanen DEFINE_V4L_STUB_FUNC(g_enc_index) 26043ad3b7a2SSami Tolvanen DEFINE_V4L_STUB_FUNC(encoder_cmd) 26053ad3b7a2SSami Tolvanen DEFINE_V4L_STUB_FUNC(try_encoder_cmd) 26063ad3b7a2SSami Tolvanen DEFINE_V4L_STUB_FUNC(decoder_cmd) 26073ad3b7a2SSami Tolvanen DEFINE_V4L_STUB_FUNC(try_decoder_cmd) 26083ad3b7a2SSami Tolvanen DEFINE_V4L_STUB_FUNC(s_dv_timings) 26093ad3b7a2SSami Tolvanen DEFINE_V4L_STUB_FUNC(g_dv_timings) 26103ad3b7a2SSami Tolvanen DEFINE_V4L_STUB_FUNC(enum_dv_timings) 26113ad3b7a2SSami Tolvanen DEFINE_V4L_STUB_FUNC(query_dv_timings) 26123ad3b7a2SSami Tolvanen DEFINE_V4L_STUB_FUNC(dv_timings_cap) 26135bc3cb74SMauro Carvalho Chehab 26147c91d0a4SEric Biggers static const struct v4l2_ioctl_info v4l2_ioctls[] = { 26153ad3b7a2SSami Tolvanen IOCTL_INFO(VIDIOC_QUERYCAP, v4l_querycap, v4l_print_querycap, 0), 26163ad3b7a2SSami Tolvanen IOCTL_INFO(VIDIOC_ENUM_FMT, v4l_enum_fmt, v4l_print_fmtdesc, INFO_FL_CLEAR(v4l2_fmtdesc, type)), 26173ad3b7a2SSami Tolvanen IOCTL_INFO(VIDIOC_G_FMT, v4l_g_fmt, v4l_print_format, 0), 26183ad3b7a2SSami Tolvanen IOCTL_INFO(VIDIOC_S_FMT, v4l_s_fmt, v4l_print_format, INFO_FL_PRIO), 26193ad3b7a2SSami Tolvanen IOCTL_INFO(VIDIOC_REQBUFS, v4l_reqbufs, v4l_print_requestbuffers, INFO_FL_PRIO | INFO_FL_QUEUE), 26203ad3b7a2SSami Tolvanen IOCTL_INFO(VIDIOC_QUERYBUF, v4l_querybuf, v4l_print_buffer, INFO_FL_QUEUE | INFO_FL_CLEAR(v4l2_buffer, length)), 26213ad3b7a2SSami Tolvanen IOCTL_INFO(VIDIOC_G_FBUF, v4l_stub_g_fbuf, v4l_print_framebuffer, 0), 26223ad3b7a2SSami Tolvanen IOCTL_INFO(VIDIOC_S_FBUF, v4l_stub_s_fbuf, v4l_print_framebuffer, INFO_FL_PRIO), 26233ad3b7a2SSami Tolvanen IOCTL_INFO(VIDIOC_OVERLAY, v4l_overlay, v4l_print_u32, INFO_FL_PRIO), 26243ad3b7a2SSami Tolvanen IOCTL_INFO(VIDIOC_QBUF, v4l_qbuf, v4l_print_buffer, INFO_FL_QUEUE), 26253ad3b7a2SSami Tolvanen IOCTL_INFO(VIDIOC_EXPBUF, v4l_stub_expbuf, v4l_print_exportbuffer, INFO_FL_QUEUE | INFO_FL_CLEAR(v4l2_exportbuffer, flags)), 26263ad3b7a2SSami Tolvanen IOCTL_INFO(VIDIOC_DQBUF, v4l_dqbuf, v4l_print_buffer, INFO_FL_QUEUE), 26273ad3b7a2SSami Tolvanen IOCTL_INFO(VIDIOC_STREAMON, v4l_streamon, v4l_print_buftype, INFO_FL_PRIO | INFO_FL_QUEUE), 26283ad3b7a2SSami Tolvanen IOCTL_INFO(VIDIOC_STREAMOFF, v4l_streamoff, v4l_print_buftype, INFO_FL_PRIO | INFO_FL_QUEUE), 26293ad3b7a2SSami Tolvanen IOCTL_INFO(VIDIOC_G_PARM, v4l_g_parm, v4l_print_streamparm, INFO_FL_CLEAR(v4l2_streamparm, type)), 26303ad3b7a2SSami Tolvanen IOCTL_INFO(VIDIOC_S_PARM, v4l_s_parm, v4l_print_streamparm, INFO_FL_PRIO), 26313ad3b7a2SSami Tolvanen IOCTL_INFO(VIDIOC_G_STD, v4l_stub_g_std, v4l_print_std, 0), 26323ad3b7a2SSami Tolvanen IOCTL_INFO(VIDIOC_S_STD, v4l_s_std, v4l_print_std, INFO_FL_PRIO), 26333ad3b7a2SSami Tolvanen IOCTL_INFO(VIDIOC_ENUMSTD, v4l_enumstd, v4l_print_standard, INFO_FL_CLEAR(v4l2_standard, index)), 26343ad3b7a2SSami Tolvanen IOCTL_INFO(VIDIOC_ENUMINPUT, v4l_enuminput, v4l_print_enuminput, INFO_FL_CLEAR(v4l2_input, index)), 26353ad3b7a2SSami Tolvanen IOCTL_INFO(VIDIOC_G_CTRL, v4l_g_ctrl, v4l_print_control, INFO_FL_CTRL | INFO_FL_CLEAR(v4l2_control, id)), 26363ad3b7a2SSami Tolvanen IOCTL_INFO(VIDIOC_S_CTRL, v4l_s_ctrl, v4l_print_control, INFO_FL_PRIO | INFO_FL_CTRL), 26373ad3b7a2SSami Tolvanen IOCTL_INFO(VIDIOC_G_TUNER, v4l_g_tuner, v4l_print_tuner, INFO_FL_CLEAR(v4l2_tuner, index)), 26383ad3b7a2SSami Tolvanen IOCTL_INFO(VIDIOC_S_TUNER, v4l_s_tuner, v4l_print_tuner, INFO_FL_PRIO), 26393ad3b7a2SSami Tolvanen IOCTL_INFO(VIDIOC_G_AUDIO, v4l_stub_g_audio, v4l_print_audio, 0), 26403ad3b7a2SSami Tolvanen IOCTL_INFO(VIDIOC_S_AUDIO, v4l_stub_s_audio, v4l_print_audio, INFO_FL_PRIO), 26413ad3b7a2SSami Tolvanen IOCTL_INFO(VIDIOC_QUERYCTRL, v4l_queryctrl, v4l_print_queryctrl, INFO_FL_CTRL | INFO_FL_CLEAR(v4l2_queryctrl, id)), 26423ad3b7a2SSami Tolvanen IOCTL_INFO(VIDIOC_QUERYMENU, v4l_querymenu, v4l_print_querymenu, INFO_FL_CTRL | INFO_FL_CLEAR(v4l2_querymenu, index)), 26433ad3b7a2SSami Tolvanen IOCTL_INFO(VIDIOC_G_INPUT, v4l_stub_g_input, v4l_print_u32, 0), 26443ad3b7a2SSami Tolvanen IOCTL_INFO(VIDIOC_S_INPUT, v4l_s_input, v4l_print_u32, INFO_FL_PRIO), 26453ad3b7a2SSami Tolvanen IOCTL_INFO(VIDIOC_G_EDID, v4l_stub_g_edid, v4l_print_edid, INFO_FL_ALWAYS_COPY), 26463ad3b7a2SSami Tolvanen IOCTL_INFO(VIDIOC_S_EDID, v4l_stub_s_edid, v4l_print_edid, INFO_FL_PRIO | INFO_FL_ALWAYS_COPY), 26473ad3b7a2SSami Tolvanen IOCTL_INFO(VIDIOC_G_OUTPUT, v4l_stub_g_output, v4l_print_u32, 0), 26483ad3b7a2SSami Tolvanen IOCTL_INFO(VIDIOC_S_OUTPUT, v4l_s_output, v4l_print_u32, INFO_FL_PRIO), 26493ad3b7a2SSami Tolvanen IOCTL_INFO(VIDIOC_ENUMOUTPUT, v4l_enumoutput, v4l_print_enumoutput, INFO_FL_CLEAR(v4l2_output, index)), 26503ad3b7a2SSami Tolvanen IOCTL_INFO(VIDIOC_G_AUDOUT, v4l_stub_g_audout, v4l_print_audioout, 0), 26513ad3b7a2SSami Tolvanen IOCTL_INFO(VIDIOC_S_AUDOUT, v4l_stub_s_audout, v4l_print_audioout, INFO_FL_PRIO), 26523ad3b7a2SSami Tolvanen IOCTL_INFO(VIDIOC_G_MODULATOR, v4l_g_modulator, v4l_print_modulator, INFO_FL_CLEAR(v4l2_modulator, index)), 26533ad3b7a2SSami Tolvanen IOCTL_INFO(VIDIOC_S_MODULATOR, v4l_s_modulator, v4l_print_modulator, INFO_FL_PRIO), 26543ad3b7a2SSami Tolvanen IOCTL_INFO(VIDIOC_G_FREQUENCY, v4l_g_frequency, v4l_print_frequency, INFO_FL_CLEAR(v4l2_frequency, tuner)), 26553ad3b7a2SSami Tolvanen IOCTL_INFO(VIDIOC_S_FREQUENCY, v4l_s_frequency, v4l_print_frequency, INFO_FL_PRIO), 26563ad3b7a2SSami Tolvanen IOCTL_INFO(VIDIOC_CROPCAP, v4l_cropcap, v4l_print_cropcap, INFO_FL_CLEAR(v4l2_cropcap, type)), 26573ad3b7a2SSami Tolvanen IOCTL_INFO(VIDIOC_G_CROP, v4l_g_crop, v4l_print_crop, INFO_FL_CLEAR(v4l2_crop, type)), 26583ad3b7a2SSami Tolvanen IOCTL_INFO(VIDIOC_S_CROP, v4l_s_crop, v4l_print_crop, INFO_FL_PRIO), 26593ad3b7a2SSami Tolvanen IOCTL_INFO(VIDIOC_G_SELECTION, v4l_g_selection, v4l_print_selection, INFO_FL_CLEAR(v4l2_selection, r)), 26603ad3b7a2SSami Tolvanen IOCTL_INFO(VIDIOC_S_SELECTION, v4l_s_selection, v4l_print_selection, INFO_FL_PRIO | INFO_FL_CLEAR(v4l2_selection, r)), 26613ad3b7a2SSami Tolvanen IOCTL_INFO(VIDIOC_G_JPEGCOMP, v4l_stub_g_jpegcomp, v4l_print_jpegcompression, 0), 26623ad3b7a2SSami Tolvanen IOCTL_INFO(VIDIOC_S_JPEGCOMP, v4l_stub_s_jpegcomp, v4l_print_jpegcompression, INFO_FL_PRIO), 26633ad3b7a2SSami Tolvanen IOCTL_INFO(VIDIOC_QUERYSTD, v4l_querystd, v4l_print_std, 0), 26643ad3b7a2SSami Tolvanen IOCTL_INFO(VIDIOC_TRY_FMT, v4l_try_fmt, v4l_print_format, 0), 26653ad3b7a2SSami Tolvanen IOCTL_INFO(VIDIOC_ENUMAUDIO, v4l_stub_enumaudio, v4l_print_audio, INFO_FL_CLEAR(v4l2_audio, index)), 26663ad3b7a2SSami Tolvanen IOCTL_INFO(VIDIOC_ENUMAUDOUT, v4l_stub_enumaudout, v4l_print_audioout, INFO_FL_CLEAR(v4l2_audioout, index)), 26673ad3b7a2SSami Tolvanen IOCTL_INFO(VIDIOC_G_PRIORITY, v4l_g_priority, v4l_print_u32, 0), 26683ad3b7a2SSami Tolvanen IOCTL_INFO(VIDIOC_S_PRIORITY, v4l_s_priority, v4l_print_u32, INFO_FL_PRIO), 26693ad3b7a2SSami 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)), 26703ad3b7a2SSami Tolvanen IOCTL_INFO(VIDIOC_LOG_STATUS, v4l_log_status, v4l_print_newline, 0), 26713ad3b7a2SSami Tolvanen IOCTL_INFO(VIDIOC_G_EXT_CTRLS, v4l_g_ext_ctrls, v4l_print_ext_controls, INFO_FL_CTRL), 26723ad3b7a2SSami Tolvanen IOCTL_INFO(VIDIOC_S_EXT_CTRLS, v4l_s_ext_ctrls, v4l_print_ext_controls, INFO_FL_PRIO | INFO_FL_CTRL), 26733ad3b7a2SSami Tolvanen IOCTL_INFO(VIDIOC_TRY_EXT_CTRLS, v4l_try_ext_ctrls, v4l_print_ext_controls, INFO_FL_CTRL), 26743ad3b7a2SSami Tolvanen IOCTL_INFO(VIDIOC_ENUM_FRAMESIZES, v4l_stub_enum_framesizes, v4l_print_frmsizeenum, INFO_FL_CLEAR(v4l2_frmsizeenum, pixel_format)), 26753ad3b7a2SSami Tolvanen IOCTL_INFO(VIDIOC_ENUM_FRAMEINTERVALS, v4l_stub_enum_frameintervals, v4l_print_frmivalenum, INFO_FL_CLEAR(v4l2_frmivalenum, height)), 26763ad3b7a2SSami Tolvanen IOCTL_INFO(VIDIOC_G_ENC_INDEX, v4l_stub_g_enc_index, v4l_print_enc_idx, 0), 26773ad3b7a2SSami Tolvanen IOCTL_INFO(VIDIOC_ENCODER_CMD, v4l_stub_encoder_cmd, v4l_print_encoder_cmd, INFO_FL_PRIO | INFO_FL_CLEAR(v4l2_encoder_cmd, flags)), 26783ad3b7a2SSami Tolvanen IOCTL_INFO(VIDIOC_TRY_ENCODER_CMD, v4l_stub_try_encoder_cmd, v4l_print_encoder_cmd, INFO_FL_CLEAR(v4l2_encoder_cmd, flags)), 26793ad3b7a2SSami Tolvanen IOCTL_INFO(VIDIOC_DECODER_CMD, v4l_stub_decoder_cmd, v4l_print_decoder_cmd, INFO_FL_PRIO), 26803ad3b7a2SSami Tolvanen IOCTL_INFO(VIDIOC_TRY_DECODER_CMD, v4l_stub_try_decoder_cmd, v4l_print_decoder_cmd, 0), 26813ad3b7a2SSami Tolvanen IOCTL_INFO(VIDIOC_DBG_S_REGISTER, v4l_dbg_s_register, v4l_print_dbg_register, 0), 26823ad3b7a2SSami Tolvanen IOCTL_INFO(VIDIOC_DBG_G_REGISTER, v4l_dbg_g_register, v4l_print_dbg_register, 0), 26833ad3b7a2SSami Tolvanen IOCTL_INFO(VIDIOC_S_HW_FREQ_SEEK, v4l_s_hw_freq_seek, v4l_print_hw_freq_seek, INFO_FL_PRIO), 26843ad3b7a2SSami 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)), 26853ad3b7a2SSami Tolvanen IOCTL_INFO(VIDIOC_G_DV_TIMINGS, v4l_stub_g_dv_timings, v4l_print_dv_timings, 0), 26863ad3b7a2SSami Tolvanen IOCTL_INFO(VIDIOC_DQEVENT, v4l_dqevent, v4l_print_event, 0), 26873ad3b7a2SSami Tolvanen IOCTL_INFO(VIDIOC_SUBSCRIBE_EVENT, v4l_subscribe_event, v4l_print_event_subscription, 0), 26883ad3b7a2SSami Tolvanen IOCTL_INFO(VIDIOC_UNSUBSCRIBE_EVENT, v4l_unsubscribe_event, v4l_print_event_subscription, 0), 26893ad3b7a2SSami Tolvanen IOCTL_INFO(VIDIOC_CREATE_BUFS, v4l_create_bufs, v4l_print_create_buffers, INFO_FL_PRIO | INFO_FL_QUEUE), 26903ad3b7a2SSami Tolvanen IOCTL_INFO(VIDIOC_PREPARE_BUF, v4l_prepare_buf, v4l_print_buffer, INFO_FL_QUEUE), 26913ad3b7a2SSami 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)), 26923ad3b7a2SSami Tolvanen IOCTL_INFO(VIDIOC_QUERY_DV_TIMINGS, v4l_stub_query_dv_timings, v4l_print_dv_timings, INFO_FL_ALWAYS_COPY), 26933ad3b7a2SSami 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)), 26943ad3b7a2SSami Tolvanen IOCTL_INFO(VIDIOC_ENUM_FREQ_BANDS, v4l_enum_freq_bands, v4l_print_freq_band, 0), 26953ad3b7a2SSami 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)), 26963ad3b7a2SSami 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)), 26975bc3cb74SMauro Carvalho Chehab }; 26985bc3cb74SMauro Carvalho Chehab #define V4L2_IOCTLS ARRAY_SIZE(v4l2_ioctls) 26995bc3cb74SMauro Carvalho Chehab 270073a11062SHans Verkuil static bool v4l2_is_known_ioctl(unsigned int cmd) 27015bc3cb74SMauro Carvalho Chehab { 27025bc3cb74SMauro Carvalho Chehab if (_IOC_NR(cmd) >= V4L2_IOCTLS) 27035bc3cb74SMauro Carvalho Chehab return false; 27045bc3cb74SMauro Carvalho Chehab return v4l2_ioctls[_IOC_NR(cmd)].ioctl == cmd; 27055bc3cb74SMauro Carvalho Chehab } 27065bc3cb74SMauro Carvalho Chehab 270773a11062SHans Verkuil static struct mutex *v4l2_ioctl_get_lock(struct video_device *vdev, 2708d862bc08SHans Verkuil struct v4l2_fh *vfh, unsigned int cmd, 2709d862bc08SHans Verkuil void *arg) 27105bc3cb74SMauro Carvalho Chehab { 27115bc3cb74SMauro Carvalho Chehab if (_IOC_NR(cmd) >= V4L2_IOCTLS) 27125bc3cb74SMauro Carvalho Chehab return vdev->lock; 2713d862bc08SHans Verkuil #if IS_ENABLED(CONFIG_V4L2_MEM2MEM_DEV) 2714d862bc08SHans Verkuil if (vfh && vfh->m2m_ctx && 2715d862bc08SHans Verkuil (v4l2_ioctls[_IOC_NR(cmd)].flags & INFO_FL_QUEUE)) { 2716542a522dSEzequiel Garcia if (vfh->m2m_ctx->q_lock) 2717542a522dSEzequiel Garcia return vfh->m2m_ctx->q_lock; 2718d862bc08SHans Verkuil } 2719d862bc08SHans Verkuil #endif 27205bc3cb74SMauro Carvalho Chehab if (vdev->queue && vdev->queue->lock && 27215bc3cb74SMauro Carvalho Chehab (v4l2_ioctls[_IOC_NR(cmd)].flags & INFO_FL_QUEUE)) 27225bc3cb74SMauro Carvalho Chehab return vdev->queue->lock; 27235bc3cb74SMauro Carvalho Chehab return vdev->lock; 27245bc3cb74SMauro Carvalho Chehab } 27255bc3cb74SMauro Carvalho Chehab 27265bc3cb74SMauro Carvalho Chehab /* Common ioctl debug function. This function can be used by 27275bc3cb74SMauro Carvalho Chehab external ioctl messages as well as internal V4L ioctl */ 27285bc3cb74SMauro Carvalho Chehab void v4l_printk_ioctl(const char *prefix, unsigned int cmd) 27295bc3cb74SMauro Carvalho Chehab { 27305bc3cb74SMauro Carvalho Chehab const char *dir, *type; 27315bc3cb74SMauro Carvalho Chehab 27325bc3cb74SMauro Carvalho Chehab if (prefix) 27335bc3cb74SMauro Carvalho Chehab printk(KERN_DEBUG "%s: ", prefix); 27345bc3cb74SMauro Carvalho Chehab 27355bc3cb74SMauro Carvalho Chehab switch (_IOC_TYPE(cmd)) { 27365bc3cb74SMauro Carvalho Chehab case 'd': 27375bc3cb74SMauro Carvalho Chehab type = "v4l2_int"; 27385bc3cb74SMauro Carvalho Chehab break; 27395bc3cb74SMauro Carvalho Chehab case 'V': 27405bc3cb74SMauro Carvalho Chehab if (_IOC_NR(cmd) >= V4L2_IOCTLS) { 27415bc3cb74SMauro Carvalho Chehab type = "v4l2"; 27425bc3cb74SMauro Carvalho Chehab break; 27435bc3cb74SMauro Carvalho Chehab } 27445bc3cb74SMauro Carvalho Chehab pr_cont("%s", v4l2_ioctls[_IOC_NR(cmd)].name); 27455bc3cb74SMauro Carvalho Chehab return; 27465bc3cb74SMauro Carvalho Chehab default: 27475bc3cb74SMauro Carvalho Chehab type = "unknown"; 27485bc3cb74SMauro Carvalho Chehab break; 27495bc3cb74SMauro Carvalho Chehab } 27505bc3cb74SMauro Carvalho Chehab 27515bc3cb74SMauro Carvalho Chehab switch (_IOC_DIR(cmd)) { 27525bc3cb74SMauro Carvalho Chehab case _IOC_NONE: dir = "--"; break; 27535bc3cb74SMauro Carvalho Chehab case _IOC_READ: dir = "r-"; break; 27545bc3cb74SMauro Carvalho Chehab case _IOC_WRITE: dir = "-w"; break; 27555bc3cb74SMauro Carvalho Chehab case _IOC_READ | _IOC_WRITE: dir = "rw"; break; 27565bc3cb74SMauro Carvalho Chehab default: dir = "*ERR*"; break; 27575bc3cb74SMauro Carvalho Chehab } 27585bc3cb74SMauro Carvalho Chehab pr_cont("%s ioctl '%c', dir=%s, #%d (0x%08x)", 27595bc3cb74SMauro Carvalho Chehab type, _IOC_TYPE(cmd), dir, _IOC_NR(cmd), cmd); 27605bc3cb74SMauro Carvalho Chehab } 27615bc3cb74SMauro Carvalho Chehab EXPORT_SYMBOL(v4l_printk_ioctl); 27625bc3cb74SMauro Carvalho Chehab 27635bc3cb74SMauro Carvalho Chehab static long __video_do_ioctl(struct file *file, 27645bc3cb74SMauro Carvalho Chehab unsigned int cmd, void *arg) 27655bc3cb74SMauro Carvalho Chehab { 27665bc3cb74SMauro Carvalho Chehab struct video_device *vfd = video_devdata(file); 2767cc6eddcdSHans Verkuil struct mutex *req_queue_lock = NULL; 276873a11062SHans Verkuil struct mutex *lock; /* ioctl serialization mutex */ 27695bc3cb74SMauro Carvalho Chehab const struct v4l2_ioctl_ops *ops = vfd->ioctl_ops; 27705bc3cb74SMauro Carvalho Chehab bool write_only = false; 27715bc3cb74SMauro Carvalho Chehab struct v4l2_ioctl_info default_info; 27725bc3cb74SMauro Carvalho Chehab const struct v4l2_ioctl_info *info; 27735bc3cb74SMauro Carvalho Chehab void *fh = file->private_data; 27745bc3cb74SMauro Carvalho Chehab struct v4l2_fh *vfh = NULL; 277517028cdbSHans Verkuil int dev_debug = vfd->dev_debug; 27765bc3cb74SMauro Carvalho Chehab long ret = -ENOTTY; 27775bc3cb74SMauro Carvalho Chehab 27785bc3cb74SMauro Carvalho Chehab if (ops == NULL) { 27795bc3cb74SMauro Carvalho Chehab pr_warn("%s: has no ioctl_ops.\n", 27805bc3cb74SMauro Carvalho Chehab video_device_node_name(vfd)); 27815bc3cb74SMauro Carvalho Chehab return ret; 27825bc3cb74SMauro Carvalho Chehab } 27835bc3cb74SMauro Carvalho Chehab 2784b7284bb0SRamakrishnan Muthukrishnan if (test_bit(V4L2_FL_USES_V4L2_FH, &vfd->flags)) 27855bc3cb74SMauro Carvalho Chehab vfh = file->private_data; 27865bc3cb74SMauro Carvalho Chehab 2787cc6eddcdSHans Verkuil /* 2788cc6eddcdSHans Verkuil * We need to serialize streamon/off with queueing new requests. 2789cc6eddcdSHans Verkuil * These ioctls may trigger the cancellation of a streaming 2790cc6eddcdSHans Verkuil * operation, and that should not be mixed with queueing a new 2791cc6eddcdSHans Verkuil * request at the same time. 2792cc6eddcdSHans Verkuil */ 2793cc6eddcdSHans Verkuil if (v4l2_device_supports_requests(vfd->v4l2_dev) && 2794cc6eddcdSHans Verkuil (cmd == VIDIOC_STREAMON || cmd == VIDIOC_STREAMOFF)) { 2795cc6eddcdSHans Verkuil req_queue_lock = &vfd->v4l2_dev->mdev->req_queue_mutex; 2796cc6eddcdSHans Verkuil 2797cc6eddcdSHans Verkuil if (mutex_lock_interruptible(req_queue_lock)) 2798cc6eddcdSHans Verkuil return -ERESTARTSYS; 2799cc6eddcdSHans Verkuil } 2800cc6eddcdSHans Verkuil 2801d862bc08SHans Verkuil lock = v4l2_ioctl_get_lock(vfd, vfh, cmd, arg); 280273a11062SHans Verkuil 2803cc6eddcdSHans Verkuil if (lock && mutex_lock_interruptible(lock)) { 2804cc6eddcdSHans Verkuil if (req_queue_lock) 2805cc6eddcdSHans Verkuil mutex_unlock(req_queue_lock); 280673a11062SHans Verkuil return -ERESTARTSYS; 2807cc6eddcdSHans Verkuil } 280873a11062SHans Verkuil 280973a11062SHans Verkuil if (!video_is_registered(vfd)) { 281073a11062SHans Verkuil ret = -ENODEV; 281173a11062SHans Verkuil goto unlock; 281273a11062SHans Verkuil } 281373a11062SHans Verkuil 28145bc3cb74SMauro Carvalho Chehab if (v4l2_is_known_ioctl(cmd)) { 28155bc3cb74SMauro Carvalho Chehab info = &v4l2_ioctls[_IOC_NR(cmd)]; 28165bc3cb74SMauro Carvalho Chehab 28175bc3cb74SMauro Carvalho Chehab if (!test_bit(_IOC_NR(cmd), vfd->valid_ioctls) && 28185bc3cb74SMauro Carvalho Chehab !((info->flags & INFO_FL_CTRL) && vfh && vfh->ctrl_handler)) 28195bc3cb74SMauro Carvalho Chehab goto done; 28205bc3cb74SMauro Carvalho Chehab 2821b7284bb0SRamakrishnan Muthukrishnan if (vfh && (info->flags & INFO_FL_PRIO)) { 28225bc3cb74SMauro Carvalho Chehab ret = v4l2_prio_check(vfd->prio, vfh->prio); 28235bc3cb74SMauro Carvalho Chehab if (ret) 28245bc3cb74SMauro Carvalho Chehab goto done; 28255bc3cb74SMauro Carvalho Chehab } 28265bc3cb74SMauro Carvalho Chehab } else { 28275bc3cb74SMauro Carvalho Chehab default_info.ioctl = cmd; 28285bc3cb74SMauro Carvalho Chehab default_info.flags = 0; 28295bc3cb74SMauro Carvalho Chehab default_info.debug = v4l_print_default; 28305bc3cb74SMauro Carvalho Chehab info = &default_info; 28315bc3cb74SMauro Carvalho Chehab } 28325bc3cb74SMauro Carvalho Chehab 28335bc3cb74SMauro Carvalho Chehab write_only = _IOC_DIR(cmd) == _IOC_WRITE; 28343ad3b7a2SSami Tolvanen if (info != &default_info) { 28353ad3b7a2SSami Tolvanen ret = info->func(ops, file, fh, arg); 28365bc3cb74SMauro Carvalho Chehab } else if (!ops->vidioc_default) { 28375bc3cb74SMauro Carvalho Chehab ret = -ENOTTY; 28385bc3cb74SMauro Carvalho Chehab } else { 28395bc3cb74SMauro Carvalho Chehab ret = ops->vidioc_default(file, fh, 2840b7284bb0SRamakrishnan Muthukrishnan vfh ? v4l2_prio_check(vfd->prio, vfh->prio) >= 0 : 0, 28415bc3cb74SMauro Carvalho Chehab cmd, arg); 28425bc3cb74SMauro Carvalho Chehab } 28435bc3cb74SMauro Carvalho Chehab 28445bc3cb74SMauro Carvalho Chehab done: 284517028cdbSHans Verkuil if (dev_debug & (V4L2_DEV_DEBUG_IOCTL | V4L2_DEV_DEBUG_IOCTL_ARG)) { 284617028cdbSHans Verkuil if (!(dev_debug & V4L2_DEV_DEBUG_STREAMING) && 284717028cdbSHans Verkuil (cmd == VIDIOC_QBUF || cmd == VIDIOC_DQBUF)) 28485983d3bcSHans Verkuil goto unlock; 284917028cdbSHans Verkuil 28505bc3cb74SMauro Carvalho Chehab v4l_printk_ioctl(video_device_node_name(vfd), cmd); 28515bc3cb74SMauro Carvalho Chehab if (ret < 0) 2852505d04bdSHans Verkuil pr_cont(": error %ld", ret); 285317028cdbSHans Verkuil if (!(dev_debug & V4L2_DEV_DEBUG_IOCTL_ARG)) 28545bc3cb74SMauro Carvalho Chehab pr_cont("\n"); 28555bc3cb74SMauro Carvalho Chehab else if (_IOC_DIR(cmd) == _IOC_NONE) 28565bc3cb74SMauro Carvalho Chehab info->debug(arg, write_only); 28575bc3cb74SMauro Carvalho Chehab else { 28585bc3cb74SMauro Carvalho Chehab pr_cont(": "); 28595bc3cb74SMauro Carvalho Chehab info->debug(arg, write_only); 28605bc3cb74SMauro Carvalho Chehab } 28615bc3cb74SMauro Carvalho Chehab } 28625bc3cb74SMauro Carvalho Chehab 286373a11062SHans Verkuil unlock: 286473a11062SHans Verkuil if (lock) 286573a11062SHans Verkuil mutex_unlock(lock); 2866cc6eddcdSHans Verkuil if (req_queue_lock) 2867cc6eddcdSHans Verkuil mutex_unlock(req_queue_lock); 28685bc3cb74SMauro Carvalho Chehab return ret; 28695bc3cb74SMauro Carvalho Chehab } 28705bc3cb74SMauro Carvalho Chehab 28715bc3cb74SMauro Carvalho Chehab static int check_array_args(unsigned int cmd, void *parg, size_t *array_size, 2872ba2d35c1SHans Verkuil void __user **user_ptr, void ***kernel_ptr) 28735bc3cb74SMauro Carvalho Chehab { 28745bc3cb74SMauro Carvalho Chehab int ret = 0; 28755bc3cb74SMauro Carvalho Chehab 28765bc3cb74SMauro Carvalho Chehab switch (cmd) { 287796b1a702SHans Verkuil case VIDIOC_PREPARE_BUF: 28785bc3cb74SMauro Carvalho Chehab case VIDIOC_QUERYBUF: 28795bc3cb74SMauro Carvalho Chehab case VIDIOC_QBUF: 28805bc3cb74SMauro Carvalho Chehab case VIDIOC_DQBUF: { 28815bc3cb74SMauro Carvalho Chehab struct v4l2_buffer *buf = parg; 28825bc3cb74SMauro Carvalho Chehab 28835bc3cb74SMauro Carvalho Chehab if (V4L2_TYPE_IS_MULTIPLANAR(buf->type) && buf->length > 0) { 28845bc3cb74SMauro Carvalho Chehab if (buf->length > VIDEO_MAX_PLANES) { 28855bc3cb74SMauro Carvalho Chehab ret = -EINVAL; 28865bc3cb74SMauro Carvalho Chehab break; 28875bc3cb74SMauro Carvalho Chehab } 28885bc3cb74SMauro Carvalho Chehab *user_ptr = (void __user *)buf->m.planes; 2889ba2d35c1SHans Verkuil *kernel_ptr = (void **)&buf->m.planes; 28905bc3cb74SMauro Carvalho Chehab *array_size = sizeof(struct v4l2_plane) * buf->length; 28915bc3cb74SMauro Carvalho Chehab ret = 1; 28925bc3cb74SMauro Carvalho Chehab } 28935bc3cb74SMauro Carvalho Chehab break; 28945bc3cb74SMauro Carvalho Chehab } 28955bc3cb74SMauro Carvalho Chehab 2896dd519bb3SHans Verkuil case VIDIOC_G_EDID: 2897dd519bb3SHans Verkuil case VIDIOC_S_EDID: { 2898dd519bb3SHans Verkuil struct v4l2_edid *edid = parg; 2899ed45ce2cSHans Verkuil 2900ed45ce2cSHans Verkuil if (edid->blocks) { 29011b8b10ccSHans Verkuil if (edid->blocks > 256) { 29021b8b10ccSHans Verkuil ret = -EINVAL; 29031b8b10ccSHans Verkuil break; 29041b8b10ccSHans Verkuil } 2905ed45ce2cSHans Verkuil *user_ptr = (void __user *)edid->edid; 2906ba2d35c1SHans Verkuil *kernel_ptr = (void **)&edid->edid; 2907ed45ce2cSHans Verkuil *array_size = edid->blocks * 128; 2908ed45ce2cSHans Verkuil ret = 1; 2909ed45ce2cSHans Verkuil } 2910ed45ce2cSHans Verkuil break; 2911ed45ce2cSHans Verkuil } 2912ed45ce2cSHans Verkuil 29135bc3cb74SMauro Carvalho Chehab case VIDIOC_S_EXT_CTRLS: 29145bc3cb74SMauro Carvalho Chehab case VIDIOC_G_EXT_CTRLS: 29155bc3cb74SMauro Carvalho Chehab case VIDIOC_TRY_EXT_CTRLS: { 29165bc3cb74SMauro Carvalho Chehab struct v4l2_ext_controls *ctrls = parg; 29175bc3cb74SMauro Carvalho Chehab 29185bc3cb74SMauro Carvalho Chehab if (ctrls->count != 0) { 29195bc3cb74SMauro Carvalho Chehab if (ctrls->count > V4L2_CID_MAX_CTRLS) { 29205bc3cb74SMauro Carvalho Chehab ret = -EINVAL; 29215bc3cb74SMauro Carvalho Chehab break; 29225bc3cb74SMauro Carvalho Chehab } 29235bc3cb74SMauro Carvalho Chehab *user_ptr = (void __user *)ctrls->controls; 2924ba2d35c1SHans Verkuil *kernel_ptr = (void **)&ctrls->controls; 29255bc3cb74SMauro Carvalho Chehab *array_size = sizeof(struct v4l2_ext_control) 29265bc3cb74SMauro Carvalho Chehab * ctrls->count; 29275bc3cb74SMauro Carvalho Chehab ret = 1; 29285bc3cb74SMauro Carvalho Chehab } 29295bc3cb74SMauro Carvalho Chehab break; 29305bc3cb74SMauro Carvalho Chehab } 29315bc3cb74SMauro Carvalho Chehab } 29325bc3cb74SMauro Carvalho Chehab 29335bc3cb74SMauro Carvalho Chehab return ret; 29345bc3cb74SMauro Carvalho Chehab } 29355bc3cb74SMauro Carvalho Chehab 29365bc3cb74SMauro Carvalho Chehab long 29375bc3cb74SMauro Carvalho Chehab video_usercopy(struct file *file, unsigned int cmd, unsigned long arg, 29385bc3cb74SMauro Carvalho Chehab v4l2_kioctl func) 29395bc3cb74SMauro Carvalho Chehab { 29405bc3cb74SMauro Carvalho Chehab char sbuf[128]; 29415bc3cb74SMauro Carvalho Chehab void *mbuf = NULL; 29425bc3cb74SMauro Carvalho Chehab void *parg = (void *)arg; 29435bc3cb74SMauro Carvalho Chehab long err = -EINVAL; 29445bc3cb74SMauro Carvalho Chehab bool has_array_args; 2945043f77edSHans Verkuil bool always_copy = false; 29465bc3cb74SMauro Carvalho Chehab size_t array_size = 0; 29475bc3cb74SMauro Carvalho Chehab void __user *user_ptr = NULL; 29485bc3cb74SMauro Carvalho Chehab void **kernel_ptr = NULL; 2949f8a695c4SMauro Carvalho Chehab const size_t ioc_size = _IOC_SIZE(cmd); 29505bc3cb74SMauro Carvalho Chehab 29515bc3cb74SMauro Carvalho Chehab /* Copy arguments into temp kernel buffer */ 29525bc3cb74SMauro Carvalho Chehab if (_IOC_DIR(cmd) != _IOC_NONE) { 2953f8a695c4SMauro Carvalho Chehab if (ioc_size <= sizeof(sbuf)) { 29545bc3cb74SMauro Carvalho Chehab parg = sbuf; 29555bc3cb74SMauro Carvalho Chehab } else { 29565bc3cb74SMauro Carvalho Chehab /* too big to allocate from stack */ 2957f8a695c4SMauro Carvalho Chehab mbuf = kvmalloc(ioc_size, GFP_KERNEL); 29585bc3cb74SMauro Carvalho Chehab if (NULL == mbuf) 29595bc3cb74SMauro Carvalho Chehab return -ENOMEM; 29605bc3cb74SMauro Carvalho Chehab parg = mbuf; 29615bc3cb74SMauro Carvalho Chehab } 29625bc3cb74SMauro Carvalho Chehab 29635bc3cb74SMauro Carvalho Chehab err = -EFAULT; 29645bc3cb74SMauro Carvalho Chehab if (_IOC_DIR(cmd) & _IOC_WRITE) { 2965f8a695c4SMauro Carvalho Chehab unsigned int n = ioc_size; 29665bc3cb74SMauro Carvalho Chehab 29675bc3cb74SMauro Carvalho Chehab /* 29685bc3cb74SMauro Carvalho Chehab * In some cases, only a few fields are used as input, 29695bc3cb74SMauro Carvalho Chehab * i.e. when the app sets "index" and then the driver 29705bc3cb74SMauro Carvalho Chehab * fills in the rest of the structure for the thing 29715bc3cb74SMauro Carvalho Chehab * with that index. We only need to copy up the first 29725bc3cb74SMauro Carvalho Chehab * non-input field. 29735bc3cb74SMauro Carvalho Chehab */ 29745bc3cb74SMauro Carvalho Chehab if (v4l2_is_known_ioctl(cmd)) { 29755bc3cb74SMauro Carvalho Chehab u32 flags = v4l2_ioctls[_IOC_NR(cmd)].flags; 2976043f77edSHans Verkuil 29775bc3cb74SMauro Carvalho Chehab if (flags & INFO_FL_CLEAR_MASK) 29785bc3cb74SMauro Carvalho Chehab n = (flags & INFO_FL_CLEAR_MASK) >> 16; 2979043f77edSHans Verkuil always_copy = flags & INFO_FL_ALWAYS_COPY; 29805bc3cb74SMauro Carvalho Chehab } 29815bc3cb74SMauro Carvalho Chehab 29825bc3cb74SMauro Carvalho Chehab if (copy_from_user(parg, (void __user *)arg, n)) 29835bc3cb74SMauro Carvalho Chehab goto out; 29845bc3cb74SMauro Carvalho Chehab 29855bc3cb74SMauro Carvalho Chehab /* zero out anything we don't copy from userspace */ 2986f8a695c4SMauro Carvalho Chehab if (n < ioc_size) 2987f8a695c4SMauro Carvalho Chehab memset((u8 *)parg + n, 0, ioc_size - n); 29885bc3cb74SMauro Carvalho Chehab } else { 29895bc3cb74SMauro Carvalho Chehab /* read-only ioctl */ 2990f8a695c4SMauro Carvalho Chehab memset(parg, 0, ioc_size); 29915bc3cb74SMauro Carvalho Chehab } 29925bc3cb74SMauro Carvalho Chehab } 29935bc3cb74SMauro Carvalho Chehab 29945bc3cb74SMauro Carvalho Chehab err = check_array_args(cmd, parg, &array_size, &user_ptr, &kernel_ptr); 29955bc3cb74SMauro Carvalho Chehab if (err < 0) 29965bc3cb74SMauro Carvalho Chehab goto out; 29975bc3cb74SMauro Carvalho Chehab has_array_args = err; 29985bc3cb74SMauro Carvalho Chehab 29995bc3cb74SMauro Carvalho Chehab if (has_array_args) { 30005bc3cb74SMauro Carvalho Chehab /* 30015bc3cb74SMauro Carvalho Chehab * When adding new types of array args, make sure that the 30025bc3cb74SMauro Carvalho Chehab * parent argument to ioctl (which contains the pointer to the 30035bc3cb74SMauro Carvalho Chehab * array) fits into sbuf (so that mbuf will still remain 30045bc3cb74SMauro Carvalho Chehab * unused up to here). 30055bc3cb74SMauro Carvalho Chehab */ 3006758d90e1STomasz Figa mbuf = kvmalloc(array_size, GFP_KERNEL); 30075bc3cb74SMauro Carvalho Chehab err = -ENOMEM; 30085bc3cb74SMauro Carvalho Chehab if (NULL == mbuf) 30095bc3cb74SMauro Carvalho Chehab goto out_array_args; 30105bc3cb74SMauro Carvalho Chehab err = -EFAULT; 30115bc3cb74SMauro Carvalho Chehab if (copy_from_user(mbuf, user_ptr, array_size)) 30125bc3cb74SMauro Carvalho Chehab goto out_array_args; 30135bc3cb74SMauro Carvalho Chehab *kernel_ptr = mbuf; 30145bc3cb74SMauro Carvalho Chehab } 30155bc3cb74SMauro Carvalho Chehab 30165bc3cb74SMauro Carvalho Chehab /* Handles IOCTL */ 30175bc3cb74SMauro Carvalho Chehab err = func(file, cmd, parg); 3018181a4a2dSHans Verkuil if (err == -ENOTTY || err == -ENOIOCTLCMD) { 30195bc3cb74SMauro Carvalho Chehab err = -ENOTTY; 3020181a4a2dSHans Verkuil goto out; 3021181a4a2dSHans Verkuil } 3022181a4a2dSHans Verkuil 3023aa32f4c0SHans Verkuil if (err == 0) { 3024aa32f4c0SHans Verkuil if (cmd == VIDIOC_DQBUF) 3025aa32f4c0SHans Verkuil trace_v4l2_dqbuf(video_devdata(file)->minor, parg); 3026aa32f4c0SHans Verkuil else if (cmd == VIDIOC_QBUF) 3027aa32f4c0SHans Verkuil trace_v4l2_qbuf(video_devdata(file)->minor, parg); 3028aa32f4c0SHans Verkuil } 30295bc3cb74SMauro Carvalho Chehab 30305bc3cb74SMauro Carvalho Chehab if (has_array_args) { 3031ba2d35c1SHans Verkuil *kernel_ptr = (void __force *)user_ptr; 30325bc3cb74SMauro Carvalho Chehab if (copy_to_user(user_ptr, mbuf, array_size)) 30335bc3cb74SMauro Carvalho Chehab err = -EFAULT; 30345bc3cb74SMauro Carvalho Chehab goto out_array_args; 30355bc3cb74SMauro Carvalho Chehab } 3036043f77edSHans Verkuil /* 3037043f77edSHans Verkuil * Some ioctls can return an error, but still have valid 3038043f77edSHans Verkuil * results that must be returned. 3039043f77edSHans Verkuil */ 3040043f77edSHans Verkuil if (err < 0 && !always_copy) 30415bc3cb74SMauro Carvalho Chehab goto out; 30425bc3cb74SMauro Carvalho Chehab 30435bc3cb74SMauro Carvalho Chehab out_array_args: 30445bc3cb74SMauro Carvalho Chehab /* Copy results into user buffer */ 30455bc3cb74SMauro Carvalho Chehab switch (_IOC_DIR(cmd)) { 30465bc3cb74SMauro Carvalho Chehab case _IOC_READ: 30475bc3cb74SMauro Carvalho Chehab case (_IOC_WRITE | _IOC_READ): 3048f8a695c4SMauro Carvalho Chehab if (copy_to_user((void __user *)arg, parg, ioc_size)) 30495bc3cb74SMauro Carvalho Chehab err = -EFAULT; 30505bc3cb74SMauro Carvalho Chehab break; 30515bc3cb74SMauro Carvalho Chehab } 30525bc3cb74SMauro Carvalho Chehab 30535bc3cb74SMauro Carvalho Chehab out: 3054758d90e1STomasz Figa kvfree(mbuf); 30555bc3cb74SMauro Carvalho Chehab return err; 30565bc3cb74SMauro Carvalho Chehab } 30575bc3cb74SMauro Carvalho Chehab 30585bc3cb74SMauro Carvalho Chehab long video_ioctl2(struct file *file, 30595bc3cb74SMauro Carvalho Chehab unsigned int cmd, unsigned long arg) 30605bc3cb74SMauro Carvalho Chehab { 30615bc3cb74SMauro Carvalho Chehab return video_usercopy(file, cmd, arg, __video_do_ioctl); 30625bc3cb74SMauro Carvalho Chehab } 30635bc3cb74SMauro Carvalho Chehab EXPORT_SYMBOL(video_ioctl2); 3064