18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * Video capture interface for Linux version 2 48c2ecf20Sopenharmony_ci * 58c2ecf20Sopenharmony_ci * A generic framework to process V4L2 ioctl commands. 68c2ecf20Sopenharmony_ci * 78c2ecf20Sopenharmony_ci * Authors: Alan Cox, <alan@lxorguk.ukuu.org.uk> (version 1) 88c2ecf20Sopenharmony_ci * Mauro Carvalho Chehab <mchehab@kernel.org> (version 2) 98c2ecf20Sopenharmony_ci */ 108c2ecf20Sopenharmony_ci 118c2ecf20Sopenharmony_ci#include <linux/mm.h> 128c2ecf20Sopenharmony_ci#include <linux/module.h> 138c2ecf20Sopenharmony_ci#include <linux/slab.h> 148c2ecf20Sopenharmony_ci#include <linux/types.h> 158c2ecf20Sopenharmony_ci#include <linux/kernel.h> 168c2ecf20Sopenharmony_ci#include <linux/version.h> 178c2ecf20Sopenharmony_ci 188c2ecf20Sopenharmony_ci#include <linux/videodev2.h> 198c2ecf20Sopenharmony_ci 208c2ecf20Sopenharmony_ci#include <media/v4l2-common.h> 218c2ecf20Sopenharmony_ci#include <media/v4l2-ioctl.h> 228c2ecf20Sopenharmony_ci#include <media/v4l2-ctrls.h> 238c2ecf20Sopenharmony_ci#include <media/v4l2-fh.h> 248c2ecf20Sopenharmony_ci#include <media/v4l2-event.h> 258c2ecf20Sopenharmony_ci#include <media/v4l2-device.h> 268c2ecf20Sopenharmony_ci#include <media/videobuf2-v4l2.h> 278c2ecf20Sopenharmony_ci#include <media/v4l2-mc.h> 288c2ecf20Sopenharmony_ci#include <media/v4l2-mem2mem.h> 298c2ecf20Sopenharmony_ci 308c2ecf20Sopenharmony_ci#include <trace/events/v4l2.h> 318c2ecf20Sopenharmony_ci 328c2ecf20Sopenharmony_ci/* Zero out the end of the struct pointed to by p. Everything after, but 338c2ecf20Sopenharmony_ci * not including, the specified field is cleared. */ 348c2ecf20Sopenharmony_ci#define CLEAR_AFTER_FIELD(p, field) \ 358c2ecf20Sopenharmony_ci memset((u8 *)(p) + offsetof(typeof(*(p)), field) + sizeof((p)->field), \ 368c2ecf20Sopenharmony_ci 0, sizeof(*(p)) - offsetof(typeof(*(p)), field) - sizeof((p)->field)) 378c2ecf20Sopenharmony_ci 388c2ecf20Sopenharmony_ci#define is_valid_ioctl(vfd, cmd) test_bit(_IOC_NR(cmd), (vfd)->valid_ioctls) 398c2ecf20Sopenharmony_ci 408c2ecf20Sopenharmony_cistruct std_descr { 418c2ecf20Sopenharmony_ci v4l2_std_id std; 428c2ecf20Sopenharmony_ci const char *descr; 438c2ecf20Sopenharmony_ci}; 448c2ecf20Sopenharmony_ci 458c2ecf20Sopenharmony_cistatic const struct std_descr standards[] = { 468c2ecf20Sopenharmony_ci { V4L2_STD_NTSC, "NTSC" }, 478c2ecf20Sopenharmony_ci { V4L2_STD_NTSC_M, "NTSC-M" }, 488c2ecf20Sopenharmony_ci { V4L2_STD_NTSC_M_JP, "NTSC-M-JP" }, 498c2ecf20Sopenharmony_ci { V4L2_STD_NTSC_M_KR, "NTSC-M-KR" }, 508c2ecf20Sopenharmony_ci { V4L2_STD_NTSC_443, "NTSC-443" }, 518c2ecf20Sopenharmony_ci { V4L2_STD_PAL, "PAL" }, 528c2ecf20Sopenharmony_ci { V4L2_STD_PAL_BG, "PAL-BG" }, 538c2ecf20Sopenharmony_ci { V4L2_STD_PAL_B, "PAL-B" }, 548c2ecf20Sopenharmony_ci { V4L2_STD_PAL_B1, "PAL-B1" }, 558c2ecf20Sopenharmony_ci { V4L2_STD_PAL_G, "PAL-G" }, 568c2ecf20Sopenharmony_ci { V4L2_STD_PAL_H, "PAL-H" }, 578c2ecf20Sopenharmony_ci { V4L2_STD_PAL_I, "PAL-I" }, 588c2ecf20Sopenharmony_ci { V4L2_STD_PAL_DK, "PAL-DK" }, 598c2ecf20Sopenharmony_ci { V4L2_STD_PAL_D, "PAL-D" }, 608c2ecf20Sopenharmony_ci { V4L2_STD_PAL_D1, "PAL-D1" }, 618c2ecf20Sopenharmony_ci { V4L2_STD_PAL_K, "PAL-K" }, 628c2ecf20Sopenharmony_ci { V4L2_STD_PAL_M, "PAL-M" }, 638c2ecf20Sopenharmony_ci { V4L2_STD_PAL_N, "PAL-N" }, 648c2ecf20Sopenharmony_ci { V4L2_STD_PAL_Nc, "PAL-Nc" }, 658c2ecf20Sopenharmony_ci { V4L2_STD_PAL_60, "PAL-60" }, 668c2ecf20Sopenharmony_ci { V4L2_STD_SECAM, "SECAM" }, 678c2ecf20Sopenharmony_ci { V4L2_STD_SECAM_B, "SECAM-B" }, 688c2ecf20Sopenharmony_ci { V4L2_STD_SECAM_G, "SECAM-G" }, 698c2ecf20Sopenharmony_ci { V4L2_STD_SECAM_H, "SECAM-H" }, 708c2ecf20Sopenharmony_ci { V4L2_STD_SECAM_DK, "SECAM-DK" }, 718c2ecf20Sopenharmony_ci { V4L2_STD_SECAM_D, "SECAM-D" }, 728c2ecf20Sopenharmony_ci { V4L2_STD_SECAM_K, "SECAM-K" }, 738c2ecf20Sopenharmony_ci { V4L2_STD_SECAM_K1, "SECAM-K1" }, 748c2ecf20Sopenharmony_ci { V4L2_STD_SECAM_L, "SECAM-L" }, 758c2ecf20Sopenharmony_ci { V4L2_STD_SECAM_LC, "SECAM-Lc" }, 768c2ecf20Sopenharmony_ci { 0, "Unknown" } 778c2ecf20Sopenharmony_ci}; 788c2ecf20Sopenharmony_ci 798c2ecf20Sopenharmony_ci/* video4linux standard ID conversion to standard name 808c2ecf20Sopenharmony_ci */ 818c2ecf20Sopenharmony_ciconst char *v4l2_norm_to_name(v4l2_std_id id) 828c2ecf20Sopenharmony_ci{ 838c2ecf20Sopenharmony_ci u32 myid = id; 848c2ecf20Sopenharmony_ci int i; 858c2ecf20Sopenharmony_ci 868c2ecf20Sopenharmony_ci /* HACK: ppc32 architecture doesn't have __ucmpdi2 function to handle 878c2ecf20Sopenharmony_ci 64 bit comparisons. So, on that architecture, with some gcc 888c2ecf20Sopenharmony_ci variants, compilation fails. Currently, the max value is 30bit wide. 898c2ecf20Sopenharmony_ci */ 908c2ecf20Sopenharmony_ci BUG_ON(myid != id); 918c2ecf20Sopenharmony_ci 928c2ecf20Sopenharmony_ci for (i = 0; standards[i].std; i++) 938c2ecf20Sopenharmony_ci if (myid == standards[i].std) 948c2ecf20Sopenharmony_ci break; 958c2ecf20Sopenharmony_ci return standards[i].descr; 968c2ecf20Sopenharmony_ci} 978c2ecf20Sopenharmony_ciEXPORT_SYMBOL(v4l2_norm_to_name); 988c2ecf20Sopenharmony_ci 998c2ecf20Sopenharmony_ci/* Returns frame period for the given standard */ 1008c2ecf20Sopenharmony_civoid v4l2_video_std_frame_period(int id, struct v4l2_fract *frameperiod) 1018c2ecf20Sopenharmony_ci{ 1028c2ecf20Sopenharmony_ci if (id & V4L2_STD_525_60) { 1038c2ecf20Sopenharmony_ci frameperiod->numerator = 1001; 1048c2ecf20Sopenharmony_ci frameperiod->denominator = 30000; 1058c2ecf20Sopenharmony_ci } else { 1068c2ecf20Sopenharmony_ci frameperiod->numerator = 1; 1078c2ecf20Sopenharmony_ci frameperiod->denominator = 25; 1088c2ecf20Sopenharmony_ci } 1098c2ecf20Sopenharmony_ci} 1108c2ecf20Sopenharmony_ciEXPORT_SYMBOL(v4l2_video_std_frame_period); 1118c2ecf20Sopenharmony_ci 1128c2ecf20Sopenharmony_ci/* Fill in the fields of a v4l2_standard structure according to the 1138c2ecf20Sopenharmony_ci 'id' and 'transmission' parameters. Returns negative on error. */ 1148c2ecf20Sopenharmony_ciint v4l2_video_std_construct(struct v4l2_standard *vs, 1158c2ecf20Sopenharmony_ci int id, const char *name) 1168c2ecf20Sopenharmony_ci{ 1178c2ecf20Sopenharmony_ci vs->id = id; 1188c2ecf20Sopenharmony_ci v4l2_video_std_frame_period(id, &vs->frameperiod); 1198c2ecf20Sopenharmony_ci vs->framelines = (id & V4L2_STD_525_60) ? 525 : 625; 1208c2ecf20Sopenharmony_ci strscpy(vs->name, name, sizeof(vs->name)); 1218c2ecf20Sopenharmony_ci return 0; 1228c2ecf20Sopenharmony_ci} 1238c2ecf20Sopenharmony_ciEXPORT_SYMBOL(v4l2_video_std_construct); 1248c2ecf20Sopenharmony_ci 1258c2ecf20Sopenharmony_ci/* Fill in the fields of a v4l2_standard structure according to the 1268c2ecf20Sopenharmony_ci * 'id' and 'vs->index' parameters. Returns negative on error. */ 1278c2ecf20Sopenharmony_ciint v4l_video_std_enumstd(struct v4l2_standard *vs, v4l2_std_id id) 1288c2ecf20Sopenharmony_ci{ 1298c2ecf20Sopenharmony_ci v4l2_std_id curr_id = 0; 1308c2ecf20Sopenharmony_ci unsigned int index = vs->index, i, j = 0; 1318c2ecf20Sopenharmony_ci const char *descr = ""; 1328c2ecf20Sopenharmony_ci 1338c2ecf20Sopenharmony_ci /* Return -ENODATA if the id for the current input 1348c2ecf20Sopenharmony_ci or output is 0, meaning that it doesn't support this API. */ 1358c2ecf20Sopenharmony_ci if (id == 0) 1368c2ecf20Sopenharmony_ci return -ENODATA; 1378c2ecf20Sopenharmony_ci 1388c2ecf20Sopenharmony_ci /* Return norm array in a canonical way */ 1398c2ecf20Sopenharmony_ci for (i = 0; i <= index && id; i++) { 1408c2ecf20Sopenharmony_ci /* last std value in the standards array is 0, so this 1418c2ecf20Sopenharmony_ci while always ends there since (id & 0) == 0. */ 1428c2ecf20Sopenharmony_ci while ((id & standards[j].std) != standards[j].std) 1438c2ecf20Sopenharmony_ci j++; 1448c2ecf20Sopenharmony_ci curr_id = standards[j].std; 1458c2ecf20Sopenharmony_ci descr = standards[j].descr; 1468c2ecf20Sopenharmony_ci j++; 1478c2ecf20Sopenharmony_ci if (curr_id == 0) 1488c2ecf20Sopenharmony_ci break; 1498c2ecf20Sopenharmony_ci if (curr_id != V4L2_STD_PAL && 1508c2ecf20Sopenharmony_ci curr_id != V4L2_STD_SECAM && 1518c2ecf20Sopenharmony_ci curr_id != V4L2_STD_NTSC) 1528c2ecf20Sopenharmony_ci id &= ~curr_id; 1538c2ecf20Sopenharmony_ci } 1548c2ecf20Sopenharmony_ci if (i <= index) 1558c2ecf20Sopenharmony_ci return -EINVAL; 1568c2ecf20Sopenharmony_ci 1578c2ecf20Sopenharmony_ci v4l2_video_std_construct(vs, curr_id, descr); 1588c2ecf20Sopenharmony_ci return 0; 1598c2ecf20Sopenharmony_ci} 1608c2ecf20Sopenharmony_ci 1618c2ecf20Sopenharmony_ci/* ----------------------------------------------------------------- */ 1628c2ecf20Sopenharmony_ci/* some arrays for pretty-printing debug messages of enum types */ 1638c2ecf20Sopenharmony_ci 1648c2ecf20Sopenharmony_ciconst char *v4l2_field_names[] = { 1658c2ecf20Sopenharmony_ci [V4L2_FIELD_ANY] = "any", 1668c2ecf20Sopenharmony_ci [V4L2_FIELD_NONE] = "none", 1678c2ecf20Sopenharmony_ci [V4L2_FIELD_TOP] = "top", 1688c2ecf20Sopenharmony_ci [V4L2_FIELD_BOTTOM] = "bottom", 1698c2ecf20Sopenharmony_ci [V4L2_FIELD_INTERLACED] = "interlaced", 1708c2ecf20Sopenharmony_ci [V4L2_FIELD_SEQ_TB] = "seq-tb", 1718c2ecf20Sopenharmony_ci [V4L2_FIELD_SEQ_BT] = "seq-bt", 1728c2ecf20Sopenharmony_ci [V4L2_FIELD_ALTERNATE] = "alternate", 1738c2ecf20Sopenharmony_ci [V4L2_FIELD_INTERLACED_TB] = "interlaced-tb", 1748c2ecf20Sopenharmony_ci [V4L2_FIELD_INTERLACED_BT] = "interlaced-bt", 1758c2ecf20Sopenharmony_ci}; 1768c2ecf20Sopenharmony_ciEXPORT_SYMBOL(v4l2_field_names); 1778c2ecf20Sopenharmony_ci 1788c2ecf20Sopenharmony_ciconst char *v4l2_type_names[] = { 1798c2ecf20Sopenharmony_ci [0] = "0", 1808c2ecf20Sopenharmony_ci [V4L2_BUF_TYPE_VIDEO_CAPTURE] = "vid-cap", 1818c2ecf20Sopenharmony_ci [V4L2_BUF_TYPE_VIDEO_OVERLAY] = "vid-overlay", 1828c2ecf20Sopenharmony_ci [V4L2_BUF_TYPE_VIDEO_OUTPUT] = "vid-out", 1838c2ecf20Sopenharmony_ci [V4L2_BUF_TYPE_VBI_CAPTURE] = "vbi-cap", 1848c2ecf20Sopenharmony_ci [V4L2_BUF_TYPE_VBI_OUTPUT] = "vbi-out", 1858c2ecf20Sopenharmony_ci [V4L2_BUF_TYPE_SLICED_VBI_CAPTURE] = "sliced-vbi-cap", 1868c2ecf20Sopenharmony_ci [V4L2_BUF_TYPE_SLICED_VBI_OUTPUT] = "sliced-vbi-out", 1878c2ecf20Sopenharmony_ci [V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY] = "vid-out-overlay", 1888c2ecf20Sopenharmony_ci [V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE] = "vid-cap-mplane", 1898c2ecf20Sopenharmony_ci [V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE] = "vid-out-mplane", 1908c2ecf20Sopenharmony_ci [V4L2_BUF_TYPE_SDR_CAPTURE] = "sdr-cap", 1918c2ecf20Sopenharmony_ci [V4L2_BUF_TYPE_SDR_OUTPUT] = "sdr-out", 1928c2ecf20Sopenharmony_ci [V4L2_BUF_TYPE_META_CAPTURE] = "meta-cap", 1938c2ecf20Sopenharmony_ci [V4L2_BUF_TYPE_META_OUTPUT] = "meta-out", 1948c2ecf20Sopenharmony_ci}; 1958c2ecf20Sopenharmony_ciEXPORT_SYMBOL(v4l2_type_names); 1968c2ecf20Sopenharmony_ci 1978c2ecf20Sopenharmony_cistatic const char *v4l2_memory_names[] = { 1988c2ecf20Sopenharmony_ci [V4L2_MEMORY_MMAP] = "mmap", 1998c2ecf20Sopenharmony_ci [V4L2_MEMORY_USERPTR] = "userptr", 2008c2ecf20Sopenharmony_ci [V4L2_MEMORY_OVERLAY] = "overlay", 2018c2ecf20Sopenharmony_ci [V4L2_MEMORY_DMABUF] = "dmabuf", 2028c2ecf20Sopenharmony_ci}; 2038c2ecf20Sopenharmony_ci 2048c2ecf20Sopenharmony_ci#define prt_names(a, arr) (((unsigned)(a)) < ARRAY_SIZE(arr) ? arr[a] : "unknown") 2058c2ecf20Sopenharmony_ci 2068c2ecf20Sopenharmony_ci/* ------------------------------------------------------------------ */ 2078c2ecf20Sopenharmony_ci/* debug help functions */ 2088c2ecf20Sopenharmony_ci 2098c2ecf20Sopenharmony_cistatic void v4l_print_querycap(const void *arg, bool write_only) 2108c2ecf20Sopenharmony_ci{ 2118c2ecf20Sopenharmony_ci const struct v4l2_capability *p = arg; 2128c2ecf20Sopenharmony_ci 2138c2ecf20Sopenharmony_ci pr_cont("driver=%.*s, card=%.*s, bus=%.*s, version=0x%08x, capabilities=0x%08x, device_caps=0x%08x\n", 2148c2ecf20Sopenharmony_ci (int)sizeof(p->driver), p->driver, 2158c2ecf20Sopenharmony_ci (int)sizeof(p->card), p->card, 2168c2ecf20Sopenharmony_ci (int)sizeof(p->bus_info), p->bus_info, 2178c2ecf20Sopenharmony_ci p->version, p->capabilities, p->device_caps); 2188c2ecf20Sopenharmony_ci} 2198c2ecf20Sopenharmony_ci 2208c2ecf20Sopenharmony_cistatic void v4l_print_enuminput(const void *arg, bool write_only) 2218c2ecf20Sopenharmony_ci{ 2228c2ecf20Sopenharmony_ci const struct v4l2_input *p = arg; 2238c2ecf20Sopenharmony_ci 2248c2ecf20Sopenharmony_ci pr_cont("index=%u, name=%.*s, type=%u, audioset=0x%x, tuner=%u, std=0x%08Lx, status=0x%x, capabilities=0x%x\n", 2258c2ecf20Sopenharmony_ci p->index, (int)sizeof(p->name), p->name, p->type, p->audioset, 2268c2ecf20Sopenharmony_ci p->tuner, (unsigned long long)p->std, p->status, 2278c2ecf20Sopenharmony_ci p->capabilities); 2288c2ecf20Sopenharmony_ci} 2298c2ecf20Sopenharmony_ci 2308c2ecf20Sopenharmony_cistatic void v4l_print_enumoutput(const void *arg, bool write_only) 2318c2ecf20Sopenharmony_ci{ 2328c2ecf20Sopenharmony_ci const struct v4l2_output *p = arg; 2338c2ecf20Sopenharmony_ci 2348c2ecf20Sopenharmony_ci pr_cont("index=%u, name=%.*s, type=%u, audioset=0x%x, modulator=%u, std=0x%08Lx, capabilities=0x%x\n", 2358c2ecf20Sopenharmony_ci p->index, (int)sizeof(p->name), p->name, p->type, p->audioset, 2368c2ecf20Sopenharmony_ci p->modulator, (unsigned long long)p->std, p->capabilities); 2378c2ecf20Sopenharmony_ci} 2388c2ecf20Sopenharmony_ci 2398c2ecf20Sopenharmony_cistatic void v4l_print_audio(const void *arg, bool write_only) 2408c2ecf20Sopenharmony_ci{ 2418c2ecf20Sopenharmony_ci const struct v4l2_audio *p = arg; 2428c2ecf20Sopenharmony_ci 2438c2ecf20Sopenharmony_ci if (write_only) 2448c2ecf20Sopenharmony_ci pr_cont("index=%u, mode=0x%x\n", p->index, p->mode); 2458c2ecf20Sopenharmony_ci else 2468c2ecf20Sopenharmony_ci pr_cont("index=%u, name=%.*s, capability=0x%x, mode=0x%x\n", 2478c2ecf20Sopenharmony_ci p->index, (int)sizeof(p->name), p->name, 2488c2ecf20Sopenharmony_ci p->capability, p->mode); 2498c2ecf20Sopenharmony_ci} 2508c2ecf20Sopenharmony_ci 2518c2ecf20Sopenharmony_cistatic void v4l_print_audioout(const void *arg, bool write_only) 2528c2ecf20Sopenharmony_ci{ 2538c2ecf20Sopenharmony_ci const struct v4l2_audioout *p = arg; 2548c2ecf20Sopenharmony_ci 2558c2ecf20Sopenharmony_ci if (write_only) 2568c2ecf20Sopenharmony_ci pr_cont("index=%u\n", p->index); 2578c2ecf20Sopenharmony_ci else 2588c2ecf20Sopenharmony_ci pr_cont("index=%u, name=%.*s, capability=0x%x, mode=0x%x\n", 2598c2ecf20Sopenharmony_ci p->index, (int)sizeof(p->name), p->name, 2608c2ecf20Sopenharmony_ci p->capability, p->mode); 2618c2ecf20Sopenharmony_ci} 2628c2ecf20Sopenharmony_ci 2638c2ecf20Sopenharmony_cistatic void v4l_print_fmtdesc(const void *arg, bool write_only) 2648c2ecf20Sopenharmony_ci{ 2658c2ecf20Sopenharmony_ci const struct v4l2_fmtdesc *p = arg; 2668c2ecf20Sopenharmony_ci 2678c2ecf20Sopenharmony_ci pr_cont("index=%u, type=%s, flags=0x%x, pixelformat=%c%c%c%c, mbus_code=0x%04x, description='%.*s'\n", 2688c2ecf20Sopenharmony_ci p->index, prt_names(p->type, v4l2_type_names), 2698c2ecf20Sopenharmony_ci p->flags, (p->pixelformat & 0xff), 2708c2ecf20Sopenharmony_ci (p->pixelformat >> 8) & 0xff, 2718c2ecf20Sopenharmony_ci (p->pixelformat >> 16) & 0xff, 2728c2ecf20Sopenharmony_ci (p->pixelformat >> 24) & 0xff, 2738c2ecf20Sopenharmony_ci p->mbus_code, 2748c2ecf20Sopenharmony_ci (int)sizeof(p->description), p->description); 2758c2ecf20Sopenharmony_ci} 2768c2ecf20Sopenharmony_ci 2778c2ecf20Sopenharmony_cistatic void v4l_print_format(const void *arg, bool write_only) 2788c2ecf20Sopenharmony_ci{ 2798c2ecf20Sopenharmony_ci const struct v4l2_format *p = arg; 2808c2ecf20Sopenharmony_ci const struct v4l2_pix_format *pix; 2818c2ecf20Sopenharmony_ci const struct v4l2_pix_format_mplane *mp; 2828c2ecf20Sopenharmony_ci const struct v4l2_vbi_format *vbi; 2838c2ecf20Sopenharmony_ci const struct v4l2_sliced_vbi_format *sliced; 2848c2ecf20Sopenharmony_ci const struct v4l2_window *win; 2858c2ecf20Sopenharmony_ci const struct v4l2_sdr_format *sdr; 2868c2ecf20Sopenharmony_ci const struct v4l2_meta_format *meta; 2878c2ecf20Sopenharmony_ci u32 planes; 2888c2ecf20Sopenharmony_ci unsigned i; 2898c2ecf20Sopenharmony_ci 2908c2ecf20Sopenharmony_ci pr_cont("type=%s", prt_names(p->type, v4l2_type_names)); 2918c2ecf20Sopenharmony_ci switch (p->type) { 2928c2ecf20Sopenharmony_ci case V4L2_BUF_TYPE_VIDEO_CAPTURE: 2938c2ecf20Sopenharmony_ci case V4L2_BUF_TYPE_VIDEO_OUTPUT: 2948c2ecf20Sopenharmony_ci pix = &p->fmt.pix; 2958c2ecf20Sopenharmony_ci 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", 2968c2ecf20Sopenharmony_ci pix->width, pix->height, 2978c2ecf20Sopenharmony_ci (pix->pixelformat & 0xff), 2988c2ecf20Sopenharmony_ci (pix->pixelformat >> 8) & 0xff, 2998c2ecf20Sopenharmony_ci (pix->pixelformat >> 16) & 0xff, 3008c2ecf20Sopenharmony_ci (pix->pixelformat >> 24) & 0xff, 3018c2ecf20Sopenharmony_ci prt_names(pix->field, v4l2_field_names), 3028c2ecf20Sopenharmony_ci pix->bytesperline, pix->sizeimage, 3038c2ecf20Sopenharmony_ci pix->colorspace, pix->flags, pix->ycbcr_enc, 3048c2ecf20Sopenharmony_ci pix->quantization, pix->xfer_func); 3058c2ecf20Sopenharmony_ci break; 3068c2ecf20Sopenharmony_ci case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE: 3078c2ecf20Sopenharmony_ci case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE: 3088c2ecf20Sopenharmony_ci mp = &p->fmt.pix_mp; 3098c2ecf20Sopenharmony_ci 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", 3108c2ecf20Sopenharmony_ci mp->width, mp->height, 3118c2ecf20Sopenharmony_ci (mp->pixelformat & 0xff), 3128c2ecf20Sopenharmony_ci (mp->pixelformat >> 8) & 0xff, 3138c2ecf20Sopenharmony_ci (mp->pixelformat >> 16) & 0xff, 3148c2ecf20Sopenharmony_ci (mp->pixelformat >> 24) & 0xff, 3158c2ecf20Sopenharmony_ci prt_names(mp->field, v4l2_field_names), 3168c2ecf20Sopenharmony_ci mp->colorspace, mp->num_planes, mp->flags, 3178c2ecf20Sopenharmony_ci mp->ycbcr_enc, mp->quantization, mp->xfer_func); 3188c2ecf20Sopenharmony_ci planes = min_t(u32, mp->num_planes, VIDEO_MAX_PLANES); 3198c2ecf20Sopenharmony_ci for (i = 0; i < planes; i++) 3208c2ecf20Sopenharmony_ci printk(KERN_DEBUG "plane %u: bytesperline=%u sizeimage=%u\n", i, 3218c2ecf20Sopenharmony_ci mp->plane_fmt[i].bytesperline, 3228c2ecf20Sopenharmony_ci mp->plane_fmt[i].sizeimage); 3238c2ecf20Sopenharmony_ci break; 3248c2ecf20Sopenharmony_ci case V4L2_BUF_TYPE_VIDEO_OVERLAY: 3258c2ecf20Sopenharmony_ci case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY: 3268c2ecf20Sopenharmony_ci win = &p->fmt.win; 3278c2ecf20Sopenharmony_ci /* Note: we can't print the clip list here since the clips 3288c2ecf20Sopenharmony_ci * pointer is a userspace pointer, not a kernelspace 3298c2ecf20Sopenharmony_ci * pointer. */ 3308c2ecf20Sopenharmony_ci 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", 3318c2ecf20Sopenharmony_ci win->w.width, win->w.height, win->w.left, win->w.top, 3328c2ecf20Sopenharmony_ci prt_names(win->field, v4l2_field_names), 3338c2ecf20Sopenharmony_ci win->chromakey, win->clipcount, win->clips, 3348c2ecf20Sopenharmony_ci win->bitmap, win->global_alpha); 3358c2ecf20Sopenharmony_ci break; 3368c2ecf20Sopenharmony_ci case V4L2_BUF_TYPE_VBI_CAPTURE: 3378c2ecf20Sopenharmony_ci case V4L2_BUF_TYPE_VBI_OUTPUT: 3388c2ecf20Sopenharmony_ci vbi = &p->fmt.vbi; 3398c2ecf20Sopenharmony_ci pr_cont(", sampling_rate=%u, offset=%u, samples_per_line=%u, sample_format=%c%c%c%c, start=%u,%u, count=%u,%u\n", 3408c2ecf20Sopenharmony_ci vbi->sampling_rate, vbi->offset, 3418c2ecf20Sopenharmony_ci vbi->samples_per_line, 3428c2ecf20Sopenharmony_ci (vbi->sample_format & 0xff), 3438c2ecf20Sopenharmony_ci (vbi->sample_format >> 8) & 0xff, 3448c2ecf20Sopenharmony_ci (vbi->sample_format >> 16) & 0xff, 3458c2ecf20Sopenharmony_ci (vbi->sample_format >> 24) & 0xff, 3468c2ecf20Sopenharmony_ci vbi->start[0], vbi->start[1], 3478c2ecf20Sopenharmony_ci vbi->count[0], vbi->count[1]); 3488c2ecf20Sopenharmony_ci break; 3498c2ecf20Sopenharmony_ci case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE: 3508c2ecf20Sopenharmony_ci case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT: 3518c2ecf20Sopenharmony_ci sliced = &p->fmt.sliced; 3528c2ecf20Sopenharmony_ci pr_cont(", service_set=0x%08x, io_size=%d\n", 3538c2ecf20Sopenharmony_ci sliced->service_set, sliced->io_size); 3548c2ecf20Sopenharmony_ci for (i = 0; i < 24; i++) 3558c2ecf20Sopenharmony_ci printk(KERN_DEBUG "line[%02u]=0x%04x, 0x%04x\n", i, 3568c2ecf20Sopenharmony_ci sliced->service_lines[0][i], 3578c2ecf20Sopenharmony_ci sliced->service_lines[1][i]); 3588c2ecf20Sopenharmony_ci break; 3598c2ecf20Sopenharmony_ci case V4L2_BUF_TYPE_SDR_CAPTURE: 3608c2ecf20Sopenharmony_ci case V4L2_BUF_TYPE_SDR_OUTPUT: 3618c2ecf20Sopenharmony_ci sdr = &p->fmt.sdr; 3628c2ecf20Sopenharmony_ci pr_cont(", pixelformat=%c%c%c%c\n", 3638c2ecf20Sopenharmony_ci (sdr->pixelformat >> 0) & 0xff, 3648c2ecf20Sopenharmony_ci (sdr->pixelformat >> 8) & 0xff, 3658c2ecf20Sopenharmony_ci (sdr->pixelformat >> 16) & 0xff, 3668c2ecf20Sopenharmony_ci (sdr->pixelformat >> 24) & 0xff); 3678c2ecf20Sopenharmony_ci break; 3688c2ecf20Sopenharmony_ci case V4L2_BUF_TYPE_META_CAPTURE: 3698c2ecf20Sopenharmony_ci case V4L2_BUF_TYPE_META_OUTPUT: 3708c2ecf20Sopenharmony_ci meta = &p->fmt.meta; 3718c2ecf20Sopenharmony_ci pr_cont(", dataformat=%c%c%c%c, buffersize=%u\n", 3728c2ecf20Sopenharmony_ci (meta->dataformat >> 0) & 0xff, 3738c2ecf20Sopenharmony_ci (meta->dataformat >> 8) & 0xff, 3748c2ecf20Sopenharmony_ci (meta->dataformat >> 16) & 0xff, 3758c2ecf20Sopenharmony_ci (meta->dataformat >> 24) & 0xff, 3768c2ecf20Sopenharmony_ci meta->buffersize); 3778c2ecf20Sopenharmony_ci break; 3788c2ecf20Sopenharmony_ci } 3798c2ecf20Sopenharmony_ci} 3808c2ecf20Sopenharmony_ci 3818c2ecf20Sopenharmony_cistatic void v4l_print_framebuffer(const void *arg, bool write_only) 3828c2ecf20Sopenharmony_ci{ 3838c2ecf20Sopenharmony_ci const struct v4l2_framebuffer *p = arg; 3848c2ecf20Sopenharmony_ci 3858c2ecf20Sopenharmony_ci 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", 3868c2ecf20Sopenharmony_ci p->capability, p->flags, p->base, 3878c2ecf20Sopenharmony_ci p->fmt.width, p->fmt.height, 3888c2ecf20Sopenharmony_ci (p->fmt.pixelformat & 0xff), 3898c2ecf20Sopenharmony_ci (p->fmt.pixelformat >> 8) & 0xff, 3908c2ecf20Sopenharmony_ci (p->fmt.pixelformat >> 16) & 0xff, 3918c2ecf20Sopenharmony_ci (p->fmt.pixelformat >> 24) & 0xff, 3928c2ecf20Sopenharmony_ci p->fmt.bytesperline, p->fmt.sizeimage, 3938c2ecf20Sopenharmony_ci p->fmt.colorspace); 3948c2ecf20Sopenharmony_ci} 3958c2ecf20Sopenharmony_ci 3968c2ecf20Sopenharmony_cistatic void v4l_print_buftype(const void *arg, bool write_only) 3978c2ecf20Sopenharmony_ci{ 3988c2ecf20Sopenharmony_ci pr_cont("type=%s\n", prt_names(*(u32 *)arg, v4l2_type_names)); 3998c2ecf20Sopenharmony_ci} 4008c2ecf20Sopenharmony_ci 4018c2ecf20Sopenharmony_cistatic void v4l_print_modulator(const void *arg, bool write_only) 4028c2ecf20Sopenharmony_ci{ 4038c2ecf20Sopenharmony_ci const struct v4l2_modulator *p = arg; 4048c2ecf20Sopenharmony_ci 4058c2ecf20Sopenharmony_ci if (write_only) 4068c2ecf20Sopenharmony_ci pr_cont("index=%u, txsubchans=0x%x\n", p->index, p->txsubchans); 4078c2ecf20Sopenharmony_ci else 4088c2ecf20Sopenharmony_ci pr_cont("index=%u, name=%.*s, capability=0x%x, rangelow=%u, rangehigh=%u, txsubchans=0x%x\n", 4098c2ecf20Sopenharmony_ci p->index, (int)sizeof(p->name), p->name, p->capability, 4108c2ecf20Sopenharmony_ci p->rangelow, p->rangehigh, p->txsubchans); 4118c2ecf20Sopenharmony_ci} 4128c2ecf20Sopenharmony_ci 4138c2ecf20Sopenharmony_cistatic void v4l_print_tuner(const void *arg, bool write_only) 4148c2ecf20Sopenharmony_ci{ 4158c2ecf20Sopenharmony_ci const struct v4l2_tuner *p = arg; 4168c2ecf20Sopenharmony_ci 4178c2ecf20Sopenharmony_ci if (write_only) 4188c2ecf20Sopenharmony_ci pr_cont("index=%u, audmode=%u\n", p->index, p->audmode); 4198c2ecf20Sopenharmony_ci else 4208c2ecf20Sopenharmony_ci 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", 4218c2ecf20Sopenharmony_ci p->index, (int)sizeof(p->name), p->name, p->type, 4228c2ecf20Sopenharmony_ci p->capability, p->rangelow, 4238c2ecf20Sopenharmony_ci p->rangehigh, p->signal, p->afc, 4248c2ecf20Sopenharmony_ci p->rxsubchans, p->audmode); 4258c2ecf20Sopenharmony_ci} 4268c2ecf20Sopenharmony_ci 4278c2ecf20Sopenharmony_cistatic void v4l_print_frequency(const void *arg, bool write_only) 4288c2ecf20Sopenharmony_ci{ 4298c2ecf20Sopenharmony_ci const struct v4l2_frequency *p = arg; 4308c2ecf20Sopenharmony_ci 4318c2ecf20Sopenharmony_ci pr_cont("tuner=%u, type=%u, frequency=%u\n", 4328c2ecf20Sopenharmony_ci p->tuner, p->type, p->frequency); 4338c2ecf20Sopenharmony_ci} 4348c2ecf20Sopenharmony_ci 4358c2ecf20Sopenharmony_cistatic void v4l_print_standard(const void *arg, bool write_only) 4368c2ecf20Sopenharmony_ci{ 4378c2ecf20Sopenharmony_ci const struct v4l2_standard *p = arg; 4388c2ecf20Sopenharmony_ci 4398c2ecf20Sopenharmony_ci pr_cont("index=%u, id=0x%Lx, name=%.*s, fps=%u/%u, framelines=%u\n", 4408c2ecf20Sopenharmony_ci p->index, 4418c2ecf20Sopenharmony_ci (unsigned long long)p->id, (int)sizeof(p->name), p->name, 4428c2ecf20Sopenharmony_ci p->frameperiod.numerator, 4438c2ecf20Sopenharmony_ci p->frameperiod.denominator, 4448c2ecf20Sopenharmony_ci p->framelines); 4458c2ecf20Sopenharmony_ci} 4468c2ecf20Sopenharmony_ci 4478c2ecf20Sopenharmony_cistatic void v4l_print_std(const void *arg, bool write_only) 4488c2ecf20Sopenharmony_ci{ 4498c2ecf20Sopenharmony_ci pr_cont("std=0x%08Lx\n", *(const long long unsigned *)arg); 4508c2ecf20Sopenharmony_ci} 4518c2ecf20Sopenharmony_ci 4528c2ecf20Sopenharmony_cistatic void v4l_print_hw_freq_seek(const void *arg, bool write_only) 4538c2ecf20Sopenharmony_ci{ 4548c2ecf20Sopenharmony_ci const struct v4l2_hw_freq_seek *p = arg; 4558c2ecf20Sopenharmony_ci 4568c2ecf20Sopenharmony_ci pr_cont("tuner=%u, type=%u, seek_upward=%u, wrap_around=%u, spacing=%u, rangelow=%u, rangehigh=%u\n", 4578c2ecf20Sopenharmony_ci p->tuner, p->type, p->seek_upward, p->wrap_around, p->spacing, 4588c2ecf20Sopenharmony_ci p->rangelow, p->rangehigh); 4598c2ecf20Sopenharmony_ci} 4608c2ecf20Sopenharmony_ci 4618c2ecf20Sopenharmony_cistatic void v4l_print_requestbuffers(const void *arg, bool write_only) 4628c2ecf20Sopenharmony_ci{ 4638c2ecf20Sopenharmony_ci const struct v4l2_requestbuffers *p = arg; 4648c2ecf20Sopenharmony_ci 4658c2ecf20Sopenharmony_ci pr_cont("count=%d, type=%s, memory=%s\n", 4668c2ecf20Sopenharmony_ci p->count, 4678c2ecf20Sopenharmony_ci prt_names(p->type, v4l2_type_names), 4688c2ecf20Sopenharmony_ci prt_names(p->memory, v4l2_memory_names)); 4698c2ecf20Sopenharmony_ci} 4708c2ecf20Sopenharmony_ci 4718c2ecf20Sopenharmony_cistatic void v4l_print_buffer(const void *arg, bool write_only) 4728c2ecf20Sopenharmony_ci{ 4738c2ecf20Sopenharmony_ci const struct v4l2_buffer *p = arg; 4748c2ecf20Sopenharmony_ci const struct v4l2_timecode *tc = &p->timecode; 4758c2ecf20Sopenharmony_ci const struct v4l2_plane *plane; 4768c2ecf20Sopenharmony_ci int i; 4778c2ecf20Sopenharmony_ci 4788c2ecf20Sopenharmony_ci pr_cont("%02d:%02d:%02d.%09ld index=%d, type=%s, request_fd=%d, flags=0x%08x, field=%s, sequence=%d, memory=%s", 4798c2ecf20Sopenharmony_ci (int)p->timestamp.tv_sec / 3600, 4808c2ecf20Sopenharmony_ci ((int)p->timestamp.tv_sec / 60) % 60, 4818c2ecf20Sopenharmony_ci ((int)p->timestamp.tv_sec % 60), 4828c2ecf20Sopenharmony_ci (long)p->timestamp.tv_usec, 4838c2ecf20Sopenharmony_ci p->index, 4848c2ecf20Sopenharmony_ci prt_names(p->type, v4l2_type_names), p->request_fd, 4858c2ecf20Sopenharmony_ci p->flags, prt_names(p->field, v4l2_field_names), 4868c2ecf20Sopenharmony_ci p->sequence, prt_names(p->memory, v4l2_memory_names)); 4878c2ecf20Sopenharmony_ci 4888c2ecf20Sopenharmony_ci if (V4L2_TYPE_IS_MULTIPLANAR(p->type) && p->m.planes) { 4898c2ecf20Sopenharmony_ci pr_cont("\n"); 4908c2ecf20Sopenharmony_ci for (i = 0; i < p->length; ++i) { 4918c2ecf20Sopenharmony_ci plane = &p->m.planes[i]; 4928c2ecf20Sopenharmony_ci printk(KERN_DEBUG 4938c2ecf20Sopenharmony_ci "plane %d: bytesused=%d, data_offset=0x%08x, offset/userptr=0x%lx, length=%d\n", 4948c2ecf20Sopenharmony_ci i, plane->bytesused, plane->data_offset, 4958c2ecf20Sopenharmony_ci plane->m.userptr, plane->length); 4968c2ecf20Sopenharmony_ci } 4978c2ecf20Sopenharmony_ci } else { 4988c2ecf20Sopenharmony_ci pr_cont(", bytesused=%d, offset/userptr=0x%lx, length=%d\n", 4998c2ecf20Sopenharmony_ci p->bytesused, p->m.userptr, p->length); 5008c2ecf20Sopenharmony_ci } 5018c2ecf20Sopenharmony_ci 5028c2ecf20Sopenharmony_ci printk(KERN_DEBUG "timecode=%02d:%02d:%02d type=%d, flags=0x%08x, frames=%d, userbits=0x%08x\n", 5038c2ecf20Sopenharmony_ci tc->hours, tc->minutes, tc->seconds, 5048c2ecf20Sopenharmony_ci tc->type, tc->flags, tc->frames, *(__u32 *)tc->userbits); 5058c2ecf20Sopenharmony_ci} 5068c2ecf20Sopenharmony_ci 5078c2ecf20Sopenharmony_cistatic void v4l_print_exportbuffer(const void *arg, bool write_only) 5088c2ecf20Sopenharmony_ci{ 5098c2ecf20Sopenharmony_ci const struct v4l2_exportbuffer *p = arg; 5108c2ecf20Sopenharmony_ci 5118c2ecf20Sopenharmony_ci pr_cont("fd=%d, type=%s, index=%u, plane=%u, flags=0x%08x\n", 5128c2ecf20Sopenharmony_ci p->fd, prt_names(p->type, v4l2_type_names), 5138c2ecf20Sopenharmony_ci p->index, p->plane, p->flags); 5148c2ecf20Sopenharmony_ci} 5158c2ecf20Sopenharmony_ci 5168c2ecf20Sopenharmony_cistatic void v4l_print_create_buffers(const void *arg, bool write_only) 5178c2ecf20Sopenharmony_ci{ 5188c2ecf20Sopenharmony_ci const struct v4l2_create_buffers *p = arg; 5198c2ecf20Sopenharmony_ci 5208c2ecf20Sopenharmony_ci pr_cont("index=%d, count=%d, memory=%s, ", 5218c2ecf20Sopenharmony_ci p->index, p->count, 5228c2ecf20Sopenharmony_ci prt_names(p->memory, v4l2_memory_names)); 5238c2ecf20Sopenharmony_ci v4l_print_format(&p->format, write_only); 5248c2ecf20Sopenharmony_ci} 5258c2ecf20Sopenharmony_ci 5268c2ecf20Sopenharmony_cistatic void v4l_print_streamparm(const void *arg, bool write_only) 5278c2ecf20Sopenharmony_ci{ 5288c2ecf20Sopenharmony_ci const struct v4l2_streamparm *p = arg; 5298c2ecf20Sopenharmony_ci 5308c2ecf20Sopenharmony_ci pr_cont("type=%s", prt_names(p->type, v4l2_type_names)); 5318c2ecf20Sopenharmony_ci 5328c2ecf20Sopenharmony_ci if (p->type == V4L2_BUF_TYPE_VIDEO_CAPTURE || 5338c2ecf20Sopenharmony_ci p->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) { 5348c2ecf20Sopenharmony_ci const struct v4l2_captureparm *c = &p->parm.capture; 5358c2ecf20Sopenharmony_ci 5368c2ecf20Sopenharmony_ci pr_cont(", capability=0x%x, capturemode=0x%x, timeperframe=%d/%d, extendedmode=%d, readbuffers=%d\n", 5378c2ecf20Sopenharmony_ci c->capability, c->capturemode, 5388c2ecf20Sopenharmony_ci c->timeperframe.numerator, c->timeperframe.denominator, 5398c2ecf20Sopenharmony_ci c->extendedmode, c->readbuffers); 5408c2ecf20Sopenharmony_ci } else if (p->type == V4L2_BUF_TYPE_VIDEO_OUTPUT || 5418c2ecf20Sopenharmony_ci p->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) { 5428c2ecf20Sopenharmony_ci const struct v4l2_outputparm *c = &p->parm.output; 5438c2ecf20Sopenharmony_ci 5448c2ecf20Sopenharmony_ci pr_cont(", capability=0x%x, outputmode=0x%x, timeperframe=%d/%d, extendedmode=%d, writebuffers=%d\n", 5458c2ecf20Sopenharmony_ci c->capability, c->outputmode, 5468c2ecf20Sopenharmony_ci c->timeperframe.numerator, c->timeperframe.denominator, 5478c2ecf20Sopenharmony_ci c->extendedmode, c->writebuffers); 5488c2ecf20Sopenharmony_ci } else { 5498c2ecf20Sopenharmony_ci pr_cont("\n"); 5508c2ecf20Sopenharmony_ci } 5518c2ecf20Sopenharmony_ci} 5528c2ecf20Sopenharmony_ci 5538c2ecf20Sopenharmony_cistatic void v4l_print_queryctrl(const void *arg, bool write_only) 5548c2ecf20Sopenharmony_ci{ 5558c2ecf20Sopenharmony_ci const struct v4l2_queryctrl *p = arg; 5568c2ecf20Sopenharmony_ci 5578c2ecf20Sopenharmony_ci pr_cont("id=0x%x, type=%d, name=%.*s, min/max=%d/%d, step=%d, default=%d, flags=0x%08x\n", 5588c2ecf20Sopenharmony_ci p->id, p->type, (int)sizeof(p->name), p->name, 5598c2ecf20Sopenharmony_ci p->minimum, p->maximum, 5608c2ecf20Sopenharmony_ci p->step, p->default_value, p->flags); 5618c2ecf20Sopenharmony_ci} 5628c2ecf20Sopenharmony_ci 5638c2ecf20Sopenharmony_cistatic void v4l_print_query_ext_ctrl(const void *arg, bool write_only) 5648c2ecf20Sopenharmony_ci{ 5658c2ecf20Sopenharmony_ci const struct v4l2_query_ext_ctrl *p = arg; 5668c2ecf20Sopenharmony_ci 5678c2ecf20Sopenharmony_ci 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", 5688c2ecf20Sopenharmony_ci p->id, p->type, (int)sizeof(p->name), p->name, 5698c2ecf20Sopenharmony_ci p->minimum, p->maximum, 5708c2ecf20Sopenharmony_ci p->step, p->default_value, p->flags, 5718c2ecf20Sopenharmony_ci p->elem_size, p->elems, p->nr_of_dims, 5728c2ecf20Sopenharmony_ci p->dims[0], p->dims[1], p->dims[2], p->dims[3]); 5738c2ecf20Sopenharmony_ci} 5748c2ecf20Sopenharmony_ci 5758c2ecf20Sopenharmony_cistatic void v4l_print_querymenu(const void *arg, bool write_only) 5768c2ecf20Sopenharmony_ci{ 5778c2ecf20Sopenharmony_ci const struct v4l2_querymenu *p = arg; 5788c2ecf20Sopenharmony_ci 5798c2ecf20Sopenharmony_ci pr_cont("id=0x%x, index=%d\n", p->id, p->index); 5808c2ecf20Sopenharmony_ci} 5818c2ecf20Sopenharmony_ci 5828c2ecf20Sopenharmony_cistatic void v4l_print_control(const void *arg, bool write_only) 5838c2ecf20Sopenharmony_ci{ 5848c2ecf20Sopenharmony_ci const struct v4l2_control *p = arg; 5858c2ecf20Sopenharmony_ci const char *name = v4l2_ctrl_get_name(p->id); 5868c2ecf20Sopenharmony_ci 5878c2ecf20Sopenharmony_ci if (name) 5888c2ecf20Sopenharmony_ci pr_cont("name=%s, ", name); 5898c2ecf20Sopenharmony_ci pr_cont("id=0x%x, value=%d\n", p->id, p->value); 5908c2ecf20Sopenharmony_ci} 5918c2ecf20Sopenharmony_ci 5928c2ecf20Sopenharmony_cistatic void v4l_print_ext_controls(const void *arg, bool write_only) 5938c2ecf20Sopenharmony_ci{ 5948c2ecf20Sopenharmony_ci const struct v4l2_ext_controls *p = arg; 5958c2ecf20Sopenharmony_ci int i; 5968c2ecf20Sopenharmony_ci 5978c2ecf20Sopenharmony_ci pr_cont("which=0x%x, count=%d, error_idx=%d, request_fd=%d", 5988c2ecf20Sopenharmony_ci p->which, p->count, p->error_idx, p->request_fd); 5998c2ecf20Sopenharmony_ci for (i = 0; i < p->count; i++) { 6008c2ecf20Sopenharmony_ci unsigned int id = p->controls[i].id; 6018c2ecf20Sopenharmony_ci const char *name = v4l2_ctrl_get_name(id); 6028c2ecf20Sopenharmony_ci 6038c2ecf20Sopenharmony_ci if (name) 6048c2ecf20Sopenharmony_ci pr_cont(", name=%s", name); 6058c2ecf20Sopenharmony_ci if (!p->controls[i].size) 6068c2ecf20Sopenharmony_ci pr_cont(", id/val=0x%x/0x%x", id, p->controls[i].value); 6078c2ecf20Sopenharmony_ci else 6088c2ecf20Sopenharmony_ci pr_cont(", id/size=0x%x/%u", id, p->controls[i].size); 6098c2ecf20Sopenharmony_ci } 6108c2ecf20Sopenharmony_ci pr_cont("\n"); 6118c2ecf20Sopenharmony_ci} 6128c2ecf20Sopenharmony_ci 6138c2ecf20Sopenharmony_cistatic void v4l_print_cropcap(const void *arg, bool write_only) 6148c2ecf20Sopenharmony_ci{ 6158c2ecf20Sopenharmony_ci const struct v4l2_cropcap *p = arg; 6168c2ecf20Sopenharmony_ci 6178c2ecf20Sopenharmony_ci pr_cont("type=%s, bounds wxh=%dx%d, x,y=%d,%d, defrect wxh=%dx%d, x,y=%d,%d, pixelaspect %d/%d\n", 6188c2ecf20Sopenharmony_ci prt_names(p->type, v4l2_type_names), 6198c2ecf20Sopenharmony_ci p->bounds.width, p->bounds.height, 6208c2ecf20Sopenharmony_ci p->bounds.left, p->bounds.top, 6218c2ecf20Sopenharmony_ci p->defrect.width, p->defrect.height, 6228c2ecf20Sopenharmony_ci p->defrect.left, p->defrect.top, 6238c2ecf20Sopenharmony_ci p->pixelaspect.numerator, p->pixelaspect.denominator); 6248c2ecf20Sopenharmony_ci} 6258c2ecf20Sopenharmony_ci 6268c2ecf20Sopenharmony_cistatic void v4l_print_crop(const void *arg, bool write_only) 6278c2ecf20Sopenharmony_ci{ 6288c2ecf20Sopenharmony_ci const struct v4l2_crop *p = arg; 6298c2ecf20Sopenharmony_ci 6308c2ecf20Sopenharmony_ci pr_cont("type=%s, wxh=%dx%d, x,y=%d,%d\n", 6318c2ecf20Sopenharmony_ci prt_names(p->type, v4l2_type_names), 6328c2ecf20Sopenharmony_ci p->c.width, p->c.height, 6338c2ecf20Sopenharmony_ci p->c.left, p->c.top); 6348c2ecf20Sopenharmony_ci} 6358c2ecf20Sopenharmony_ci 6368c2ecf20Sopenharmony_cistatic void v4l_print_selection(const void *arg, bool write_only) 6378c2ecf20Sopenharmony_ci{ 6388c2ecf20Sopenharmony_ci const struct v4l2_selection *p = arg; 6398c2ecf20Sopenharmony_ci 6408c2ecf20Sopenharmony_ci pr_cont("type=%s, target=%d, flags=0x%x, wxh=%dx%d, x,y=%d,%d\n", 6418c2ecf20Sopenharmony_ci prt_names(p->type, v4l2_type_names), 6428c2ecf20Sopenharmony_ci p->target, p->flags, 6438c2ecf20Sopenharmony_ci p->r.width, p->r.height, p->r.left, p->r.top); 6448c2ecf20Sopenharmony_ci} 6458c2ecf20Sopenharmony_ci 6468c2ecf20Sopenharmony_cistatic void v4l_print_jpegcompression(const void *arg, bool write_only) 6478c2ecf20Sopenharmony_ci{ 6488c2ecf20Sopenharmony_ci const struct v4l2_jpegcompression *p = arg; 6498c2ecf20Sopenharmony_ci 6508c2ecf20Sopenharmony_ci pr_cont("quality=%d, APPn=%d, APP_len=%d, COM_len=%d, jpeg_markers=0x%x\n", 6518c2ecf20Sopenharmony_ci p->quality, p->APPn, p->APP_len, 6528c2ecf20Sopenharmony_ci p->COM_len, p->jpeg_markers); 6538c2ecf20Sopenharmony_ci} 6548c2ecf20Sopenharmony_ci 6558c2ecf20Sopenharmony_cistatic void v4l_print_enc_idx(const void *arg, bool write_only) 6568c2ecf20Sopenharmony_ci{ 6578c2ecf20Sopenharmony_ci const struct v4l2_enc_idx *p = arg; 6588c2ecf20Sopenharmony_ci 6598c2ecf20Sopenharmony_ci pr_cont("entries=%d, entries_cap=%d\n", 6608c2ecf20Sopenharmony_ci p->entries, p->entries_cap); 6618c2ecf20Sopenharmony_ci} 6628c2ecf20Sopenharmony_ci 6638c2ecf20Sopenharmony_cistatic void v4l_print_encoder_cmd(const void *arg, bool write_only) 6648c2ecf20Sopenharmony_ci{ 6658c2ecf20Sopenharmony_ci const struct v4l2_encoder_cmd *p = arg; 6668c2ecf20Sopenharmony_ci 6678c2ecf20Sopenharmony_ci pr_cont("cmd=%d, flags=0x%x\n", 6688c2ecf20Sopenharmony_ci p->cmd, p->flags); 6698c2ecf20Sopenharmony_ci} 6708c2ecf20Sopenharmony_ci 6718c2ecf20Sopenharmony_cistatic void v4l_print_decoder_cmd(const void *arg, bool write_only) 6728c2ecf20Sopenharmony_ci{ 6738c2ecf20Sopenharmony_ci const struct v4l2_decoder_cmd *p = arg; 6748c2ecf20Sopenharmony_ci 6758c2ecf20Sopenharmony_ci pr_cont("cmd=%d, flags=0x%x\n", p->cmd, p->flags); 6768c2ecf20Sopenharmony_ci 6778c2ecf20Sopenharmony_ci if (p->cmd == V4L2_DEC_CMD_START) 6788c2ecf20Sopenharmony_ci pr_info("speed=%d, format=%u\n", 6798c2ecf20Sopenharmony_ci p->start.speed, p->start.format); 6808c2ecf20Sopenharmony_ci else if (p->cmd == V4L2_DEC_CMD_STOP) 6818c2ecf20Sopenharmony_ci pr_info("pts=%llu\n", p->stop.pts); 6828c2ecf20Sopenharmony_ci} 6838c2ecf20Sopenharmony_ci 6848c2ecf20Sopenharmony_cistatic void v4l_print_dbg_chip_info(const void *arg, bool write_only) 6858c2ecf20Sopenharmony_ci{ 6868c2ecf20Sopenharmony_ci const struct v4l2_dbg_chip_info *p = arg; 6878c2ecf20Sopenharmony_ci 6888c2ecf20Sopenharmony_ci pr_cont("type=%u, ", p->match.type); 6898c2ecf20Sopenharmony_ci if (p->match.type == V4L2_CHIP_MATCH_I2C_DRIVER) 6908c2ecf20Sopenharmony_ci pr_cont("name=%.*s, ", 6918c2ecf20Sopenharmony_ci (int)sizeof(p->match.name), p->match.name); 6928c2ecf20Sopenharmony_ci else 6938c2ecf20Sopenharmony_ci pr_cont("addr=%u, ", p->match.addr); 6948c2ecf20Sopenharmony_ci pr_cont("name=%.*s\n", (int)sizeof(p->name), p->name); 6958c2ecf20Sopenharmony_ci} 6968c2ecf20Sopenharmony_ci 6978c2ecf20Sopenharmony_cistatic void v4l_print_dbg_register(const void *arg, bool write_only) 6988c2ecf20Sopenharmony_ci{ 6998c2ecf20Sopenharmony_ci const struct v4l2_dbg_register *p = arg; 7008c2ecf20Sopenharmony_ci 7018c2ecf20Sopenharmony_ci pr_cont("type=%u, ", p->match.type); 7028c2ecf20Sopenharmony_ci if (p->match.type == V4L2_CHIP_MATCH_I2C_DRIVER) 7038c2ecf20Sopenharmony_ci pr_cont("name=%.*s, ", 7048c2ecf20Sopenharmony_ci (int)sizeof(p->match.name), p->match.name); 7058c2ecf20Sopenharmony_ci else 7068c2ecf20Sopenharmony_ci pr_cont("addr=%u, ", p->match.addr); 7078c2ecf20Sopenharmony_ci pr_cont("reg=0x%llx, val=0x%llx\n", 7088c2ecf20Sopenharmony_ci p->reg, p->val); 7098c2ecf20Sopenharmony_ci} 7108c2ecf20Sopenharmony_ci 7118c2ecf20Sopenharmony_cistatic void v4l_print_dv_timings(const void *arg, bool write_only) 7128c2ecf20Sopenharmony_ci{ 7138c2ecf20Sopenharmony_ci const struct v4l2_dv_timings *p = arg; 7148c2ecf20Sopenharmony_ci 7158c2ecf20Sopenharmony_ci switch (p->type) { 7168c2ecf20Sopenharmony_ci case V4L2_DV_BT_656_1120: 7178c2ecf20Sopenharmony_ci 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", 7188c2ecf20Sopenharmony_ci p->bt.interlaced, p->bt.pixelclock, 7198c2ecf20Sopenharmony_ci p->bt.width, p->bt.height, 7208c2ecf20Sopenharmony_ci p->bt.polarities, p->bt.hfrontporch, 7218c2ecf20Sopenharmony_ci p->bt.hsync, p->bt.hbackporch, 7228c2ecf20Sopenharmony_ci p->bt.vfrontporch, p->bt.vsync, 7238c2ecf20Sopenharmony_ci p->bt.vbackporch, p->bt.il_vfrontporch, 7248c2ecf20Sopenharmony_ci p->bt.il_vsync, p->bt.il_vbackporch, 7258c2ecf20Sopenharmony_ci p->bt.standards, p->bt.flags); 7268c2ecf20Sopenharmony_ci break; 7278c2ecf20Sopenharmony_ci default: 7288c2ecf20Sopenharmony_ci pr_cont("type=%d\n", p->type); 7298c2ecf20Sopenharmony_ci break; 7308c2ecf20Sopenharmony_ci } 7318c2ecf20Sopenharmony_ci} 7328c2ecf20Sopenharmony_ci 7338c2ecf20Sopenharmony_cistatic void v4l_print_enum_dv_timings(const void *arg, bool write_only) 7348c2ecf20Sopenharmony_ci{ 7358c2ecf20Sopenharmony_ci const struct v4l2_enum_dv_timings *p = arg; 7368c2ecf20Sopenharmony_ci 7378c2ecf20Sopenharmony_ci pr_cont("index=%u, ", p->index); 7388c2ecf20Sopenharmony_ci v4l_print_dv_timings(&p->timings, write_only); 7398c2ecf20Sopenharmony_ci} 7408c2ecf20Sopenharmony_ci 7418c2ecf20Sopenharmony_cistatic void v4l_print_dv_timings_cap(const void *arg, bool write_only) 7428c2ecf20Sopenharmony_ci{ 7438c2ecf20Sopenharmony_ci const struct v4l2_dv_timings_cap *p = arg; 7448c2ecf20Sopenharmony_ci 7458c2ecf20Sopenharmony_ci switch (p->type) { 7468c2ecf20Sopenharmony_ci case V4L2_DV_BT_656_1120: 7478c2ecf20Sopenharmony_ci pr_cont("type=bt-656/1120, width=%u-%u, height=%u-%u, pixelclock=%llu-%llu, standards=0x%x, capabilities=0x%x\n", 7488c2ecf20Sopenharmony_ci p->bt.min_width, p->bt.max_width, 7498c2ecf20Sopenharmony_ci p->bt.min_height, p->bt.max_height, 7508c2ecf20Sopenharmony_ci p->bt.min_pixelclock, p->bt.max_pixelclock, 7518c2ecf20Sopenharmony_ci p->bt.standards, p->bt.capabilities); 7528c2ecf20Sopenharmony_ci break; 7538c2ecf20Sopenharmony_ci default: 7548c2ecf20Sopenharmony_ci pr_cont("type=%u\n", p->type); 7558c2ecf20Sopenharmony_ci break; 7568c2ecf20Sopenharmony_ci } 7578c2ecf20Sopenharmony_ci} 7588c2ecf20Sopenharmony_ci 7598c2ecf20Sopenharmony_cistatic void v4l_print_frmsizeenum(const void *arg, bool write_only) 7608c2ecf20Sopenharmony_ci{ 7618c2ecf20Sopenharmony_ci const struct v4l2_frmsizeenum *p = arg; 7628c2ecf20Sopenharmony_ci 7638c2ecf20Sopenharmony_ci pr_cont("index=%u, pixelformat=%c%c%c%c, type=%u", 7648c2ecf20Sopenharmony_ci p->index, 7658c2ecf20Sopenharmony_ci (p->pixel_format & 0xff), 7668c2ecf20Sopenharmony_ci (p->pixel_format >> 8) & 0xff, 7678c2ecf20Sopenharmony_ci (p->pixel_format >> 16) & 0xff, 7688c2ecf20Sopenharmony_ci (p->pixel_format >> 24) & 0xff, 7698c2ecf20Sopenharmony_ci p->type); 7708c2ecf20Sopenharmony_ci switch (p->type) { 7718c2ecf20Sopenharmony_ci case V4L2_FRMSIZE_TYPE_DISCRETE: 7728c2ecf20Sopenharmony_ci pr_cont(", wxh=%ux%u\n", 7738c2ecf20Sopenharmony_ci p->discrete.width, p->discrete.height); 7748c2ecf20Sopenharmony_ci break; 7758c2ecf20Sopenharmony_ci case V4L2_FRMSIZE_TYPE_STEPWISE: 7768c2ecf20Sopenharmony_ci pr_cont(", min=%ux%u, max=%ux%u, step=%ux%u\n", 7778c2ecf20Sopenharmony_ci p->stepwise.min_width, 7788c2ecf20Sopenharmony_ci p->stepwise.min_height, 7798c2ecf20Sopenharmony_ci p->stepwise.max_width, 7808c2ecf20Sopenharmony_ci p->stepwise.max_height, 7818c2ecf20Sopenharmony_ci p->stepwise.step_width, 7828c2ecf20Sopenharmony_ci p->stepwise.step_height); 7838c2ecf20Sopenharmony_ci break; 7848c2ecf20Sopenharmony_ci case V4L2_FRMSIZE_TYPE_CONTINUOUS: 7858c2ecf20Sopenharmony_ci default: 7868c2ecf20Sopenharmony_ci pr_cont("\n"); 7878c2ecf20Sopenharmony_ci break; 7888c2ecf20Sopenharmony_ci } 7898c2ecf20Sopenharmony_ci} 7908c2ecf20Sopenharmony_ci 7918c2ecf20Sopenharmony_cistatic void v4l_print_frmivalenum(const void *arg, bool write_only) 7928c2ecf20Sopenharmony_ci{ 7938c2ecf20Sopenharmony_ci const struct v4l2_frmivalenum *p = arg; 7948c2ecf20Sopenharmony_ci 7958c2ecf20Sopenharmony_ci pr_cont("index=%u, pixelformat=%c%c%c%c, wxh=%ux%u, type=%u", 7968c2ecf20Sopenharmony_ci p->index, 7978c2ecf20Sopenharmony_ci (p->pixel_format & 0xff), 7988c2ecf20Sopenharmony_ci (p->pixel_format >> 8) & 0xff, 7998c2ecf20Sopenharmony_ci (p->pixel_format >> 16) & 0xff, 8008c2ecf20Sopenharmony_ci (p->pixel_format >> 24) & 0xff, 8018c2ecf20Sopenharmony_ci p->width, p->height, p->type); 8028c2ecf20Sopenharmony_ci switch (p->type) { 8038c2ecf20Sopenharmony_ci case V4L2_FRMIVAL_TYPE_DISCRETE: 8048c2ecf20Sopenharmony_ci pr_cont(", fps=%d/%d\n", 8058c2ecf20Sopenharmony_ci p->discrete.numerator, 8068c2ecf20Sopenharmony_ci p->discrete.denominator); 8078c2ecf20Sopenharmony_ci break; 8088c2ecf20Sopenharmony_ci case V4L2_FRMIVAL_TYPE_STEPWISE: 8098c2ecf20Sopenharmony_ci pr_cont(", min=%d/%d, max=%d/%d, step=%d/%d\n", 8108c2ecf20Sopenharmony_ci p->stepwise.min.numerator, 8118c2ecf20Sopenharmony_ci p->stepwise.min.denominator, 8128c2ecf20Sopenharmony_ci p->stepwise.max.numerator, 8138c2ecf20Sopenharmony_ci p->stepwise.max.denominator, 8148c2ecf20Sopenharmony_ci p->stepwise.step.numerator, 8158c2ecf20Sopenharmony_ci p->stepwise.step.denominator); 8168c2ecf20Sopenharmony_ci break; 8178c2ecf20Sopenharmony_ci case V4L2_FRMIVAL_TYPE_CONTINUOUS: 8188c2ecf20Sopenharmony_ci default: 8198c2ecf20Sopenharmony_ci pr_cont("\n"); 8208c2ecf20Sopenharmony_ci break; 8218c2ecf20Sopenharmony_ci } 8228c2ecf20Sopenharmony_ci} 8238c2ecf20Sopenharmony_ci 8248c2ecf20Sopenharmony_cistatic void v4l_print_event(const void *arg, bool write_only) 8258c2ecf20Sopenharmony_ci{ 8268c2ecf20Sopenharmony_ci const struct v4l2_event *p = arg; 8278c2ecf20Sopenharmony_ci const struct v4l2_event_ctrl *c; 8288c2ecf20Sopenharmony_ci 8298c2ecf20Sopenharmony_ci pr_cont("type=0x%x, pending=%u, sequence=%u, id=%u, timestamp=%llu.%9.9llu\n", 8308c2ecf20Sopenharmony_ci p->type, p->pending, p->sequence, p->id, 8318c2ecf20Sopenharmony_ci p->timestamp.tv_sec, p->timestamp.tv_nsec); 8328c2ecf20Sopenharmony_ci switch (p->type) { 8338c2ecf20Sopenharmony_ci case V4L2_EVENT_VSYNC: 8348c2ecf20Sopenharmony_ci printk(KERN_DEBUG "field=%s\n", 8358c2ecf20Sopenharmony_ci prt_names(p->u.vsync.field, v4l2_field_names)); 8368c2ecf20Sopenharmony_ci break; 8378c2ecf20Sopenharmony_ci case V4L2_EVENT_CTRL: 8388c2ecf20Sopenharmony_ci c = &p->u.ctrl; 8398c2ecf20Sopenharmony_ci printk(KERN_DEBUG "changes=0x%x, type=%u, ", 8408c2ecf20Sopenharmony_ci c->changes, c->type); 8418c2ecf20Sopenharmony_ci if (c->type == V4L2_CTRL_TYPE_INTEGER64) 8428c2ecf20Sopenharmony_ci pr_cont("value64=%lld, ", c->value64); 8438c2ecf20Sopenharmony_ci else 8448c2ecf20Sopenharmony_ci pr_cont("value=%d, ", c->value); 8458c2ecf20Sopenharmony_ci pr_cont("flags=0x%x, minimum=%d, maximum=%d, step=%d, default_value=%d\n", 8468c2ecf20Sopenharmony_ci c->flags, c->minimum, c->maximum, 8478c2ecf20Sopenharmony_ci c->step, c->default_value); 8488c2ecf20Sopenharmony_ci break; 8498c2ecf20Sopenharmony_ci case V4L2_EVENT_FRAME_SYNC: 8508c2ecf20Sopenharmony_ci pr_cont("frame_sequence=%u\n", 8518c2ecf20Sopenharmony_ci p->u.frame_sync.frame_sequence); 8528c2ecf20Sopenharmony_ci break; 8538c2ecf20Sopenharmony_ci } 8548c2ecf20Sopenharmony_ci} 8558c2ecf20Sopenharmony_ci 8568c2ecf20Sopenharmony_cistatic void v4l_print_event_subscription(const void *arg, bool write_only) 8578c2ecf20Sopenharmony_ci{ 8588c2ecf20Sopenharmony_ci const struct v4l2_event_subscription *p = arg; 8598c2ecf20Sopenharmony_ci 8608c2ecf20Sopenharmony_ci pr_cont("type=0x%x, id=0x%x, flags=0x%x\n", 8618c2ecf20Sopenharmony_ci p->type, p->id, p->flags); 8628c2ecf20Sopenharmony_ci} 8638c2ecf20Sopenharmony_ci 8648c2ecf20Sopenharmony_cistatic void v4l_print_sliced_vbi_cap(const void *arg, bool write_only) 8658c2ecf20Sopenharmony_ci{ 8668c2ecf20Sopenharmony_ci const struct v4l2_sliced_vbi_cap *p = arg; 8678c2ecf20Sopenharmony_ci int i; 8688c2ecf20Sopenharmony_ci 8698c2ecf20Sopenharmony_ci pr_cont("type=%s, service_set=0x%08x\n", 8708c2ecf20Sopenharmony_ci prt_names(p->type, v4l2_type_names), p->service_set); 8718c2ecf20Sopenharmony_ci for (i = 0; i < 24; i++) 8728c2ecf20Sopenharmony_ci printk(KERN_DEBUG "line[%02u]=0x%04x, 0x%04x\n", i, 8738c2ecf20Sopenharmony_ci p->service_lines[0][i], 8748c2ecf20Sopenharmony_ci p->service_lines[1][i]); 8758c2ecf20Sopenharmony_ci} 8768c2ecf20Sopenharmony_ci 8778c2ecf20Sopenharmony_cistatic void v4l_print_freq_band(const void *arg, bool write_only) 8788c2ecf20Sopenharmony_ci{ 8798c2ecf20Sopenharmony_ci const struct v4l2_frequency_band *p = arg; 8808c2ecf20Sopenharmony_ci 8818c2ecf20Sopenharmony_ci pr_cont("tuner=%u, type=%u, index=%u, capability=0x%x, rangelow=%u, rangehigh=%u, modulation=0x%x\n", 8828c2ecf20Sopenharmony_ci p->tuner, p->type, p->index, 8838c2ecf20Sopenharmony_ci p->capability, p->rangelow, 8848c2ecf20Sopenharmony_ci p->rangehigh, p->modulation); 8858c2ecf20Sopenharmony_ci} 8868c2ecf20Sopenharmony_ci 8878c2ecf20Sopenharmony_cistatic void v4l_print_edid(const void *arg, bool write_only) 8888c2ecf20Sopenharmony_ci{ 8898c2ecf20Sopenharmony_ci const struct v4l2_edid *p = arg; 8908c2ecf20Sopenharmony_ci 8918c2ecf20Sopenharmony_ci pr_cont("pad=%u, start_block=%u, blocks=%u\n", 8928c2ecf20Sopenharmony_ci p->pad, p->start_block, p->blocks); 8938c2ecf20Sopenharmony_ci} 8948c2ecf20Sopenharmony_ci 8958c2ecf20Sopenharmony_cistatic void v4l_print_u32(const void *arg, bool write_only) 8968c2ecf20Sopenharmony_ci{ 8978c2ecf20Sopenharmony_ci pr_cont("value=%u\n", *(const u32 *)arg); 8988c2ecf20Sopenharmony_ci} 8998c2ecf20Sopenharmony_ci 9008c2ecf20Sopenharmony_cistatic void v4l_print_newline(const void *arg, bool write_only) 9018c2ecf20Sopenharmony_ci{ 9028c2ecf20Sopenharmony_ci pr_cont("\n"); 9038c2ecf20Sopenharmony_ci} 9048c2ecf20Sopenharmony_ci 9058c2ecf20Sopenharmony_cistatic void v4l_print_default(const void *arg, bool write_only) 9068c2ecf20Sopenharmony_ci{ 9078c2ecf20Sopenharmony_ci pr_cont("driver-specific ioctl\n"); 9088c2ecf20Sopenharmony_ci} 9098c2ecf20Sopenharmony_ci 9108c2ecf20Sopenharmony_cistatic bool check_ext_ctrls(struct v4l2_ext_controls *c, unsigned long ioctl) 9118c2ecf20Sopenharmony_ci{ 9128c2ecf20Sopenharmony_ci __u32 i; 9138c2ecf20Sopenharmony_ci 9148c2ecf20Sopenharmony_ci /* zero the reserved fields */ 9158c2ecf20Sopenharmony_ci c->reserved[0] = 0; 9168c2ecf20Sopenharmony_ci for (i = 0; i < c->count; i++) 9178c2ecf20Sopenharmony_ci c->controls[i].reserved2[0] = 0; 9188c2ecf20Sopenharmony_ci 9198c2ecf20Sopenharmony_ci switch (c->which) { 9208c2ecf20Sopenharmony_ci case V4L2_CID_PRIVATE_BASE: 9218c2ecf20Sopenharmony_ci /* 9228c2ecf20Sopenharmony_ci * V4L2_CID_PRIVATE_BASE cannot be used as control class 9238c2ecf20Sopenharmony_ci * when using extended controls. 9248c2ecf20Sopenharmony_ci * Only when passed in through VIDIOC_G_CTRL and VIDIOC_S_CTRL 9258c2ecf20Sopenharmony_ci * is it allowed for backwards compatibility. 9268c2ecf20Sopenharmony_ci */ 9278c2ecf20Sopenharmony_ci if (ioctl == VIDIOC_G_CTRL || ioctl == VIDIOC_S_CTRL) 9288c2ecf20Sopenharmony_ci return false; 9298c2ecf20Sopenharmony_ci break; 9308c2ecf20Sopenharmony_ci case V4L2_CTRL_WHICH_DEF_VAL: 9318c2ecf20Sopenharmony_ci /* Default value cannot be changed */ 9328c2ecf20Sopenharmony_ci if (ioctl == VIDIOC_S_EXT_CTRLS || 9338c2ecf20Sopenharmony_ci ioctl == VIDIOC_TRY_EXT_CTRLS) { 9348c2ecf20Sopenharmony_ci c->error_idx = c->count; 9358c2ecf20Sopenharmony_ci return false; 9368c2ecf20Sopenharmony_ci } 9378c2ecf20Sopenharmony_ci return true; 9388c2ecf20Sopenharmony_ci case V4L2_CTRL_WHICH_CUR_VAL: 9398c2ecf20Sopenharmony_ci return true; 9408c2ecf20Sopenharmony_ci case V4L2_CTRL_WHICH_REQUEST_VAL: 9418c2ecf20Sopenharmony_ci c->error_idx = c->count; 9428c2ecf20Sopenharmony_ci return false; 9438c2ecf20Sopenharmony_ci } 9448c2ecf20Sopenharmony_ci 9458c2ecf20Sopenharmony_ci /* Check that all controls are from the same control class. */ 9468c2ecf20Sopenharmony_ci for (i = 0; i < c->count; i++) { 9478c2ecf20Sopenharmony_ci if (V4L2_CTRL_ID2WHICH(c->controls[i].id) != c->which) { 9488c2ecf20Sopenharmony_ci c->error_idx = ioctl == VIDIOC_TRY_EXT_CTRLS ? i : 9498c2ecf20Sopenharmony_ci c->count; 9508c2ecf20Sopenharmony_ci return false; 9518c2ecf20Sopenharmony_ci } 9528c2ecf20Sopenharmony_ci } 9538c2ecf20Sopenharmony_ci return true; 9548c2ecf20Sopenharmony_ci} 9558c2ecf20Sopenharmony_ci 9568c2ecf20Sopenharmony_cistatic int check_fmt(struct file *file, enum v4l2_buf_type type) 9578c2ecf20Sopenharmony_ci{ 9588c2ecf20Sopenharmony_ci const u32 vid_caps = V4L2_CAP_VIDEO_CAPTURE | 9598c2ecf20Sopenharmony_ci V4L2_CAP_VIDEO_CAPTURE_MPLANE | 9608c2ecf20Sopenharmony_ci V4L2_CAP_VIDEO_OUTPUT | 9618c2ecf20Sopenharmony_ci V4L2_CAP_VIDEO_OUTPUT_MPLANE | 9628c2ecf20Sopenharmony_ci V4L2_CAP_VIDEO_M2M | V4L2_CAP_VIDEO_M2M_MPLANE; 9638c2ecf20Sopenharmony_ci const u32 meta_caps = V4L2_CAP_META_CAPTURE | 9648c2ecf20Sopenharmony_ci V4L2_CAP_META_OUTPUT; 9658c2ecf20Sopenharmony_ci struct video_device *vfd = video_devdata(file); 9668c2ecf20Sopenharmony_ci const struct v4l2_ioctl_ops *ops = vfd->ioctl_ops; 9678c2ecf20Sopenharmony_ci bool is_vid = vfd->vfl_type == VFL_TYPE_VIDEO && 9688c2ecf20Sopenharmony_ci (vfd->device_caps & vid_caps); 9698c2ecf20Sopenharmony_ci bool is_vbi = vfd->vfl_type == VFL_TYPE_VBI; 9708c2ecf20Sopenharmony_ci bool is_sdr = vfd->vfl_type == VFL_TYPE_SDR; 9718c2ecf20Sopenharmony_ci bool is_tch = vfd->vfl_type == VFL_TYPE_TOUCH; 9728c2ecf20Sopenharmony_ci bool is_meta = vfd->vfl_type == VFL_TYPE_VIDEO && 9738c2ecf20Sopenharmony_ci (vfd->device_caps & meta_caps); 9748c2ecf20Sopenharmony_ci bool is_rx = vfd->vfl_dir != VFL_DIR_TX; 9758c2ecf20Sopenharmony_ci bool is_tx = vfd->vfl_dir != VFL_DIR_RX; 9768c2ecf20Sopenharmony_ci 9778c2ecf20Sopenharmony_ci if (ops == NULL) 9788c2ecf20Sopenharmony_ci return -EINVAL; 9798c2ecf20Sopenharmony_ci 9808c2ecf20Sopenharmony_ci switch (type) { 9818c2ecf20Sopenharmony_ci case V4L2_BUF_TYPE_VIDEO_CAPTURE: 9828c2ecf20Sopenharmony_ci if ((is_vid || is_tch) && is_rx && 9838c2ecf20Sopenharmony_ci (ops->vidioc_g_fmt_vid_cap || ops->vidioc_g_fmt_vid_cap_mplane)) 9848c2ecf20Sopenharmony_ci return 0; 9858c2ecf20Sopenharmony_ci break; 9868c2ecf20Sopenharmony_ci case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE: 9878c2ecf20Sopenharmony_ci if ((is_vid || is_tch) && is_rx && ops->vidioc_g_fmt_vid_cap_mplane) 9888c2ecf20Sopenharmony_ci return 0; 9898c2ecf20Sopenharmony_ci break; 9908c2ecf20Sopenharmony_ci case V4L2_BUF_TYPE_VIDEO_OVERLAY: 9918c2ecf20Sopenharmony_ci if (is_vid && is_rx && ops->vidioc_g_fmt_vid_overlay) 9928c2ecf20Sopenharmony_ci return 0; 9938c2ecf20Sopenharmony_ci break; 9948c2ecf20Sopenharmony_ci case V4L2_BUF_TYPE_VIDEO_OUTPUT: 9958c2ecf20Sopenharmony_ci if (is_vid && is_tx && 9968c2ecf20Sopenharmony_ci (ops->vidioc_g_fmt_vid_out || ops->vidioc_g_fmt_vid_out_mplane)) 9978c2ecf20Sopenharmony_ci return 0; 9988c2ecf20Sopenharmony_ci break; 9998c2ecf20Sopenharmony_ci case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE: 10008c2ecf20Sopenharmony_ci if (is_vid && is_tx && ops->vidioc_g_fmt_vid_out_mplane) 10018c2ecf20Sopenharmony_ci return 0; 10028c2ecf20Sopenharmony_ci break; 10038c2ecf20Sopenharmony_ci case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY: 10048c2ecf20Sopenharmony_ci if (is_vid && is_tx && ops->vidioc_g_fmt_vid_out_overlay) 10058c2ecf20Sopenharmony_ci return 0; 10068c2ecf20Sopenharmony_ci break; 10078c2ecf20Sopenharmony_ci case V4L2_BUF_TYPE_VBI_CAPTURE: 10088c2ecf20Sopenharmony_ci if (is_vbi && is_rx && ops->vidioc_g_fmt_vbi_cap) 10098c2ecf20Sopenharmony_ci return 0; 10108c2ecf20Sopenharmony_ci break; 10118c2ecf20Sopenharmony_ci case V4L2_BUF_TYPE_VBI_OUTPUT: 10128c2ecf20Sopenharmony_ci if (is_vbi && is_tx && ops->vidioc_g_fmt_vbi_out) 10138c2ecf20Sopenharmony_ci return 0; 10148c2ecf20Sopenharmony_ci break; 10158c2ecf20Sopenharmony_ci case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE: 10168c2ecf20Sopenharmony_ci if (is_vbi && is_rx && ops->vidioc_g_fmt_sliced_vbi_cap) 10178c2ecf20Sopenharmony_ci return 0; 10188c2ecf20Sopenharmony_ci break; 10198c2ecf20Sopenharmony_ci case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT: 10208c2ecf20Sopenharmony_ci if (is_vbi && is_tx && ops->vidioc_g_fmt_sliced_vbi_out) 10218c2ecf20Sopenharmony_ci return 0; 10228c2ecf20Sopenharmony_ci break; 10238c2ecf20Sopenharmony_ci case V4L2_BUF_TYPE_SDR_CAPTURE: 10248c2ecf20Sopenharmony_ci if (is_sdr && is_rx && ops->vidioc_g_fmt_sdr_cap) 10258c2ecf20Sopenharmony_ci return 0; 10268c2ecf20Sopenharmony_ci break; 10278c2ecf20Sopenharmony_ci case V4L2_BUF_TYPE_SDR_OUTPUT: 10288c2ecf20Sopenharmony_ci if (is_sdr && is_tx && ops->vidioc_g_fmt_sdr_out) 10298c2ecf20Sopenharmony_ci return 0; 10308c2ecf20Sopenharmony_ci break; 10318c2ecf20Sopenharmony_ci case V4L2_BUF_TYPE_META_CAPTURE: 10328c2ecf20Sopenharmony_ci if (is_meta && is_rx && ops->vidioc_g_fmt_meta_cap) 10338c2ecf20Sopenharmony_ci return 0; 10348c2ecf20Sopenharmony_ci break; 10358c2ecf20Sopenharmony_ci case V4L2_BUF_TYPE_META_OUTPUT: 10368c2ecf20Sopenharmony_ci if (is_meta && is_tx && ops->vidioc_g_fmt_meta_out) 10378c2ecf20Sopenharmony_ci return 0; 10388c2ecf20Sopenharmony_ci break; 10398c2ecf20Sopenharmony_ci default: 10408c2ecf20Sopenharmony_ci break; 10418c2ecf20Sopenharmony_ci } 10428c2ecf20Sopenharmony_ci return -EINVAL; 10438c2ecf20Sopenharmony_ci} 10448c2ecf20Sopenharmony_ci 10458c2ecf20Sopenharmony_cistatic void v4l_sanitize_format(struct v4l2_format *fmt) 10468c2ecf20Sopenharmony_ci{ 10478c2ecf20Sopenharmony_ci unsigned int offset; 10488c2ecf20Sopenharmony_ci 10498c2ecf20Sopenharmony_ci /* Make sure num_planes is not bogus */ 10508c2ecf20Sopenharmony_ci if (fmt->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE || 10518c2ecf20Sopenharmony_ci fmt->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) 10528c2ecf20Sopenharmony_ci fmt->fmt.pix_mp.num_planes = min_t(u32, fmt->fmt.pix_mp.num_planes, 10538c2ecf20Sopenharmony_ci VIDEO_MAX_PLANES); 10548c2ecf20Sopenharmony_ci 10558c2ecf20Sopenharmony_ci /* 10568c2ecf20Sopenharmony_ci * The v4l2_pix_format structure has been extended with fields that were 10578c2ecf20Sopenharmony_ci * not previously required to be set to zero by applications. The priv 10588c2ecf20Sopenharmony_ci * field, when set to a magic value, indicates the the extended fields 10598c2ecf20Sopenharmony_ci * are valid. Otherwise they will contain undefined values. To simplify 10608c2ecf20Sopenharmony_ci * the API towards drivers zero the extended fields and set the priv 10618c2ecf20Sopenharmony_ci * field to the magic value when the extended pixel format structure 10628c2ecf20Sopenharmony_ci * isn't used by applications. 10638c2ecf20Sopenharmony_ci */ 10648c2ecf20Sopenharmony_ci 10658c2ecf20Sopenharmony_ci if (fmt->type != V4L2_BUF_TYPE_VIDEO_CAPTURE && 10668c2ecf20Sopenharmony_ci fmt->type != V4L2_BUF_TYPE_VIDEO_OUTPUT) 10678c2ecf20Sopenharmony_ci return; 10688c2ecf20Sopenharmony_ci 10698c2ecf20Sopenharmony_ci if (fmt->fmt.pix.priv == V4L2_PIX_FMT_PRIV_MAGIC) 10708c2ecf20Sopenharmony_ci return; 10718c2ecf20Sopenharmony_ci 10728c2ecf20Sopenharmony_ci fmt->fmt.pix.priv = V4L2_PIX_FMT_PRIV_MAGIC; 10738c2ecf20Sopenharmony_ci 10748c2ecf20Sopenharmony_ci offset = offsetof(struct v4l2_pix_format, priv) 10758c2ecf20Sopenharmony_ci + sizeof(fmt->fmt.pix.priv); 10768c2ecf20Sopenharmony_ci memset(((void *)&fmt->fmt.pix) + offset, 0, 10778c2ecf20Sopenharmony_ci sizeof(fmt->fmt.pix) - offset); 10788c2ecf20Sopenharmony_ci} 10798c2ecf20Sopenharmony_ci 10808c2ecf20Sopenharmony_cistatic int v4l_querycap(const struct v4l2_ioctl_ops *ops, 10818c2ecf20Sopenharmony_ci struct file *file, void *fh, void *arg) 10828c2ecf20Sopenharmony_ci{ 10838c2ecf20Sopenharmony_ci struct v4l2_capability *cap = (struct v4l2_capability *)arg; 10848c2ecf20Sopenharmony_ci struct video_device *vfd = video_devdata(file); 10858c2ecf20Sopenharmony_ci int ret; 10868c2ecf20Sopenharmony_ci 10878c2ecf20Sopenharmony_ci cap->version = LINUX_VERSION_CODE; 10888c2ecf20Sopenharmony_ci cap->device_caps = vfd->device_caps; 10898c2ecf20Sopenharmony_ci cap->capabilities = vfd->device_caps | V4L2_CAP_DEVICE_CAPS; 10908c2ecf20Sopenharmony_ci 10918c2ecf20Sopenharmony_ci ret = ops->vidioc_querycap(file, fh, cap); 10928c2ecf20Sopenharmony_ci 10938c2ecf20Sopenharmony_ci /* 10948c2ecf20Sopenharmony_ci * Drivers must not change device_caps, so check for this and 10958c2ecf20Sopenharmony_ci * warn if this happened. 10968c2ecf20Sopenharmony_ci */ 10978c2ecf20Sopenharmony_ci WARN_ON(cap->device_caps != vfd->device_caps); 10988c2ecf20Sopenharmony_ci /* 10998c2ecf20Sopenharmony_ci * Check that capabilities is a superset of 11008c2ecf20Sopenharmony_ci * vfd->device_caps | V4L2_CAP_DEVICE_CAPS 11018c2ecf20Sopenharmony_ci */ 11028c2ecf20Sopenharmony_ci WARN_ON((cap->capabilities & 11038c2ecf20Sopenharmony_ci (vfd->device_caps | V4L2_CAP_DEVICE_CAPS)) != 11048c2ecf20Sopenharmony_ci (vfd->device_caps | V4L2_CAP_DEVICE_CAPS)); 11058c2ecf20Sopenharmony_ci cap->capabilities |= V4L2_CAP_EXT_PIX_FORMAT; 11068c2ecf20Sopenharmony_ci cap->device_caps |= V4L2_CAP_EXT_PIX_FORMAT; 11078c2ecf20Sopenharmony_ci 11088c2ecf20Sopenharmony_ci return ret; 11098c2ecf20Sopenharmony_ci} 11108c2ecf20Sopenharmony_ci 11118c2ecf20Sopenharmony_cistatic int v4l_g_input(const struct v4l2_ioctl_ops *ops, 11128c2ecf20Sopenharmony_ci struct file *file, void *fh, void *arg) 11138c2ecf20Sopenharmony_ci{ 11148c2ecf20Sopenharmony_ci struct video_device *vfd = video_devdata(file); 11158c2ecf20Sopenharmony_ci 11168c2ecf20Sopenharmony_ci if (vfd->device_caps & V4L2_CAP_IO_MC) { 11178c2ecf20Sopenharmony_ci *(int *)arg = 0; 11188c2ecf20Sopenharmony_ci return 0; 11198c2ecf20Sopenharmony_ci } 11208c2ecf20Sopenharmony_ci 11218c2ecf20Sopenharmony_ci return ops->vidioc_g_input(file, fh, arg); 11228c2ecf20Sopenharmony_ci} 11238c2ecf20Sopenharmony_ci 11248c2ecf20Sopenharmony_cistatic int v4l_g_output(const struct v4l2_ioctl_ops *ops, 11258c2ecf20Sopenharmony_ci struct file *file, void *fh, void *arg) 11268c2ecf20Sopenharmony_ci{ 11278c2ecf20Sopenharmony_ci struct video_device *vfd = video_devdata(file); 11288c2ecf20Sopenharmony_ci 11298c2ecf20Sopenharmony_ci if (vfd->device_caps & V4L2_CAP_IO_MC) { 11308c2ecf20Sopenharmony_ci *(int *)arg = 0; 11318c2ecf20Sopenharmony_ci return 0; 11328c2ecf20Sopenharmony_ci } 11338c2ecf20Sopenharmony_ci 11348c2ecf20Sopenharmony_ci return ops->vidioc_g_output(file, fh, arg); 11358c2ecf20Sopenharmony_ci} 11368c2ecf20Sopenharmony_ci 11378c2ecf20Sopenharmony_cistatic int v4l_s_input(const struct v4l2_ioctl_ops *ops, 11388c2ecf20Sopenharmony_ci struct file *file, void *fh, void *arg) 11398c2ecf20Sopenharmony_ci{ 11408c2ecf20Sopenharmony_ci struct video_device *vfd = video_devdata(file); 11418c2ecf20Sopenharmony_ci int ret; 11428c2ecf20Sopenharmony_ci 11438c2ecf20Sopenharmony_ci ret = v4l_enable_media_source(vfd); 11448c2ecf20Sopenharmony_ci if (ret) 11458c2ecf20Sopenharmony_ci return ret; 11468c2ecf20Sopenharmony_ci 11478c2ecf20Sopenharmony_ci if (vfd->device_caps & V4L2_CAP_IO_MC) 11488c2ecf20Sopenharmony_ci return *(int *)arg ? -EINVAL : 0; 11498c2ecf20Sopenharmony_ci 11508c2ecf20Sopenharmony_ci return ops->vidioc_s_input(file, fh, *(unsigned int *)arg); 11518c2ecf20Sopenharmony_ci} 11528c2ecf20Sopenharmony_ci 11538c2ecf20Sopenharmony_cistatic int v4l_s_output(const struct v4l2_ioctl_ops *ops, 11548c2ecf20Sopenharmony_ci struct file *file, void *fh, void *arg) 11558c2ecf20Sopenharmony_ci{ 11568c2ecf20Sopenharmony_ci struct video_device *vfd = video_devdata(file); 11578c2ecf20Sopenharmony_ci 11588c2ecf20Sopenharmony_ci if (vfd->device_caps & V4L2_CAP_IO_MC) 11598c2ecf20Sopenharmony_ci return *(int *)arg ? -EINVAL : 0; 11608c2ecf20Sopenharmony_ci 11618c2ecf20Sopenharmony_ci return ops->vidioc_s_output(file, fh, *(unsigned int *)arg); 11628c2ecf20Sopenharmony_ci} 11638c2ecf20Sopenharmony_ci 11648c2ecf20Sopenharmony_cistatic int v4l_g_priority(const struct v4l2_ioctl_ops *ops, 11658c2ecf20Sopenharmony_ci struct file *file, void *fh, void *arg) 11668c2ecf20Sopenharmony_ci{ 11678c2ecf20Sopenharmony_ci struct video_device *vfd; 11688c2ecf20Sopenharmony_ci u32 *p = arg; 11698c2ecf20Sopenharmony_ci 11708c2ecf20Sopenharmony_ci vfd = video_devdata(file); 11718c2ecf20Sopenharmony_ci *p = v4l2_prio_max(vfd->prio); 11728c2ecf20Sopenharmony_ci return 0; 11738c2ecf20Sopenharmony_ci} 11748c2ecf20Sopenharmony_ci 11758c2ecf20Sopenharmony_cistatic int v4l_s_priority(const struct v4l2_ioctl_ops *ops, 11768c2ecf20Sopenharmony_ci struct file *file, void *fh, void *arg) 11778c2ecf20Sopenharmony_ci{ 11788c2ecf20Sopenharmony_ci struct video_device *vfd; 11798c2ecf20Sopenharmony_ci struct v4l2_fh *vfh; 11808c2ecf20Sopenharmony_ci u32 *p = arg; 11818c2ecf20Sopenharmony_ci 11828c2ecf20Sopenharmony_ci vfd = video_devdata(file); 11838c2ecf20Sopenharmony_ci if (!test_bit(V4L2_FL_USES_V4L2_FH, &vfd->flags)) 11848c2ecf20Sopenharmony_ci return -ENOTTY; 11858c2ecf20Sopenharmony_ci vfh = file->private_data; 11868c2ecf20Sopenharmony_ci return v4l2_prio_change(vfd->prio, &vfh->prio, *p); 11878c2ecf20Sopenharmony_ci} 11888c2ecf20Sopenharmony_ci 11898c2ecf20Sopenharmony_cistatic int v4l_enuminput(const struct v4l2_ioctl_ops *ops, 11908c2ecf20Sopenharmony_ci struct file *file, void *fh, void *arg) 11918c2ecf20Sopenharmony_ci{ 11928c2ecf20Sopenharmony_ci struct video_device *vfd = video_devdata(file); 11938c2ecf20Sopenharmony_ci struct v4l2_input *p = arg; 11948c2ecf20Sopenharmony_ci 11958c2ecf20Sopenharmony_ci /* 11968c2ecf20Sopenharmony_ci * We set the flags for CAP_DV_TIMINGS & 11978c2ecf20Sopenharmony_ci * CAP_STD here based on ioctl handler provided by the 11988c2ecf20Sopenharmony_ci * driver. If the driver doesn't support these 11998c2ecf20Sopenharmony_ci * for a specific input, it must override these flags. 12008c2ecf20Sopenharmony_ci */ 12018c2ecf20Sopenharmony_ci if (is_valid_ioctl(vfd, VIDIOC_S_STD)) 12028c2ecf20Sopenharmony_ci p->capabilities |= V4L2_IN_CAP_STD; 12038c2ecf20Sopenharmony_ci 12048c2ecf20Sopenharmony_ci if (vfd->device_caps & V4L2_CAP_IO_MC) { 12058c2ecf20Sopenharmony_ci if (p->index) 12068c2ecf20Sopenharmony_ci return -EINVAL; 12078c2ecf20Sopenharmony_ci strscpy(p->name, vfd->name, sizeof(p->name)); 12088c2ecf20Sopenharmony_ci p->type = V4L2_INPUT_TYPE_CAMERA; 12098c2ecf20Sopenharmony_ci return 0; 12108c2ecf20Sopenharmony_ci } 12118c2ecf20Sopenharmony_ci 12128c2ecf20Sopenharmony_ci return ops->vidioc_enum_input(file, fh, p); 12138c2ecf20Sopenharmony_ci} 12148c2ecf20Sopenharmony_ci 12158c2ecf20Sopenharmony_cistatic int v4l_enumoutput(const struct v4l2_ioctl_ops *ops, 12168c2ecf20Sopenharmony_ci struct file *file, void *fh, void *arg) 12178c2ecf20Sopenharmony_ci{ 12188c2ecf20Sopenharmony_ci struct video_device *vfd = video_devdata(file); 12198c2ecf20Sopenharmony_ci struct v4l2_output *p = arg; 12208c2ecf20Sopenharmony_ci 12218c2ecf20Sopenharmony_ci /* 12228c2ecf20Sopenharmony_ci * We set the flags for CAP_DV_TIMINGS & 12238c2ecf20Sopenharmony_ci * CAP_STD here based on ioctl handler provided by the 12248c2ecf20Sopenharmony_ci * driver. If the driver doesn't support these 12258c2ecf20Sopenharmony_ci * for a specific output, it must override these flags. 12268c2ecf20Sopenharmony_ci */ 12278c2ecf20Sopenharmony_ci if (is_valid_ioctl(vfd, VIDIOC_S_STD)) 12288c2ecf20Sopenharmony_ci p->capabilities |= V4L2_OUT_CAP_STD; 12298c2ecf20Sopenharmony_ci 12308c2ecf20Sopenharmony_ci if (vfd->device_caps & V4L2_CAP_IO_MC) { 12318c2ecf20Sopenharmony_ci if (p->index) 12328c2ecf20Sopenharmony_ci return -EINVAL; 12338c2ecf20Sopenharmony_ci strscpy(p->name, vfd->name, sizeof(p->name)); 12348c2ecf20Sopenharmony_ci p->type = V4L2_OUTPUT_TYPE_ANALOG; 12358c2ecf20Sopenharmony_ci return 0; 12368c2ecf20Sopenharmony_ci } 12378c2ecf20Sopenharmony_ci 12388c2ecf20Sopenharmony_ci return ops->vidioc_enum_output(file, fh, p); 12398c2ecf20Sopenharmony_ci} 12408c2ecf20Sopenharmony_ci 12418c2ecf20Sopenharmony_cistatic void v4l_fill_fmtdesc(struct v4l2_fmtdesc *fmt) 12428c2ecf20Sopenharmony_ci{ 12438c2ecf20Sopenharmony_ci const unsigned sz = sizeof(fmt->description); 12448c2ecf20Sopenharmony_ci const char *descr = NULL; 12458c2ecf20Sopenharmony_ci u32 flags = 0; 12468c2ecf20Sopenharmony_ci 12478c2ecf20Sopenharmony_ci /* 12488c2ecf20Sopenharmony_ci * We depart from the normal coding style here since the descriptions 12498c2ecf20Sopenharmony_ci * should be aligned so it is easy to see which descriptions will be 12508c2ecf20Sopenharmony_ci * longer than 31 characters (the max length for a description). 12518c2ecf20Sopenharmony_ci * And frankly, this is easier to read anyway. 12528c2ecf20Sopenharmony_ci * 12538c2ecf20Sopenharmony_ci * Note that gcc will use O(log N) comparisons to find the right case. 12548c2ecf20Sopenharmony_ci */ 12558c2ecf20Sopenharmony_ci switch (fmt->pixelformat) { 12568c2ecf20Sopenharmony_ci /* Max description length mask: descr = "0123456789012345678901234567890" */ 12578c2ecf20Sopenharmony_ci case V4L2_PIX_FMT_RGB332: descr = "8-bit RGB 3-3-2"; break; 12588c2ecf20Sopenharmony_ci case V4L2_PIX_FMT_RGB444: descr = "16-bit A/XRGB 4-4-4-4"; break; 12598c2ecf20Sopenharmony_ci case V4L2_PIX_FMT_ARGB444: descr = "16-bit ARGB 4-4-4-4"; break; 12608c2ecf20Sopenharmony_ci case V4L2_PIX_FMT_XRGB444: descr = "16-bit XRGB 4-4-4-4"; break; 12618c2ecf20Sopenharmony_ci case V4L2_PIX_FMT_RGBA444: descr = "16-bit RGBA 4-4-4-4"; break; 12628c2ecf20Sopenharmony_ci case V4L2_PIX_FMT_RGBX444: descr = "16-bit RGBX 4-4-4-4"; break; 12638c2ecf20Sopenharmony_ci case V4L2_PIX_FMT_ABGR444: descr = "16-bit ABGR 4-4-4-4"; break; 12648c2ecf20Sopenharmony_ci case V4L2_PIX_FMT_XBGR444: descr = "16-bit XBGR 4-4-4-4"; break; 12658c2ecf20Sopenharmony_ci case V4L2_PIX_FMT_BGRA444: descr = "16-bit BGRA 4-4-4-4"; break; 12668c2ecf20Sopenharmony_ci case V4L2_PIX_FMT_BGRX444: descr = "16-bit BGRX 4-4-4-4"; break; 12678c2ecf20Sopenharmony_ci case V4L2_PIX_FMT_RGB555: descr = "16-bit A/XRGB 1-5-5-5"; break; 12688c2ecf20Sopenharmony_ci case V4L2_PIX_FMT_ARGB555: descr = "16-bit ARGB 1-5-5-5"; break; 12698c2ecf20Sopenharmony_ci case V4L2_PIX_FMT_XRGB555: descr = "16-bit XRGB 1-5-5-5"; break; 12708c2ecf20Sopenharmony_ci case V4L2_PIX_FMT_ABGR555: descr = "16-bit ABGR 1-5-5-5"; break; 12718c2ecf20Sopenharmony_ci case V4L2_PIX_FMT_XBGR555: descr = "16-bit XBGR 1-5-5-5"; break; 12728c2ecf20Sopenharmony_ci case V4L2_PIX_FMT_RGBA555: descr = "16-bit RGBA 5-5-5-1"; break; 12738c2ecf20Sopenharmony_ci case V4L2_PIX_FMT_RGBX555: descr = "16-bit RGBX 5-5-5-1"; break; 12748c2ecf20Sopenharmony_ci case V4L2_PIX_FMT_BGRA555: descr = "16-bit BGRA 5-5-5-1"; break; 12758c2ecf20Sopenharmony_ci case V4L2_PIX_FMT_BGRX555: descr = "16-bit BGRX 5-5-5-1"; break; 12768c2ecf20Sopenharmony_ci case V4L2_PIX_FMT_RGB565: descr = "16-bit RGB 5-6-5"; break; 12778c2ecf20Sopenharmony_ci case V4L2_PIX_FMT_RGB555X: descr = "16-bit A/XRGB 1-5-5-5 BE"; break; 12788c2ecf20Sopenharmony_ci case V4L2_PIX_FMT_ARGB555X: descr = "16-bit ARGB 1-5-5-5 BE"; break; 12798c2ecf20Sopenharmony_ci case V4L2_PIX_FMT_XRGB555X: descr = "16-bit XRGB 1-5-5-5 BE"; break; 12808c2ecf20Sopenharmony_ci case V4L2_PIX_FMT_RGB565X: descr = "16-bit RGB 5-6-5 BE"; break; 12818c2ecf20Sopenharmony_ci case V4L2_PIX_FMT_BGR666: descr = "18-bit BGRX 6-6-6-14"; break; 12828c2ecf20Sopenharmony_ci case V4L2_PIX_FMT_BGR24: descr = "24-bit BGR 8-8-8"; break; 12838c2ecf20Sopenharmony_ci case V4L2_PIX_FMT_RGB24: descr = "24-bit RGB 8-8-8"; break; 12848c2ecf20Sopenharmony_ci case V4L2_PIX_FMT_BGR32: descr = "32-bit BGRA/X 8-8-8-8"; break; 12858c2ecf20Sopenharmony_ci case V4L2_PIX_FMT_ABGR32: descr = "32-bit BGRA 8-8-8-8"; break; 12868c2ecf20Sopenharmony_ci case V4L2_PIX_FMT_XBGR32: descr = "32-bit BGRX 8-8-8-8"; break; 12878c2ecf20Sopenharmony_ci case V4L2_PIX_FMT_RGB32: descr = "32-bit A/XRGB 8-8-8-8"; break; 12888c2ecf20Sopenharmony_ci case V4L2_PIX_FMT_ARGB32: descr = "32-bit ARGB 8-8-8-8"; break; 12898c2ecf20Sopenharmony_ci case V4L2_PIX_FMT_XRGB32: descr = "32-bit XRGB 8-8-8-8"; break; 12908c2ecf20Sopenharmony_ci case V4L2_PIX_FMT_BGRA32: descr = "32-bit ABGR 8-8-8-8"; break; 12918c2ecf20Sopenharmony_ci case V4L2_PIX_FMT_BGRX32: descr = "32-bit XBGR 8-8-8-8"; break; 12928c2ecf20Sopenharmony_ci case V4L2_PIX_FMT_RGBA32: descr = "32-bit RGBA 8-8-8-8"; break; 12938c2ecf20Sopenharmony_ci case V4L2_PIX_FMT_RGBX32: descr = "32-bit RGBX 8-8-8-8"; break; 12948c2ecf20Sopenharmony_ci case V4L2_PIX_FMT_GREY: descr = "8-bit Greyscale"; break; 12958c2ecf20Sopenharmony_ci case V4L2_PIX_FMT_Y4: descr = "4-bit Greyscale"; break; 12968c2ecf20Sopenharmony_ci case V4L2_PIX_FMT_Y6: descr = "6-bit Greyscale"; break; 12978c2ecf20Sopenharmony_ci case V4L2_PIX_FMT_Y10: descr = "10-bit Greyscale"; break; 12988c2ecf20Sopenharmony_ci case V4L2_PIX_FMT_Y12: descr = "12-bit Greyscale"; break; 12998c2ecf20Sopenharmony_ci case V4L2_PIX_FMT_Y14: descr = "14-bit Greyscale"; break; 13008c2ecf20Sopenharmony_ci case V4L2_PIX_FMT_Y16: descr = "16-bit Greyscale"; break; 13018c2ecf20Sopenharmony_ci case V4L2_PIX_FMT_Y16_BE: descr = "16-bit Greyscale BE"; break; 13028c2ecf20Sopenharmony_ci case V4L2_PIX_FMT_Y10BPACK: descr = "10-bit Greyscale (Packed)"; break; 13038c2ecf20Sopenharmony_ci case V4L2_PIX_FMT_Y10P: descr = "10-bit Greyscale (MIPI Packed)"; break; 13048c2ecf20Sopenharmony_ci case V4L2_PIX_FMT_Y8I: descr = "Interleaved 8-bit Greyscale"; break; 13058c2ecf20Sopenharmony_ci case V4L2_PIX_FMT_Y12I: descr = "Interleaved 12-bit Greyscale"; break; 13068c2ecf20Sopenharmony_ci case V4L2_PIX_FMT_Z16: descr = "16-bit Depth"; break; 13078c2ecf20Sopenharmony_ci case V4L2_PIX_FMT_INZI: descr = "Planar 10:16 Greyscale Depth"; break; 13088c2ecf20Sopenharmony_ci case V4L2_PIX_FMT_CNF4: descr = "4-bit Depth Confidence (Packed)"; break; 13098c2ecf20Sopenharmony_ci case V4L2_PIX_FMT_PAL8: descr = "8-bit Palette"; break; 13108c2ecf20Sopenharmony_ci case V4L2_PIX_FMT_UV8: descr = "8-bit Chrominance UV 4-4"; break; 13118c2ecf20Sopenharmony_ci case V4L2_PIX_FMT_YVU410: descr = "Planar YVU 4:1:0"; break; 13128c2ecf20Sopenharmony_ci case V4L2_PIX_FMT_YVU420: descr = "Planar YVU 4:2:0"; break; 13138c2ecf20Sopenharmony_ci case V4L2_PIX_FMT_YUYV: descr = "YUYV 4:2:2"; break; 13148c2ecf20Sopenharmony_ci case V4L2_PIX_FMT_YYUV: descr = "YYUV 4:2:2"; break; 13158c2ecf20Sopenharmony_ci case V4L2_PIX_FMT_YVYU: descr = "YVYU 4:2:2"; break; 13168c2ecf20Sopenharmony_ci case V4L2_PIX_FMT_UYVY: descr = "UYVY 4:2:2"; break; 13178c2ecf20Sopenharmony_ci case V4L2_PIX_FMT_VYUY: descr = "VYUY 4:2:2"; break; 13188c2ecf20Sopenharmony_ci case V4L2_PIX_FMT_YUV422P: descr = "Planar YUV 4:2:2"; break; 13198c2ecf20Sopenharmony_ci case V4L2_PIX_FMT_YUV411P: descr = "Planar YUV 4:1:1"; break; 13208c2ecf20Sopenharmony_ci case V4L2_PIX_FMT_Y41P: descr = "YUV 4:1:1 (Packed)"; break; 13218c2ecf20Sopenharmony_ci case V4L2_PIX_FMT_YUV444: descr = "16-bit A/XYUV 4-4-4-4"; break; 13228c2ecf20Sopenharmony_ci case V4L2_PIX_FMT_YUV555: descr = "16-bit A/XYUV 1-5-5-5"; break; 13238c2ecf20Sopenharmony_ci case V4L2_PIX_FMT_YUV565: descr = "16-bit YUV 5-6-5"; break; 13248c2ecf20Sopenharmony_ci case V4L2_PIX_FMT_YUV32: descr = "32-bit A/XYUV 8-8-8-8"; break; 13258c2ecf20Sopenharmony_ci case V4L2_PIX_FMT_AYUV32: descr = "32-bit AYUV 8-8-8-8"; break; 13268c2ecf20Sopenharmony_ci case V4L2_PIX_FMT_XYUV32: descr = "32-bit XYUV 8-8-8-8"; break; 13278c2ecf20Sopenharmony_ci case V4L2_PIX_FMT_VUYA32: descr = "32-bit VUYA 8-8-8-8"; break; 13288c2ecf20Sopenharmony_ci case V4L2_PIX_FMT_VUYX32: descr = "32-bit VUYX 8-8-8-8"; break; 13298c2ecf20Sopenharmony_ci case V4L2_PIX_FMT_YUV410: descr = "Planar YUV 4:1:0"; break; 13308c2ecf20Sopenharmony_ci case V4L2_PIX_FMT_YUV420: descr = "Planar YUV 4:2:0"; break; 13318c2ecf20Sopenharmony_ci case V4L2_PIX_FMT_HI240: descr = "8-bit Dithered RGB (BTTV)"; break; 13328c2ecf20Sopenharmony_ci case V4L2_PIX_FMT_HM12: descr = "YUV 4:2:0 (16x16 Macroblocks)"; break; 13338c2ecf20Sopenharmony_ci case V4L2_PIX_FMT_M420: descr = "YUV 4:2:0 (M420)"; break; 13348c2ecf20Sopenharmony_ci case V4L2_PIX_FMT_NV12: descr = "Y/CbCr 4:2:0"; break; 13358c2ecf20Sopenharmony_ci case V4L2_PIX_FMT_NV21: descr = "Y/CrCb 4:2:0"; break; 13368c2ecf20Sopenharmony_ci case V4L2_PIX_FMT_NV16: descr = "Y/CbCr 4:2:2"; break; 13378c2ecf20Sopenharmony_ci case V4L2_PIX_FMT_NV61: descr = "Y/CrCb 4:2:2"; break; 13388c2ecf20Sopenharmony_ci case V4L2_PIX_FMT_NV24: descr = "Y/CbCr 4:4:4"; break; 13398c2ecf20Sopenharmony_ci case V4L2_PIX_FMT_NV42: descr = "Y/CrCb 4:4:4"; break; 13408c2ecf20Sopenharmony_ci case V4L2_PIX_FMT_NV12M: descr = "Y/CbCr 4:2:0 (N-C)"; break; 13418c2ecf20Sopenharmony_ci case V4L2_PIX_FMT_NV21M: descr = "Y/CrCb 4:2:0 (N-C)"; break; 13428c2ecf20Sopenharmony_ci case V4L2_PIX_FMT_NV16M: descr = "Y/CbCr 4:2:2 (N-C)"; break; 13438c2ecf20Sopenharmony_ci case V4L2_PIX_FMT_NV61M: descr = "Y/CrCb 4:2:2 (N-C)"; break; 13448c2ecf20Sopenharmony_ci case V4L2_PIX_FMT_NV12MT: descr = "Y/CbCr 4:2:0 (64x32 MB, N-C)"; break; 13458c2ecf20Sopenharmony_ci case V4L2_PIX_FMT_NV12MT_16X16: descr = "Y/CbCr 4:2:0 (16x16 MB, N-C)"; break; 13468c2ecf20Sopenharmony_ci case V4L2_PIX_FMT_YUV420M: descr = "Planar YUV 4:2:0 (N-C)"; break; 13478c2ecf20Sopenharmony_ci case V4L2_PIX_FMT_YVU420M: descr = "Planar YVU 4:2:0 (N-C)"; break; 13488c2ecf20Sopenharmony_ci case V4L2_PIX_FMT_YUV422M: descr = "Planar YUV 4:2:2 (N-C)"; break; 13498c2ecf20Sopenharmony_ci case V4L2_PIX_FMT_YVU422M: descr = "Planar YVU 4:2:2 (N-C)"; break; 13508c2ecf20Sopenharmony_ci case V4L2_PIX_FMT_YUV444M: descr = "Planar YUV 4:4:4 (N-C)"; break; 13518c2ecf20Sopenharmony_ci case V4L2_PIX_FMT_YVU444M: descr = "Planar YVU 4:4:4 (N-C)"; break; 13528c2ecf20Sopenharmony_ci case V4L2_PIX_FMT_SBGGR8: descr = "8-bit Bayer BGBG/GRGR"; break; 13538c2ecf20Sopenharmony_ci case V4L2_PIX_FMT_SGBRG8: descr = "8-bit Bayer GBGB/RGRG"; break; 13548c2ecf20Sopenharmony_ci case V4L2_PIX_FMT_SGRBG8: descr = "8-bit Bayer GRGR/BGBG"; break; 13558c2ecf20Sopenharmony_ci case V4L2_PIX_FMT_SRGGB8: descr = "8-bit Bayer RGRG/GBGB"; break; 13568c2ecf20Sopenharmony_ci case V4L2_PIX_FMT_SBGGR10: descr = "10-bit Bayer BGBG/GRGR"; break; 13578c2ecf20Sopenharmony_ci case V4L2_PIX_FMT_SGBRG10: descr = "10-bit Bayer GBGB/RGRG"; break; 13588c2ecf20Sopenharmony_ci case V4L2_PIX_FMT_SGRBG10: descr = "10-bit Bayer GRGR/BGBG"; break; 13598c2ecf20Sopenharmony_ci case V4L2_PIX_FMT_SRGGB10: descr = "10-bit Bayer RGRG/GBGB"; break; 13608c2ecf20Sopenharmony_ci case V4L2_PIX_FMT_SBGGR10P: descr = "10-bit Bayer BGBG/GRGR Packed"; break; 13618c2ecf20Sopenharmony_ci case V4L2_PIX_FMT_SGBRG10P: descr = "10-bit Bayer GBGB/RGRG Packed"; break; 13628c2ecf20Sopenharmony_ci case V4L2_PIX_FMT_SGRBG10P: descr = "10-bit Bayer GRGR/BGBG Packed"; break; 13638c2ecf20Sopenharmony_ci case V4L2_PIX_FMT_SRGGB10P: descr = "10-bit Bayer RGRG/GBGB Packed"; break; 13648c2ecf20Sopenharmony_ci case V4L2_PIX_FMT_IPU3_SBGGR10: descr = "10-bit bayer BGGR IPU3 Packed"; break; 13658c2ecf20Sopenharmony_ci case V4L2_PIX_FMT_IPU3_SGBRG10: descr = "10-bit bayer GBRG IPU3 Packed"; break; 13668c2ecf20Sopenharmony_ci case V4L2_PIX_FMT_IPU3_SGRBG10: descr = "10-bit bayer GRBG IPU3 Packed"; break; 13678c2ecf20Sopenharmony_ci case V4L2_PIX_FMT_IPU3_SRGGB10: descr = "10-bit bayer RGGB IPU3 Packed"; break; 13688c2ecf20Sopenharmony_ci case V4L2_PIX_FMT_SBGGR10ALAW8: descr = "8-bit Bayer BGBG/GRGR (A-law)"; break; 13698c2ecf20Sopenharmony_ci case V4L2_PIX_FMT_SGBRG10ALAW8: descr = "8-bit Bayer GBGB/RGRG (A-law)"; break; 13708c2ecf20Sopenharmony_ci case V4L2_PIX_FMT_SGRBG10ALAW8: descr = "8-bit Bayer GRGR/BGBG (A-law)"; break; 13718c2ecf20Sopenharmony_ci case V4L2_PIX_FMT_SRGGB10ALAW8: descr = "8-bit Bayer RGRG/GBGB (A-law)"; break; 13728c2ecf20Sopenharmony_ci case V4L2_PIX_FMT_SBGGR10DPCM8: descr = "8-bit Bayer BGBG/GRGR (DPCM)"; break; 13738c2ecf20Sopenharmony_ci case V4L2_PIX_FMT_SGBRG10DPCM8: descr = "8-bit Bayer GBGB/RGRG (DPCM)"; break; 13748c2ecf20Sopenharmony_ci case V4L2_PIX_FMT_SGRBG10DPCM8: descr = "8-bit Bayer GRGR/BGBG (DPCM)"; break; 13758c2ecf20Sopenharmony_ci case V4L2_PIX_FMT_SRGGB10DPCM8: descr = "8-bit Bayer RGRG/GBGB (DPCM)"; break; 13768c2ecf20Sopenharmony_ci case V4L2_PIX_FMT_SBGGR12: descr = "12-bit Bayer BGBG/GRGR"; break; 13778c2ecf20Sopenharmony_ci case V4L2_PIX_FMT_SGBRG12: descr = "12-bit Bayer GBGB/RGRG"; break; 13788c2ecf20Sopenharmony_ci case V4L2_PIX_FMT_SGRBG12: descr = "12-bit Bayer GRGR/BGBG"; break; 13798c2ecf20Sopenharmony_ci case V4L2_PIX_FMT_SRGGB12: descr = "12-bit Bayer RGRG/GBGB"; break; 13808c2ecf20Sopenharmony_ci case V4L2_PIX_FMT_SBGGR12P: descr = "12-bit Bayer BGBG/GRGR Packed"; break; 13818c2ecf20Sopenharmony_ci case V4L2_PIX_FMT_SGBRG12P: descr = "12-bit Bayer GBGB/RGRG Packed"; break; 13828c2ecf20Sopenharmony_ci case V4L2_PIX_FMT_SGRBG12P: descr = "12-bit Bayer GRGR/BGBG Packed"; break; 13838c2ecf20Sopenharmony_ci case V4L2_PIX_FMT_SRGGB12P: descr = "12-bit Bayer RGRG/GBGB Packed"; break; 13848c2ecf20Sopenharmony_ci case V4L2_PIX_FMT_SBGGR14: descr = "14-bit Bayer BGBG/GRGR"; break; 13858c2ecf20Sopenharmony_ci case V4L2_PIX_FMT_SGBRG14: descr = "14-bit Bayer GBGB/RGRG"; break; 13868c2ecf20Sopenharmony_ci case V4L2_PIX_FMT_SGRBG14: descr = "14-bit Bayer GRGR/BGBG"; break; 13878c2ecf20Sopenharmony_ci case V4L2_PIX_FMT_SRGGB14: descr = "14-bit Bayer RGRG/GBGB"; break; 13888c2ecf20Sopenharmony_ci case V4L2_PIX_FMT_SBGGR14P: descr = "14-bit Bayer BGBG/GRGR Packed"; break; 13898c2ecf20Sopenharmony_ci case V4L2_PIX_FMT_SGBRG14P: descr = "14-bit Bayer GBGB/RGRG Packed"; break; 13908c2ecf20Sopenharmony_ci case V4L2_PIX_FMT_SGRBG14P: descr = "14-bit Bayer GRGR/BGBG Packed"; break; 13918c2ecf20Sopenharmony_ci case V4L2_PIX_FMT_SRGGB14P: descr = "14-bit Bayer RGRG/GBGB Packed"; break; 13928c2ecf20Sopenharmony_ci case V4L2_PIX_FMT_SBGGR16: descr = "16-bit Bayer BGBG/GRGR"; break; 13938c2ecf20Sopenharmony_ci case V4L2_PIX_FMT_SGBRG16: descr = "16-bit Bayer GBGB/RGRG"; break; 13948c2ecf20Sopenharmony_ci case V4L2_PIX_FMT_SGRBG16: descr = "16-bit Bayer GRGR/BGBG"; break; 13958c2ecf20Sopenharmony_ci case V4L2_PIX_FMT_SRGGB16: descr = "16-bit Bayer RGRG/GBGB"; break; 13968c2ecf20Sopenharmony_ci case V4L2_PIX_FMT_SN9C20X_I420: descr = "GSPCA SN9C20X I420"; break; 13978c2ecf20Sopenharmony_ci case V4L2_PIX_FMT_SPCA501: descr = "GSPCA SPCA501"; break; 13988c2ecf20Sopenharmony_ci case V4L2_PIX_FMT_SPCA505: descr = "GSPCA SPCA505"; break; 13998c2ecf20Sopenharmony_ci case V4L2_PIX_FMT_SPCA508: descr = "GSPCA SPCA508"; break; 14008c2ecf20Sopenharmony_ci case V4L2_PIX_FMT_STV0680: descr = "GSPCA STV0680"; break; 14018c2ecf20Sopenharmony_ci case V4L2_PIX_FMT_TM6000: descr = "A/V + VBI Mux Packet"; break; 14028c2ecf20Sopenharmony_ci case V4L2_PIX_FMT_CIT_YYVYUY: descr = "GSPCA CIT YYVYUY"; break; 14038c2ecf20Sopenharmony_ci case V4L2_PIX_FMT_KONICA420: descr = "GSPCA KONICA420"; break; 14048c2ecf20Sopenharmony_ci case V4L2_PIX_FMT_HSV24: descr = "24-bit HSV 8-8-8"; break; 14058c2ecf20Sopenharmony_ci case V4L2_PIX_FMT_HSV32: descr = "32-bit XHSV 8-8-8-8"; break; 14068c2ecf20Sopenharmony_ci case V4L2_SDR_FMT_CU8: descr = "Complex U8"; break; 14078c2ecf20Sopenharmony_ci case V4L2_SDR_FMT_CU16LE: descr = "Complex U16LE"; break; 14088c2ecf20Sopenharmony_ci case V4L2_SDR_FMT_CS8: descr = "Complex S8"; break; 14098c2ecf20Sopenharmony_ci case V4L2_SDR_FMT_CS14LE: descr = "Complex S14LE"; break; 14108c2ecf20Sopenharmony_ci case V4L2_SDR_FMT_RU12LE: descr = "Real U12LE"; break; 14118c2ecf20Sopenharmony_ci case V4L2_SDR_FMT_PCU16BE: descr = "Planar Complex U16BE"; break; 14128c2ecf20Sopenharmony_ci case V4L2_SDR_FMT_PCU18BE: descr = "Planar Complex U18BE"; break; 14138c2ecf20Sopenharmony_ci case V4L2_SDR_FMT_PCU20BE: descr = "Planar Complex U20BE"; break; 14148c2ecf20Sopenharmony_ci case V4L2_TCH_FMT_DELTA_TD16: descr = "16-bit Signed Deltas"; break; 14158c2ecf20Sopenharmony_ci case V4L2_TCH_FMT_DELTA_TD08: descr = "8-bit Signed Deltas"; break; 14168c2ecf20Sopenharmony_ci case V4L2_TCH_FMT_TU16: descr = "16-bit Unsigned Touch Data"; break; 14178c2ecf20Sopenharmony_ci case V4L2_TCH_FMT_TU08: descr = "8-bit Unsigned Touch Data"; break; 14188c2ecf20Sopenharmony_ci case V4L2_META_FMT_VSP1_HGO: descr = "R-Car VSP1 1-D Histogram"; break; 14198c2ecf20Sopenharmony_ci case V4L2_META_FMT_VSP1_HGT: descr = "R-Car VSP1 2-D Histogram"; break; 14208c2ecf20Sopenharmony_ci case V4L2_META_FMT_UVC: descr = "UVC Payload Header Metadata"; break; 14218c2ecf20Sopenharmony_ci case V4L2_META_FMT_D4XX: descr = "Intel D4xx UVC Metadata"; break; 14228c2ecf20Sopenharmony_ci case V4L2_META_FMT_VIVID: descr = "Vivid Metadata"; break; 14238c2ecf20Sopenharmony_ci 14248c2ecf20Sopenharmony_ci default: 14258c2ecf20Sopenharmony_ci /* Compressed formats */ 14268c2ecf20Sopenharmony_ci flags = V4L2_FMT_FLAG_COMPRESSED; 14278c2ecf20Sopenharmony_ci switch (fmt->pixelformat) { 14288c2ecf20Sopenharmony_ci /* Max description length mask: descr = "0123456789012345678901234567890" */ 14298c2ecf20Sopenharmony_ci case V4L2_PIX_FMT_MJPEG: descr = "Motion-JPEG"; break; 14308c2ecf20Sopenharmony_ci case V4L2_PIX_FMT_JPEG: descr = "JFIF JPEG"; break; 14318c2ecf20Sopenharmony_ci case V4L2_PIX_FMT_DV: descr = "1394"; break; 14328c2ecf20Sopenharmony_ci case V4L2_PIX_FMT_MPEG: descr = "MPEG-1/2/4"; break; 14338c2ecf20Sopenharmony_ci case V4L2_PIX_FMT_H264: descr = "H.264"; break; 14348c2ecf20Sopenharmony_ci case V4L2_PIX_FMT_H264_NO_SC: descr = "H.264 (No Start Codes)"; break; 14358c2ecf20Sopenharmony_ci case V4L2_PIX_FMT_H264_MVC: descr = "H.264 MVC"; break; 14368c2ecf20Sopenharmony_ci case V4L2_PIX_FMT_H264_SLICE: descr = "H.264 Parsed Slice Data"; break; 14378c2ecf20Sopenharmony_ci case V4L2_PIX_FMT_H263: descr = "H.263"; break; 14388c2ecf20Sopenharmony_ci case V4L2_PIX_FMT_MPEG1: descr = "MPEG-1 ES"; break; 14398c2ecf20Sopenharmony_ci case V4L2_PIX_FMT_MPEG2: descr = "MPEG-2 ES"; break; 14408c2ecf20Sopenharmony_ci case V4L2_PIX_FMT_MPEG2_SLICE: descr = "MPEG-2 Parsed Slice Data"; break; 14418c2ecf20Sopenharmony_ci case V4L2_PIX_FMT_MPEG4: descr = "MPEG-4 Part 2 ES"; break; 14428c2ecf20Sopenharmony_ci case V4L2_PIX_FMT_XVID: descr = "Xvid"; break; 14438c2ecf20Sopenharmony_ci case V4L2_PIX_FMT_VC1_ANNEX_G: descr = "VC-1 (SMPTE 412M Annex G)"; break; 14448c2ecf20Sopenharmony_ci case V4L2_PIX_FMT_VC1_ANNEX_L: descr = "VC-1 (SMPTE 412M Annex L)"; break; 14458c2ecf20Sopenharmony_ci case V4L2_PIX_FMT_VP8: descr = "VP8"; break; 14468c2ecf20Sopenharmony_ci case V4L2_PIX_FMT_VP8_FRAME: descr = "VP8 Frame"; break; 14478c2ecf20Sopenharmony_ci case V4L2_PIX_FMT_VP9: descr = "VP9"; break; 14488c2ecf20Sopenharmony_ci case V4L2_PIX_FMT_HEVC: descr = "HEVC"; break; /* aka H.265 */ 14498c2ecf20Sopenharmony_ci case V4L2_PIX_FMT_HEVC_SLICE: descr = "HEVC Parsed Slice Data"; break; 14508c2ecf20Sopenharmony_ci case V4L2_PIX_FMT_FWHT: descr = "FWHT"; break; /* used in vicodec */ 14518c2ecf20Sopenharmony_ci case V4L2_PIX_FMT_FWHT_STATELESS: descr = "FWHT Stateless"; break; /* used in vicodec */ 14528c2ecf20Sopenharmony_ci case V4L2_PIX_FMT_CPIA1: descr = "GSPCA CPiA YUV"; break; 14538c2ecf20Sopenharmony_ci case V4L2_PIX_FMT_WNVA: descr = "WNVA"; break; 14548c2ecf20Sopenharmony_ci case V4L2_PIX_FMT_SN9C10X: descr = "GSPCA SN9C10X"; break; 14558c2ecf20Sopenharmony_ci case V4L2_PIX_FMT_PWC1: descr = "Raw Philips Webcam Type (Old)"; break; 14568c2ecf20Sopenharmony_ci case V4L2_PIX_FMT_PWC2: descr = "Raw Philips Webcam Type (New)"; break; 14578c2ecf20Sopenharmony_ci case V4L2_PIX_FMT_ET61X251: descr = "GSPCA ET61X251"; break; 14588c2ecf20Sopenharmony_ci case V4L2_PIX_FMT_SPCA561: descr = "GSPCA SPCA561"; break; 14598c2ecf20Sopenharmony_ci case V4L2_PIX_FMT_PAC207: descr = "GSPCA PAC207"; break; 14608c2ecf20Sopenharmony_ci case V4L2_PIX_FMT_MR97310A: descr = "GSPCA MR97310A"; break; 14618c2ecf20Sopenharmony_ci case V4L2_PIX_FMT_JL2005BCD: descr = "GSPCA JL2005BCD"; break; 14628c2ecf20Sopenharmony_ci case V4L2_PIX_FMT_SN9C2028: descr = "GSPCA SN9C2028"; break; 14638c2ecf20Sopenharmony_ci case V4L2_PIX_FMT_SQ905C: descr = "GSPCA SQ905C"; break; 14648c2ecf20Sopenharmony_ci case V4L2_PIX_FMT_PJPG: descr = "GSPCA PJPG"; break; 14658c2ecf20Sopenharmony_ci case V4L2_PIX_FMT_OV511: descr = "GSPCA OV511"; break; 14668c2ecf20Sopenharmony_ci case V4L2_PIX_FMT_OV518: descr = "GSPCA OV518"; break; 14678c2ecf20Sopenharmony_ci case V4L2_PIX_FMT_JPGL: descr = "JPEG Lite"; break; 14688c2ecf20Sopenharmony_ci case V4L2_PIX_FMT_SE401: descr = "GSPCA SE401"; break; 14698c2ecf20Sopenharmony_ci case V4L2_PIX_FMT_S5C_UYVY_JPG: descr = "S5C73MX interleaved UYVY/JPEG"; break; 14708c2ecf20Sopenharmony_ci case V4L2_PIX_FMT_MT21C: descr = "Mediatek Compressed Format"; break; 14718c2ecf20Sopenharmony_ci case V4L2_PIX_FMT_SUNXI_TILED_NV12: descr = "Sunxi Tiled NV12 Format"; break; 14728c2ecf20Sopenharmony_ci default: 14738c2ecf20Sopenharmony_ci if (fmt->description[0]) 14748c2ecf20Sopenharmony_ci return; 14758c2ecf20Sopenharmony_ci WARN(1, "Unknown pixelformat 0x%08x\n", fmt->pixelformat); 14768c2ecf20Sopenharmony_ci flags = 0; 14778c2ecf20Sopenharmony_ci snprintf(fmt->description, sz, "%c%c%c%c%s", 14788c2ecf20Sopenharmony_ci (char)(fmt->pixelformat & 0x7f), 14798c2ecf20Sopenharmony_ci (char)((fmt->pixelformat >> 8) & 0x7f), 14808c2ecf20Sopenharmony_ci (char)((fmt->pixelformat >> 16) & 0x7f), 14818c2ecf20Sopenharmony_ci (char)((fmt->pixelformat >> 24) & 0x7f), 14828c2ecf20Sopenharmony_ci (fmt->pixelformat & (1UL << 31)) ? "-BE" : ""); 14838c2ecf20Sopenharmony_ci break; 14848c2ecf20Sopenharmony_ci } 14858c2ecf20Sopenharmony_ci } 14868c2ecf20Sopenharmony_ci 14878c2ecf20Sopenharmony_ci if (descr) 14888c2ecf20Sopenharmony_ci WARN_ON(strscpy(fmt->description, descr, sz) < 0); 14898c2ecf20Sopenharmony_ci fmt->flags |= flags; 14908c2ecf20Sopenharmony_ci} 14918c2ecf20Sopenharmony_ci 14928c2ecf20Sopenharmony_cistatic int v4l_enum_fmt(const struct v4l2_ioctl_ops *ops, 14938c2ecf20Sopenharmony_ci struct file *file, void *fh, void *arg) 14948c2ecf20Sopenharmony_ci{ 14958c2ecf20Sopenharmony_ci struct video_device *vdev = video_devdata(file); 14968c2ecf20Sopenharmony_ci struct v4l2_fmtdesc *p = arg; 14978c2ecf20Sopenharmony_ci int ret = check_fmt(file, p->type); 14988c2ecf20Sopenharmony_ci u32 mbus_code; 14998c2ecf20Sopenharmony_ci u32 cap_mask; 15008c2ecf20Sopenharmony_ci 15018c2ecf20Sopenharmony_ci if (ret) 15028c2ecf20Sopenharmony_ci return ret; 15038c2ecf20Sopenharmony_ci ret = -EINVAL; 15048c2ecf20Sopenharmony_ci 15058c2ecf20Sopenharmony_ci if (!(vdev->device_caps & V4L2_CAP_IO_MC)) 15068c2ecf20Sopenharmony_ci p->mbus_code = 0; 15078c2ecf20Sopenharmony_ci 15088c2ecf20Sopenharmony_ci mbus_code = p->mbus_code; 15098c2ecf20Sopenharmony_ci CLEAR_AFTER_FIELD(p, type); 15108c2ecf20Sopenharmony_ci p->mbus_code = mbus_code; 15118c2ecf20Sopenharmony_ci 15128c2ecf20Sopenharmony_ci switch (p->type) { 15138c2ecf20Sopenharmony_ci case V4L2_BUF_TYPE_VIDEO_CAPTURE: 15148c2ecf20Sopenharmony_ci case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE: 15158c2ecf20Sopenharmony_ci cap_mask = V4L2_CAP_VIDEO_CAPTURE_MPLANE | 15168c2ecf20Sopenharmony_ci V4L2_CAP_VIDEO_M2M_MPLANE; 15178c2ecf20Sopenharmony_ci if (!!(vdev->device_caps & cap_mask) != 15188c2ecf20Sopenharmony_ci (p->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)) 15198c2ecf20Sopenharmony_ci break; 15208c2ecf20Sopenharmony_ci 15218c2ecf20Sopenharmony_ci if (unlikely(!ops->vidioc_enum_fmt_vid_cap)) 15228c2ecf20Sopenharmony_ci break; 15238c2ecf20Sopenharmony_ci ret = ops->vidioc_enum_fmt_vid_cap(file, fh, arg); 15248c2ecf20Sopenharmony_ci break; 15258c2ecf20Sopenharmony_ci case V4L2_BUF_TYPE_VIDEO_OVERLAY: 15268c2ecf20Sopenharmony_ci if (unlikely(!ops->vidioc_enum_fmt_vid_overlay)) 15278c2ecf20Sopenharmony_ci break; 15288c2ecf20Sopenharmony_ci ret = ops->vidioc_enum_fmt_vid_overlay(file, fh, arg); 15298c2ecf20Sopenharmony_ci break; 15308c2ecf20Sopenharmony_ci case V4L2_BUF_TYPE_VIDEO_OUTPUT: 15318c2ecf20Sopenharmony_ci case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE: 15328c2ecf20Sopenharmony_ci cap_mask = V4L2_CAP_VIDEO_OUTPUT_MPLANE | 15338c2ecf20Sopenharmony_ci V4L2_CAP_VIDEO_M2M_MPLANE; 15348c2ecf20Sopenharmony_ci if (!!(vdev->device_caps & cap_mask) != 15358c2ecf20Sopenharmony_ci (p->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)) 15368c2ecf20Sopenharmony_ci break; 15378c2ecf20Sopenharmony_ci 15388c2ecf20Sopenharmony_ci if (unlikely(!ops->vidioc_enum_fmt_vid_out)) 15398c2ecf20Sopenharmony_ci break; 15408c2ecf20Sopenharmony_ci ret = ops->vidioc_enum_fmt_vid_out(file, fh, arg); 15418c2ecf20Sopenharmony_ci break; 15428c2ecf20Sopenharmony_ci case V4L2_BUF_TYPE_SDR_CAPTURE: 15438c2ecf20Sopenharmony_ci if (unlikely(!ops->vidioc_enum_fmt_sdr_cap)) 15448c2ecf20Sopenharmony_ci break; 15458c2ecf20Sopenharmony_ci ret = ops->vidioc_enum_fmt_sdr_cap(file, fh, arg); 15468c2ecf20Sopenharmony_ci break; 15478c2ecf20Sopenharmony_ci case V4L2_BUF_TYPE_SDR_OUTPUT: 15488c2ecf20Sopenharmony_ci if (unlikely(!ops->vidioc_enum_fmt_sdr_out)) 15498c2ecf20Sopenharmony_ci break; 15508c2ecf20Sopenharmony_ci ret = ops->vidioc_enum_fmt_sdr_out(file, fh, arg); 15518c2ecf20Sopenharmony_ci break; 15528c2ecf20Sopenharmony_ci case V4L2_BUF_TYPE_META_CAPTURE: 15538c2ecf20Sopenharmony_ci if (unlikely(!ops->vidioc_enum_fmt_meta_cap)) 15548c2ecf20Sopenharmony_ci break; 15558c2ecf20Sopenharmony_ci ret = ops->vidioc_enum_fmt_meta_cap(file, fh, arg); 15568c2ecf20Sopenharmony_ci break; 15578c2ecf20Sopenharmony_ci case V4L2_BUF_TYPE_META_OUTPUT: 15588c2ecf20Sopenharmony_ci if (unlikely(!ops->vidioc_enum_fmt_meta_out)) 15598c2ecf20Sopenharmony_ci break; 15608c2ecf20Sopenharmony_ci ret = ops->vidioc_enum_fmt_meta_out(file, fh, arg); 15618c2ecf20Sopenharmony_ci break; 15628c2ecf20Sopenharmony_ci } 15638c2ecf20Sopenharmony_ci if (ret == 0) 15648c2ecf20Sopenharmony_ci v4l_fill_fmtdesc(p); 15658c2ecf20Sopenharmony_ci return ret; 15668c2ecf20Sopenharmony_ci} 15678c2ecf20Sopenharmony_ci 15688c2ecf20Sopenharmony_cistatic void v4l_pix_format_touch(struct v4l2_pix_format *p) 15698c2ecf20Sopenharmony_ci{ 15708c2ecf20Sopenharmony_ci /* 15718c2ecf20Sopenharmony_ci * The v4l2_pix_format structure contains fields that make no sense for 15728c2ecf20Sopenharmony_ci * touch. Set them to default values in this case. 15738c2ecf20Sopenharmony_ci */ 15748c2ecf20Sopenharmony_ci 15758c2ecf20Sopenharmony_ci p->field = V4L2_FIELD_NONE; 15768c2ecf20Sopenharmony_ci p->colorspace = V4L2_COLORSPACE_RAW; 15778c2ecf20Sopenharmony_ci p->flags = 0; 15788c2ecf20Sopenharmony_ci p->ycbcr_enc = 0; 15798c2ecf20Sopenharmony_ci p->quantization = 0; 15808c2ecf20Sopenharmony_ci p->xfer_func = 0; 15818c2ecf20Sopenharmony_ci} 15828c2ecf20Sopenharmony_ci 15838c2ecf20Sopenharmony_cistatic int v4l_g_fmt(const struct v4l2_ioctl_ops *ops, 15848c2ecf20Sopenharmony_ci struct file *file, void *fh, void *arg) 15858c2ecf20Sopenharmony_ci{ 15868c2ecf20Sopenharmony_ci struct v4l2_format *p = arg; 15878c2ecf20Sopenharmony_ci struct video_device *vfd = video_devdata(file); 15888c2ecf20Sopenharmony_ci int ret = check_fmt(file, p->type); 15898c2ecf20Sopenharmony_ci 15908c2ecf20Sopenharmony_ci if (ret) 15918c2ecf20Sopenharmony_ci return ret; 15928c2ecf20Sopenharmony_ci 15938c2ecf20Sopenharmony_ci /* 15948c2ecf20Sopenharmony_ci * fmt can't be cleared for these overlay types due to the 'clips' 15958c2ecf20Sopenharmony_ci * 'clipcount' and 'bitmap' pointers in struct v4l2_window. 15968c2ecf20Sopenharmony_ci * Those are provided by the user. So handle these two overlay types 15978c2ecf20Sopenharmony_ci * first, and then just do a simple memset for the other types. 15988c2ecf20Sopenharmony_ci */ 15998c2ecf20Sopenharmony_ci switch (p->type) { 16008c2ecf20Sopenharmony_ci case V4L2_BUF_TYPE_VIDEO_OVERLAY: 16018c2ecf20Sopenharmony_ci case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY: { 16028c2ecf20Sopenharmony_ci struct v4l2_clip __user *clips = p->fmt.win.clips; 16038c2ecf20Sopenharmony_ci u32 clipcount = p->fmt.win.clipcount; 16048c2ecf20Sopenharmony_ci void __user *bitmap = p->fmt.win.bitmap; 16058c2ecf20Sopenharmony_ci 16068c2ecf20Sopenharmony_ci memset(&p->fmt, 0, sizeof(p->fmt)); 16078c2ecf20Sopenharmony_ci p->fmt.win.clips = clips; 16088c2ecf20Sopenharmony_ci p->fmt.win.clipcount = clipcount; 16098c2ecf20Sopenharmony_ci p->fmt.win.bitmap = bitmap; 16108c2ecf20Sopenharmony_ci break; 16118c2ecf20Sopenharmony_ci } 16128c2ecf20Sopenharmony_ci default: 16138c2ecf20Sopenharmony_ci memset(&p->fmt, 0, sizeof(p->fmt)); 16148c2ecf20Sopenharmony_ci break; 16158c2ecf20Sopenharmony_ci } 16168c2ecf20Sopenharmony_ci 16178c2ecf20Sopenharmony_ci switch (p->type) { 16188c2ecf20Sopenharmony_ci case V4L2_BUF_TYPE_VIDEO_CAPTURE: 16198c2ecf20Sopenharmony_ci if (unlikely(!ops->vidioc_g_fmt_vid_cap)) 16208c2ecf20Sopenharmony_ci break; 16218c2ecf20Sopenharmony_ci p->fmt.pix.priv = V4L2_PIX_FMT_PRIV_MAGIC; 16228c2ecf20Sopenharmony_ci ret = ops->vidioc_g_fmt_vid_cap(file, fh, arg); 16238c2ecf20Sopenharmony_ci /* just in case the driver zeroed it again */ 16248c2ecf20Sopenharmony_ci p->fmt.pix.priv = V4L2_PIX_FMT_PRIV_MAGIC; 16258c2ecf20Sopenharmony_ci if (vfd->vfl_type == VFL_TYPE_TOUCH) 16268c2ecf20Sopenharmony_ci v4l_pix_format_touch(&p->fmt.pix); 16278c2ecf20Sopenharmony_ci return ret; 16288c2ecf20Sopenharmony_ci case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE: 16298c2ecf20Sopenharmony_ci return ops->vidioc_g_fmt_vid_cap_mplane(file, fh, arg); 16308c2ecf20Sopenharmony_ci case V4L2_BUF_TYPE_VIDEO_OVERLAY: 16318c2ecf20Sopenharmony_ci return ops->vidioc_g_fmt_vid_overlay(file, fh, arg); 16328c2ecf20Sopenharmony_ci case V4L2_BUF_TYPE_VBI_CAPTURE: 16338c2ecf20Sopenharmony_ci return ops->vidioc_g_fmt_vbi_cap(file, fh, arg); 16348c2ecf20Sopenharmony_ci case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE: 16358c2ecf20Sopenharmony_ci return ops->vidioc_g_fmt_sliced_vbi_cap(file, fh, arg); 16368c2ecf20Sopenharmony_ci case V4L2_BUF_TYPE_VIDEO_OUTPUT: 16378c2ecf20Sopenharmony_ci if (unlikely(!ops->vidioc_g_fmt_vid_out)) 16388c2ecf20Sopenharmony_ci break; 16398c2ecf20Sopenharmony_ci p->fmt.pix.priv = V4L2_PIX_FMT_PRIV_MAGIC; 16408c2ecf20Sopenharmony_ci ret = ops->vidioc_g_fmt_vid_out(file, fh, arg); 16418c2ecf20Sopenharmony_ci /* just in case the driver zeroed it again */ 16428c2ecf20Sopenharmony_ci p->fmt.pix.priv = V4L2_PIX_FMT_PRIV_MAGIC; 16438c2ecf20Sopenharmony_ci return ret; 16448c2ecf20Sopenharmony_ci case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE: 16458c2ecf20Sopenharmony_ci return ops->vidioc_g_fmt_vid_out_mplane(file, fh, arg); 16468c2ecf20Sopenharmony_ci case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY: 16478c2ecf20Sopenharmony_ci return ops->vidioc_g_fmt_vid_out_overlay(file, fh, arg); 16488c2ecf20Sopenharmony_ci case V4L2_BUF_TYPE_VBI_OUTPUT: 16498c2ecf20Sopenharmony_ci return ops->vidioc_g_fmt_vbi_out(file, fh, arg); 16508c2ecf20Sopenharmony_ci case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT: 16518c2ecf20Sopenharmony_ci return ops->vidioc_g_fmt_sliced_vbi_out(file, fh, arg); 16528c2ecf20Sopenharmony_ci case V4L2_BUF_TYPE_SDR_CAPTURE: 16538c2ecf20Sopenharmony_ci return ops->vidioc_g_fmt_sdr_cap(file, fh, arg); 16548c2ecf20Sopenharmony_ci case V4L2_BUF_TYPE_SDR_OUTPUT: 16558c2ecf20Sopenharmony_ci return ops->vidioc_g_fmt_sdr_out(file, fh, arg); 16568c2ecf20Sopenharmony_ci case V4L2_BUF_TYPE_META_CAPTURE: 16578c2ecf20Sopenharmony_ci return ops->vidioc_g_fmt_meta_cap(file, fh, arg); 16588c2ecf20Sopenharmony_ci case V4L2_BUF_TYPE_META_OUTPUT: 16598c2ecf20Sopenharmony_ci return ops->vidioc_g_fmt_meta_out(file, fh, arg); 16608c2ecf20Sopenharmony_ci } 16618c2ecf20Sopenharmony_ci return -EINVAL; 16628c2ecf20Sopenharmony_ci} 16638c2ecf20Sopenharmony_ci 16648c2ecf20Sopenharmony_cistatic int v4l_s_fmt(const struct v4l2_ioctl_ops *ops, 16658c2ecf20Sopenharmony_ci struct file *file, void *fh, void *arg) 16668c2ecf20Sopenharmony_ci{ 16678c2ecf20Sopenharmony_ci struct v4l2_format *p = arg; 16688c2ecf20Sopenharmony_ci struct video_device *vfd = video_devdata(file); 16698c2ecf20Sopenharmony_ci int ret = check_fmt(file, p->type); 16708c2ecf20Sopenharmony_ci unsigned int i; 16718c2ecf20Sopenharmony_ci 16728c2ecf20Sopenharmony_ci if (ret) 16738c2ecf20Sopenharmony_ci return ret; 16748c2ecf20Sopenharmony_ci 16758c2ecf20Sopenharmony_ci ret = v4l_enable_media_source(vfd); 16768c2ecf20Sopenharmony_ci if (ret) 16778c2ecf20Sopenharmony_ci return ret; 16788c2ecf20Sopenharmony_ci v4l_sanitize_format(p); 16798c2ecf20Sopenharmony_ci 16808c2ecf20Sopenharmony_ci switch (p->type) { 16818c2ecf20Sopenharmony_ci case V4L2_BUF_TYPE_VIDEO_CAPTURE: 16828c2ecf20Sopenharmony_ci if (unlikely(!ops->vidioc_s_fmt_vid_cap)) 16838c2ecf20Sopenharmony_ci break; 16848c2ecf20Sopenharmony_ci CLEAR_AFTER_FIELD(p, fmt.pix); 16858c2ecf20Sopenharmony_ci ret = ops->vidioc_s_fmt_vid_cap(file, fh, arg); 16868c2ecf20Sopenharmony_ci /* just in case the driver zeroed it again */ 16878c2ecf20Sopenharmony_ci p->fmt.pix.priv = V4L2_PIX_FMT_PRIV_MAGIC; 16888c2ecf20Sopenharmony_ci if (vfd->vfl_type == VFL_TYPE_TOUCH) 16898c2ecf20Sopenharmony_ci v4l_pix_format_touch(&p->fmt.pix); 16908c2ecf20Sopenharmony_ci return ret; 16918c2ecf20Sopenharmony_ci case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE: 16928c2ecf20Sopenharmony_ci if (unlikely(!ops->vidioc_s_fmt_vid_cap_mplane)) 16938c2ecf20Sopenharmony_ci break; 16948c2ecf20Sopenharmony_ci CLEAR_AFTER_FIELD(p, fmt.pix_mp.xfer_func); 16958c2ecf20Sopenharmony_ci for (i = 0; i < p->fmt.pix_mp.num_planes; i++) 16968c2ecf20Sopenharmony_ci CLEAR_AFTER_FIELD(&p->fmt.pix_mp.plane_fmt[i], 16978c2ecf20Sopenharmony_ci bytesperline); 16988c2ecf20Sopenharmony_ci return ops->vidioc_s_fmt_vid_cap_mplane(file, fh, arg); 16998c2ecf20Sopenharmony_ci case V4L2_BUF_TYPE_VIDEO_OVERLAY: 17008c2ecf20Sopenharmony_ci if (unlikely(!ops->vidioc_s_fmt_vid_overlay)) 17018c2ecf20Sopenharmony_ci break; 17028c2ecf20Sopenharmony_ci CLEAR_AFTER_FIELD(p, fmt.win); 17038c2ecf20Sopenharmony_ci return ops->vidioc_s_fmt_vid_overlay(file, fh, arg); 17048c2ecf20Sopenharmony_ci case V4L2_BUF_TYPE_VBI_CAPTURE: 17058c2ecf20Sopenharmony_ci if (unlikely(!ops->vidioc_s_fmt_vbi_cap)) 17068c2ecf20Sopenharmony_ci break; 17078c2ecf20Sopenharmony_ci CLEAR_AFTER_FIELD(p, fmt.vbi.flags); 17088c2ecf20Sopenharmony_ci return ops->vidioc_s_fmt_vbi_cap(file, fh, arg); 17098c2ecf20Sopenharmony_ci case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE: 17108c2ecf20Sopenharmony_ci if (unlikely(!ops->vidioc_s_fmt_sliced_vbi_cap)) 17118c2ecf20Sopenharmony_ci break; 17128c2ecf20Sopenharmony_ci CLEAR_AFTER_FIELD(p, fmt.sliced.io_size); 17138c2ecf20Sopenharmony_ci return ops->vidioc_s_fmt_sliced_vbi_cap(file, fh, arg); 17148c2ecf20Sopenharmony_ci case V4L2_BUF_TYPE_VIDEO_OUTPUT: 17158c2ecf20Sopenharmony_ci if (unlikely(!ops->vidioc_s_fmt_vid_out)) 17168c2ecf20Sopenharmony_ci break; 17178c2ecf20Sopenharmony_ci CLEAR_AFTER_FIELD(p, fmt.pix); 17188c2ecf20Sopenharmony_ci ret = ops->vidioc_s_fmt_vid_out(file, fh, arg); 17198c2ecf20Sopenharmony_ci /* just in case the driver zeroed it again */ 17208c2ecf20Sopenharmony_ci p->fmt.pix.priv = V4L2_PIX_FMT_PRIV_MAGIC; 17218c2ecf20Sopenharmony_ci return ret; 17228c2ecf20Sopenharmony_ci case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE: 17238c2ecf20Sopenharmony_ci if (unlikely(!ops->vidioc_s_fmt_vid_out_mplane)) 17248c2ecf20Sopenharmony_ci break; 17258c2ecf20Sopenharmony_ci CLEAR_AFTER_FIELD(p, fmt.pix_mp.xfer_func); 17268c2ecf20Sopenharmony_ci for (i = 0; i < p->fmt.pix_mp.num_planes; i++) 17278c2ecf20Sopenharmony_ci CLEAR_AFTER_FIELD(&p->fmt.pix_mp.plane_fmt[i], 17288c2ecf20Sopenharmony_ci bytesperline); 17298c2ecf20Sopenharmony_ci return ops->vidioc_s_fmt_vid_out_mplane(file, fh, arg); 17308c2ecf20Sopenharmony_ci case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY: 17318c2ecf20Sopenharmony_ci if (unlikely(!ops->vidioc_s_fmt_vid_out_overlay)) 17328c2ecf20Sopenharmony_ci break; 17338c2ecf20Sopenharmony_ci CLEAR_AFTER_FIELD(p, fmt.win); 17348c2ecf20Sopenharmony_ci return ops->vidioc_s_fmt_vid_out_overlay(file, fh, arg); 17358c2ecf20Sopenharmony_ci case V4L2_BUF_TYPE_VBI_OUTPUT: 17368c2ecf20Sopenharmony_ci if (unlikely(!ops->vidioc_s_fmt_vbi_out)) 17378c2ecf20Sopenharmony_ci break; 17388c2ecf20Sopenharmony_ci CLEAR_AFTER_FIELD(p, fmt.vbi.flags); 17398c2ecf20Sopenharmony_ci return ops->vidioc_s_fmt_vbi_out(file, fh, arg); 17408c2ecf20Sopenharmony_ci case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT: 17418c2ecf20Sopenharmony_ci if (unlikely(!ops->vidioc_s_fmt_sliced_vbi_out)) 17428c2ecf20Sopenharmony_ci break; 17438c2ecf20Sopenharmony_ci CLEAR_AFTER_FIELD(p, fmt.sliced.io_size); 17448c2ecf20Sopenharmony_ci return ops->vidioc_s_fmt_sliced_vbi_out(file, fh, arg); 17458c2ecf20Sopenharmony_ci case V4L2_BUF_TYPE_SDR_CAPTURE: 17468c2ecf20Sopenharmony_ci if (unlikely(!ops->vidioc_s_fmt_sdr_cap)) 17478c2ecf20Sopenharmony_ci break; 17488c2ecf20Sopenharmony_ci CLEAR_AFTER_FIELD(p, fmt.sdr.buffersize); 17498c2ecf20Sopenharmony_ci return ops->vidioc_s_fmt_sdr_cap(file, fh, arg); 17508c2ecf20Sopenharmony_ci case V4L2_BUF_TYPE_SDR_OUTPUT: 17518c2ecf20Sopenharmony_ci if (unlikely(!ops->vidioc_s_fmt_sdr_out)) 17528c2ecf20Sopenharmony_ci break; 17538c2ecf20Sopenharmony_ci CLEAR_AFTER_FIELD(p, fmt.sdr.buffersize); 17548c2ecf20Sopenharmony_ci return ops->vidioc_s_fmt_sdr_out(file, fh, arg); 17558c2ecf20Sopenharmony_ci case V4L2_BUF_TYPE_META_CAPTURE: 17568c2ecf20Sopenharmony_ci if (unlikely(!ops->vidioc_s_fmt_meta_cap)) 17578c2ecf20Sopenharmony_ci break; 17588c2ecf20Sopenharmony_ci CLEAR_AFTER_FIELD(p, fmt.meta); 17598c2ecf20Sopenharmony_ci return ops->vidioc_s_fmt_meta_cap(file, fh, arg); 17608c2ecf20Sopenharmony_ci case V4L2_BUF_TYPE_META_OUTPUT: 17618c2ecf20Sopenharmony_ci if (unlikely(!ops->vidioc_s_fmt_meta_out)) 17628c2ecf20Sopenharmony_ci break; 17638c2ecf20Sopenharmony_ci CLEAR_AFTER_FIELD(p, fmt.meta); 17648c2ecf20Sopenharmony_ci return ops->vidioc_s_fmt_meta_out(file, fh, arg); 17658c2ecf20Sopenharmony_ci } 17668c2ecf20Sopenharmony_ci return -EINVAL; 17678c2ecf20Sopenharmony_ci} 17688c2ecf20Sopenharmony_ci 17698c2ecf20Sopenharmony_cistatic int v4l_try_fmt(const struct v4l2_ioctl_ops *ops, 17708c2ecf20Sopenharmony_ci struct file *file, void *fh, void *arg) 17718c2ecf20Sopenharmony_ci{ 17728c2ecf20Sopenharmony_ci struct v4l2_format *p = arg; 17738c2ecf20Sopenharmony_ci struct video_device *vfd = video_devdata(file); 17748c2ecf20Sopenharmony_ci int ret = check_fmt(file, p->type); 17758c2ecf20Sopenharmony_ci unsigned int i; 17768c2ecf20Sopenharmony_ci 17778c2ecf20Sopenharmony_ci if (ret) 17788c2ecf20Sopenharmony_ci return ret; 17798c2ecf20Sopenharmony_ci 17808c2ecf20Sopenharmony_ci v4l_sanitize_format(p); 17818c2ecf20Sopenharmony_ci 17828c2ecf20Sopenharmony_ci switch (p->type) { 17838c2ecf20Sopenharmony_ci case V4L2_BUF_TYPE_VIDEO_CAPTURE: 17848c2ecf20Sopenharmony_ci if (unlikely(!ops->vidioc_try_fmt_vid_cap)) 17858c2ecf20Sopenharmony_ci break; 17868c2ecf20Sopenharmony_ci CLEAR_AFTER_FIELD(p, fmt.pix); 17878c2ecf20Sopenharmony_ci ret = ops->vidioc_try_fmt_vid_cap(file, fh, arg); 17888c2ecf20Sopenharmony_ci /* just in case the driver zeroed it again */ 17898c2ecf20Sopenharmony_ci p->fmt.pix.priv = V4L2_PIX_FMT_PRIV_MAGIC; 17908c2ecf20Sopenharmony_ci if (vfd->vfl_type == VFL_TYPE_TOUCH) 17918c2ecf20Sopenharmony_ci v4l_pix_format_touch(&p->fmt.pix); 17928c2ecf20Sopenharmony_ci return ret; 17938c2ecf20Sopenharmony_ci case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE: 17948c2ecf20Sopenharmony_ci if (unlikely(!ops->vidioc_try_fmt_vid_cap_mplane)) 17958c2ecf20Sopenharmony_ci break; 17968c2ecf20Sopenharmony_ci CLEAR_AFTER_FIELD(p, fmt.pix_mp.xfer_func); 17978c2ecf20Sopenharmony_ci for (i = 0; i < p->fmt.pix_mp.num_planes; i++) 17988c2ecf20Sopenharmony_ci CLEAR_AFTER_FIELD(&p->fmt.pix_mp.plane_fmt[i], 17998c2ecf20Sopenharmony_ci bytesperline); 18008c2ecf20Sopenharmony_ci return ops->vidioc_try_fmt_vid_cap_mplane(file, fh, arg); 18018c2ecf20Sopenharmony_ci case V4L2_BUF_TYPE_VIDEO_OVERLAY: 18028c2ecf20Sopenharmony_ci if (unlikely(!ops->vidioc_try_fmt_vid_overlay)) 18038c2ecf20Sopenharmony_ci break; 18048c2ecf20Sopenharmony_ci CLEAR_AFTER_FIELD(p, fmt.win); 18058c2ecf20Sopenharmony_ci return ops->vidioc_try_fmt_vid_overlay(file, fh, arg); 18068c2ecf20Sopenharmony_ci case V4L2_BUF_TYPE_VBI_CAPTURE: 18078c2ecf20Sopenharmony_ci if (unlikely(!ops->vidioc_try_fmt_vbi_cap)) 18088c2ecf20Sopenharmony_ci break; 18098c2ecf20Sopenharmony_ci CLEAR_AFTER_FIELD(p, fmt.vbi.flags); 18108c2ecf20Sopenharmony_ci return ops->vidioc_try_fmt_vbi_cap(file, fh, arg); 18118c2ecf20Sopenharmony_ci case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE: 18128c2ecf20Sopenharmony_ci if (unlikely(!ops->vidioc_try_fmt_sliced_vbi_cap)) 18138c2ecf20Sopenharmony_ci break; 18148c2ecf20Sopenharmony_ci CLEAR_AFTER_FIELD(p, fmt.sliced.io_size); 18158c2ecf20Sopenharmony_ci return ops->vidioc_try_fmt_sliced_vbi_cap(file, fh, arg); 18168c2ecf20Sopenharmony_ci case V4L2_BUF_TYPE_VIDEO_OUTPUT: 18178c2ecf20Sopenharmony_ci if (unlikely(!ops->vidioc_try_fmt_vid_out)) 18188c2ecf20Sopenharmony_ci break; 18198c2ecf20Sopenharmony_ci CLEAR_AFTER_FIELD(p, fmt.pix); 18208c2ecf20Sopenharmony_ci ret = ops->vidioc_try_fmt_vid_out(file, fh, arg); 18218c2ecf20Sopenharmony_ci /* just in case the driver zeroed it again */ 18228c2ecf20Sopenharmony_ci p->fmt.pix.priv = V4L2_PIX_FMT_PRIV_MAGIC; 18238c2ecf20Sopenharmony_ci return ret; 18248c2ecf20Sopenharmony_ci case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE: 18258c2ecf20Sopenharmony_ci if (unlikely(!ops->vidioc_try_fmt_vid_out_mplane)) 18268c2ecf20Sopenharmony_ci break; 18278c2ecf20Sopenharmony_ci CLEAR_AFTER_FIELD(p, fmt.pix_mp.xfer_func); 18288c2ecf20Sopenharmony_ci for (i = 0; i < p->fmt.pix_mp.num_planes; i++) 18298c2ecf20Sopenharmony_ci CLEAR_AFTER_FIELD(&p->fmt.pix_mp.plane_fmt[i], 18308c2ecf20Sopenharmony_ci bytesperline); 18318c2ecf20Sopenharmony_ci return ops->vidioc_try_fmt_vid_out_mplane(file, fh, arg); 18328c2ecf20Sopenharmony_ci case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY: 18338c2ecf20Sopenharmony_ci if (unlikely(!ops->vidioc_try_fmt_vid_out_overlay)) 18348c2ecf20Sopenharmony_ci break; 18358c2ecf20Sopenharmony_ci CLEAR_AFTER_FIELD(p, fmt.win); 18368c2ecf20Sopenharmony_ci return ops->vidioc_try_fmt_vid_out_overlay(file, fh, arg); 18378c2ecf20Sopenharmony_ci case V4L2_BUF_TYPE_VBI_OUTPUT: 18388c2ecf20Sopenharmony_ci if (unlikely(!ops->vidioc_try_fmt_vbi_out)) 18398c2ecf20Sopenharmony_ci break; 18408c2ecf20Sopenharmony_ci CLEAR_AFTER_FIELD(p, fmt.vbi.flags); 18418c2ecf20Sopenharmony_ci return ops->vidioc_try_fmt_vbi_out(file, fh, arg); 18428c2ecf20Sopenharmony_ci case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT: 18438c2ecf20Sopenharmony_ci if (unlikely(!ops->vidioc_try_fmt_sliced_vbi_out)) 18448c2ecf20Sopenharmony_ci break; 18458c2ecf20Sopenharmony_ci CLEAR_AFTER_FIELD(p, fmt.sliced.io_size); 18468c2ecf20Sopenharmony_ci return ops->vidioc_try_fmt_sliced_vbi_out(file, fh, arg); 18478c2ecf20Sopenharmony_ci case V4L2_BUF_TYPE_SDR_CAPTURE: 18488c2ecf20Sopenharmony_ci if (unlikely(!ops->vidioc_try_fmt_sdr_cap)) 18498c2ecf20Sopenharmony_ci break; 18508c2ecf20Sopenharmony_ci CLEAR_AFTER_FIELD(p, fmt.sdr.buffersize); 18518c2ecf20Sopenharmony_ci return ops->vidioc_try_fmt_sdr_cap(file, fh, arg); 18528c2ecf20Sopenharmony_ci case V4L2_BUF_TYPE_SDR_OUTPUT: 18538c2ecf20Sopenharmony_ci if (unlikely(!ops->vidioc_try_fmt_sdr_out)) 18548c2ecf20Sopenharmony_ci break; 18558c2ecf20Sopenharmony_ci CLEAR_AFTER_FIELD(p, fmt.sdr.buffersize); 18568c2ecf20Sopenharmony_ci return ops->vidioc_try_fmt_sdr_out(file, fh, arg); 18578c2ecf20Sopenharmony_ci case V4L2_BUF_TYPE_META_CAPTURE: 18588c2ecf20Sopenharmony_ci if (unlikely(!ops->vidioc_try_fmt_meta_cap)) 18598c2ecf20Sopenharmony_ci break; 18608c2ecf20Sopenharmony_ci CLEAR_AFTER_FIELD(p, fmt.meta); 18618c2ecf20Sopenharmony_ci return ops->vidioc_try_fmt_meta_cap(file, fh, arg); 18628c2ecf20Sopenharmony_ci case V4L2_BUF_TYPE_META_OUTPUT: 18638c2ecf20Sopenharmony_ci if (unlikely(!ops->vidioc_try_fmt_meta_out)) 18648c2ecf20Sopenharmony_ci break; 18658c2ecf20Sopenharmony_ci CLEAR_AFTER_FIELD(p, fmt.meta); 18668c2ecf20Sopenharmony_ci return ops->vidioc_try_fmt_meta_out(file, fh, arg); 18678c2ecf20Sopenharmony_ci } 18688c2ecf20Sopenharmony_ci return -EINVAL; 18698c2ecf20Sopenharmony_ci} 18708c2ecf20Sopenharmony_ci 18718c2ecf20Sopenharmony_cistatic int v4l_streamon(const struct v4l2_ioctl_ops *ops, 18728c2ecf20Sopenharmony_ci struct file *file, void *fh, void *arg) 18738c2ecf20Sopenharmony_ci{ 18748c2ecf20Sopenharmony_ci return ops->vidioc_streamon(file, fh, *(unsigned int *)arg); 18758c2ecf20Sopenharmony_ci} 18768c2ecf20Sopenharmony_ci 18778c2ecf20Sopenharmony_cistatic int v4l_streamoff(const struct v4l2_ioctl_ops *ops, 18788c2ecf20Sopenharmony_ci struct file *file, void *fh, void *arg) 18798c2ecf20Sopenharmony_ci{ 18808c2ecf20Sopenharmony_ci return ops->vidioc_streamoff(file, fh, *(unsigned int *)arg); 18818c2ecf20Sopenharmony_ci} 18828c2ecf20Sopenharmony_ci 18838c2ecf20Sopenharmony_cistatic int v4l_g_tuner(const struct v4l2_ioctl_ops *ops, 18848c2ecf20Sopenharmony_ci struct file *file, void *fh, void *arg) 18858c2ecf20Sopenharmony_ci{ 18868c2ecf20Sopenharmony_ci struct video_device *vfd = video_devdata(file); 18878c2ecf20Sopenharmony_ci struct v4l2_tuner *p = arg; 18888c2ecf20Sopenharmony_ci int err; 18898c2ecf20Sopenharmony_ci 18908c2ecf20Sopenharmony_ci p->type = (vfd->vfl_type == VFL_TYPE_RADIO) ? 18918c2ecf20Sopenharmony_ci V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV; 18928c2ecf20Sopenharmony_ci err = ops->vidioc_g_tuner(file, fh, p); 18938c2ecf20Sopenharmony_ci if (!err) 18948c2ecf20Sopenharmony_ci p->capability |= V4L2_TUNER_CAP_FREQ_BANDS; 18958c2ecf20Sopenharmony_ci return err; 18968c2ecf20Sopenharmony_ci} 18978c2ecf20Sopenharmony_ci 18988c2ecf20Sopenharmony_cistatic int v4l_s_tuner(const struct v4l2_ioctl_ops *ops, 18998c2ecf20Sopenharmony_ci struct file *file, void *fh, void *arg) 19008c2ecf20Sopenharmony_ci{ 19018c2ecf20Sopenharmony_ci struct video_device *vfd = video_devdata(file); 19028c2ecf20Sopenharmony_ci struct v4l2_tuner *p = arg; 19038c2ecf20Sopenharmony_ci int ret; 19048c2ecf20Sopenharmony_ci 19058c2ecf20Sopenharmony_ci ret = v4l_enable_media_source(vfd); 19068c2ecf20Sopenharmony_ci if (ret) 19078c2ecf20Sopenharmony_ci return ret; 19088c2ecf20Sopenharmony_ci p->type = (vfd->vfl_type == VFL_TYPE_RADIO) ? 19098c2ecf20Sopenharmony_ci V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV; 19108c2ecf20Sopenharmony_ci return ops->vidioc_s_tuner(file, fh, p); 19118c2ecf20Sopenharmony_ci} 19128c2ecf20Sopenharmony_ci 19138c2ecf20Sopenharmony_cistatic int v4l_g_modulator(const struct v4l2_ioctl_ops *ops, 19148c2ecf20Sopenharmony_ci struct file *file, void *fh, void *arg) 19158c2ecf20Sopenharmony_ci{ 19168c2ecf20Sopenharmony_ci struct video_device *vfd = video_devdata(file); 19178c2ecf20Sopenharmony_ci struct v4l2_modulator *p = arg; 19188c2ecf20Sopenharmony_ci int err; 19198c2ecf20Sopenharmony_ci 19208c2ecf20Sopenharmony_ci if (vfd->vfl_type == VFL_TYPE_RADIO) 19218c2ecf20Sopenharmony_ci p->type = V4L2_TUNER_RADIO; 19228c2ecf20Sopenharmony_ci 19238c2ecf20Sopenharmony_ci err = ops->vidioc_g_modulator(file, fh, p); 19248c2ecf20Sopenharmony_ci if (!err) 19258c2ecf20Sopenharmony_ci p->capability |= V4L2_TUNER_CAP_FREQ_BANDS; 19268c2ecf20Sopenharmony_ci return err; 19278c2ecf20Sopenharmony_ci} 19288c2ecf20Sopenharmony_ci 19298c2ecf20Sopenharmony_cistatic int v4l_s_modulator(const struct v4l2_ioctl_ops *ops, 19308c2ecf20Sopenharmony_ci struct file *file, void *fh, void *arg) 19318c2ecf20Sopenharmony_ci{ 19328c2ecf20Sopenharmony_ci struct video_device *vfd = video_devdata(file); 19338c2ecf20Sopenharmony_ci struct v4l2_modulator *p = arg; 19348c2ecf20Sopenharmony_ci 19358c2ecf20Sopenharmony_ci if (vfd->vfl_type == VFL_TYPE_RADIO) 19368c2ecf20Sopenharmony_ci p->type = V4L2_TUNER_RADIO; 19378c2ecf20Sopenharmony_ci 19388c2ecf20Sopenharmony_ci return ops->vidioc_s_modulator(file, fh, p); 19398c2ecf20Sopenharmony_ci} 19408c2ecf20Sopenharmony_ci 19418c2ecf20Sopenharmony_cistatic int v4l_g_frequency(const struct v4l2_ioctl_ops *ops, 19428c2ecf20Sopenharmony_ci struct file *file, void *fh, void *arg) 19438c2ecf20Sopenharmony_ci{ 19448c2ecf20Sopenharmony_ci struct video_device *vfd = video_devdata(file); 19458c2ecf20Sopenharmony_ci struct v4l2_frequency *p = arg; 19468c2ecf20Sopenharmony_ci 19478c2ecf20Sopenharmony_ci if (vfd->vfl_type == VFL_TYPE_SDR) 19488c2ecf20Sopenharmony_ci p->type = V4L2_TUNER_SDR; 19498c2ecf20Sopenharmony_ci else 19508c2ecf20Sopenharmony_ci p->type = (vfd->vfl_type == VFL_TYPE_RADIO) ? 19518c2ecf20Sopenharmony_ci V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV; 19528c2ecf20Sopenharmony_ci return ops->vidioc_g_frequency(file, fh, p); 19538c2ecf20Sopenharmony_ci} 19548c2ecf20Sopenharmony_ci 19558c2ecf20Sopenharmony_cistatic int v4l_s_frequency(const struct v4l2_ioctl_ops *ops, 19568c2ecf20Sopenharmony_ci struct file *file, void *fh, void *arg) 19578c2ecf20Sopenharmony_ci{ 19588c2ecf20Sopenharmony_ci struct video_device *vfd = video_devdata(file); 19598c2ecf20Sopenharmony_ci const struct v4l2_frequency *p = arg; 19608c2ecf20Sopenharmony_ci enum v4l2_tuner_type type; 19618c2ecf20Sopenharmony_ci int ret; 19628c2ecf20Sopenharmony_ci 19638c2ecf20Sopenharmony_ci ret = v4l_enable_media_source(vfd); 19648c2ecf20Sopenharmony_ci if (ret) 19658c2ecf20Sopenharmony_ci return ret; 19668c2ecf20Sopenharmony_ci if (vfd->vfl_type == VFL_TYPE_SDR) { 19678c2ecf20Sopenharmony_ci if (p->type != V4L2_TUNER_SDR && p->type != V4L2_TUNER_RF) 19688c2ecf20Sopenharmony_ci return -EINVAL; 19698c2ecf20Sopenharmony_ci } else { 19708c2ecf20Sopenharmony_ci type = (vfd->vfl_type == VFL_TYPE_RADIO) ? 19718c2ecf20Sopenharmony_ci V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV; 19728c2ecf20Sopenharmony_ci if (type != p->type) 19738c2ecf20Sopenharmony_ci return -EINVAL; 19748c2ecf20Sopenharmony_ci } 19758c2ecf20Sopenharmony_ci return ops->vidioc_s_frequency(file, fh, p); 19768c2ecf20Sopenharmony_ci} 19778c2ecf20Sopenharmony_ci 19788c2ecf20Sopenharmony_cistatic int v4l_enumstd(const struct v4l2_ioctl_ops *ops, 19798c2ecf20Sopenharmony_ci struct file *file, void *fh, void *arg) 19808c2ecf20Sopenharmony_ci{ 19818c2ecf20Sopenharmony_ci struct video_device *vfd = video_devdata(file); 19828c2ecf20Sopenharmony_ci struct v4l2_standard *p = arg; 19838c2ecf20Sopenharmony_ci 19848c2ecf20Sopenharmony_ci return v4l_video_std_enumstd(p, vfd->tvnorms); 19858c2ecf20Sopenharmony_ci} 19868c2ecf20Sopenharmony_ci 19878c2ecf20Sopenharmony_cistatic int v4l_s_std(const struct v4l2_ioctl_ops *ops, 19888c2ecf20Sopenharmony_ci struct file *file, void *fh, void *arg) 19898c2ecf20Sopenharmony_ci{ 19908c2ecf20Sopenharmony_ci struct video_device *vfd = video_devdata(file); 19918c2ecf20Sopenharmony_ci v4l2_std_id id = *(v4l2_std_id *)arg, norm; 19928c2ecf20Sopenharmony_ci int ret; 19938c2ecf20Sopenharmony_ci 19948c2ecf20Sopenharmony_ci ret = v4l_enable_media_source(vfd); 19958c2ecf20Sopenharmony_ci if (ret) 19968c2ecf20Sopenharmony_ci return ret; 19978c2ecf20Sopenharmony_ci norm = id & vfd->tvnorms; 19988c2ecf20Sopenharmony_ci if (vfd->tvnorms && !norm) /* Check if std is supported */ 19998c2ecf20Sopenharmony_ci return -EINVAL; 20008c2ecf20Sopenharmony_ci 20018c2ecf20Sopenharmony_ci /* Calls the specific handler */ 20028c2ecf20Sopenharmony_ci return ops->vidioc_s_std(file, fh, norm); 20038c2ecf20Sopenharmony_ci} 20048c2ecf20Sopenharmony_ci 20058c2ecf20Sopenharmony_cistatic int v4l_querystd(const struct v4l2_ioctl_ops *ops, 20068c2ecf20Sopenharmony_ci struct file *file, void *fh, void *arg) 20078c2ecf20Sopenharmony_ci{ 20088c2ecf20Sopenharmony_ci struct video_device *vfd = video_devdata(file); 20098c2ecf20Sopenharmony_ci v4l2_std_id *p = arg; 20108c2ecf20Sopenharmony_ci int ret; 20118c2ecf20Sopenharmony_ci 20128c2ecf20Sopenharmony_ci ret = v4l_enable_media_source(vfd); 20138c2ecf20Sopenharmony_ci if (ret) 20148c2ecf20Sopenharmony_ci return ret; 20158c2ecf20Sopenharmony_ci /* 20168c2ecf20Sopenharmony_ci * If no signal is detected, then the driver should return 20178c2ecf20Sopenharmony_ci * V4L2_STD_UNKNOWN. Otherwise it should return tvnorms with 20188c2ecf20Sopenharmony_ci * any standards that do not apply removed. 20198c2ecf20Sopenharmony_ci * 20208c2ecf20Sopenharmony_ci * This means that tuners, audio and video decoders can join 20218c2ecf20Sopenharmony_ci * their efforts to improve the standards detection. 20228c2ecf20Sopenharmony_ci */ 20238c2ecf20Sopenharmony_ci *p = vfd->tvnorms; 20248c2ecf20Sopenharmony_ci return ops->vidioc_querystd(file, fh, arg); 20258c2ecf20Sopenharmony_ci} 20268c2ecf20Sopenharmony_ci 20278c2ecf20Sopenharmony_cistatic int v4l_s_hw_freq_seek(const struct v4l2_ioctl_ops *ops, 20288c2ecf20Sopenharmony_ci struct file *file, void *fh, void *arg) 20298c2ecf20Sopenharmony_ci{ 20308c2ecf20Sopenharmony_ci struct video_device *vfd = video_devdata(file); 20318c2ecf20Sopenharmony_ci struct v4l2_hw_freq_seek *p = arg; 20328c2ecf20Sopenharmony_ci enum v4l2_tuner_type type; 20338c2ecf20Sopenharmony_ci int ret; 20348c2ecf20Sopenharmony_ci 20358c2ecf20Sopenharmony_ci ret = v4l_enable_media_source(vfd); 20368c2ecf20Sopenharmony_ci if (ret) 20378c2ecf20Sopenharmony_ci return ret; 20388c2ecf20Sopenharmony_ci /* s_hw_freq_seek is not supported for SDR for now */ 20398c2ecf20Sopenharmony_ci if (vfd->vfl_type == VFL_TYPE_SDR) 20408c2ecf20Sopenharmony_ci return -EINVAL; 20418c2ecf20Sopenharmony_ci 20428c2ecf20Sopenharmony_ci type = (vfd->vfl_type == VFL_TYPE_RADIO) ? 20438c2ecf20Sopenharmony_ci V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV; 20448c2ecf20Sopenharmony_ci if (p->type != type) 20458c2ecf20Sopenharmony_ci return -EINVAL; 20468c2ecf20Sopenharmony_ci return ops->vidioc_s_hw_freq_seek(file, fh, p); 20478c2ecf20Sopenharmony_ci} 20488c2ecf20Sopenharmony_ci 20498c2ecf20Sopenharmony_cistatic int v4l_overlay(const struct v4l2_ioctl_ops *ops, 20508c2ecf20Sopenharmony_ci struct file *file, void *fh, void *arg) 20518c2ecf20Sopenharmony_ci{ 20528c2ecf20Sopenharmony_ci return ops->vidioc_overlay(file, fh, *(unsigned int *)arg); 20538c2ecf20Sopenharmony_ci} 20548c2ecf20Sopenharmony_ci 20558c2ecf20Sopenharmony_cistatic int v4l_reqbufs(const struct v4l2_ioctl_ops *ops, 20568c2ecf20Sopenharmony_ci struct file *file, void *fh, void *arg) 20578c2ecf20Sopenharmony_ci{ 20588c2ecf20Sopenharmony_ci struct v4l2_requestbuffers *p = arg; 20598c2ecf20Sopenharmony_ci int ret = check_fmt(file, p->type); 20608c2ecf20Sopenharmony_ci 20618c2ecf20Sopenharmony_ci if (ret) 20628c2ecf20Sopenharmony_ci return ret; 20638c2ecf20Sopenharmony_ci 20648c2ecf20Sopenharmony_ci CLEAR_AFTER_FIELD(p, capabilities); 20658c2ecf20Sopenharmony_ci 20668c2ecf20Sopenharmony_ci return ops->vidioc_reqbufs(file, fh, p); 20678c2ecf20Sopenharmony_ci} 20688c2ecf20Sopenharmony_ci 20698c2ecf20Sopenharmony_cistatic int v4l_querybuf(const struct v4l2_ioctl_ops *ops, 20708c2ecf20Sopenharmony_ci struct file *file, void *fh, void *arg) 20718c2ecf20Sopenharmony_ci{ 20728c2ecf20Sopenharmony_ci struct v4l2_buffer *p = arg; 20738c2ecf20Sopenharmony_ci int ret = check_fmt(file, p->type); 20748c2ecf20Sopenharmony_ci 20758c2ecf20Sopenharmony_ci return ret ? ret : ops->vidioc_querybuf(file, fh, p); 20768c2ecf20Sopenharmony_ci} 20778c2ecf20Sopenharmony_ci 20788c2ecf20Sopenharmony_cistatic int v4l_qbuf(const struct v4l2_ioctl_ops *ops, 20798c2ecf20Sopenharmony_ci struct file *file, void *fh, void *arg) 20808c2ecf20Sopenharmony_ci{ 20818c2ecf20Sopenharmony_ci struct v4l2_buffer *p = arg; 20828c2ecf20Sopenharmony_ci int ret = check_fmt(file, p->type); 20838c2ecf20Sopenharmony_ci 20848c2ecf20Sopenharmony_ci return ret ? ret : ops->vidioc_qbuf(file, fh, p); 20858c2ecf20Sopenharmony_ci} 20868c2ecf20Sopenharmony_ci 20878c2ecf20Sopenharmony_cistatic int v4l_dqbuf(const struct v4l2_ioctl_ops *ops, 20888c2ecf20Sopenharmony_ci struct file *file, void *fh, void *arg) 20898c2ecf20Sopenharmony_ci{ 20908c2ecf20Sopenharmony_ci struct v4l2_buffer *p = arg; 20918c2ecf20Sopenharmony_ci int ret = check_fmt(file, p->type); 20928c2ecf20Sopenharmony_ci 20938c2ecf20Sopenharmony_ci return ret ? ret : ops->vidioc_dqbuf(file, fh, p); 20948c2ecf20Sopenharmony_ci} 20958c2ecf20Sopenharmony_ci 20968c2ecf20Sopenharmony_cistatic int v4l_create_bufs(const struct v4l2_ioctl_ops *ops, 20978c2ecf20Sopenharmony_ci struct file *file, void *fh, void *arg) 20988c2ecf20Sopenharmony_ci{ 20998c2ecf20Sopenharmony_ci struct v4l2_create_buffers *create = arg; 21008c2ecf20Sopenharmony_ci int ret = check_fmt(file, create->format.type); 21018c2ecf20Sopenharmony_ci 21028c2ecf20Sopenharmony_ci if (ret) 21038c2ecf20Sopenharmony_ci return ret; 21048c2ecf20Sopenharmony_ci 21058c2ecf20Sopenharmony_ci CLEAR_AFTER_FIELD(create, capabilities); 21068c2ecf20Sopenharmony_ci 21078c2ecf20Sopenharmony_ci v4l_sanitize_format(&create->format); 21088c2ecf20Sopenharmony_ci 21098c2ecf20Sopenharmony_ci ret = ops->vidioc_create_bufs(file, fh, create); 21108c2ecf20Sopenharmony_ci 21118c2ecf20Sopenharmony_ci if (create->format.type == V4L2_BUF_TYPE_VIDEO_CAPTURE || 21128c2ecf20Sopenharmony_ci create->format.type == V4L2_BUF_TYPE_VIDEO_OUTPUT) 21138c2ecf20Sopenharmony_ci create->format.fmt.pix.priv = V4L2_PIX_FMT_PRIV_MAGIC; 21148c2ecf20Sopenharmony_ci 21158c2ecf20Sopenharmony_ci return ret; 21168c2ecf20Sopenharmony_ci} 21178c2ecf20Sopenharmony_ci 21188c2ecf20Sopenharmony_cistatic int v4l_prepare_buf(const struct v4l2_ioctl_ops *ops, 21198c2ecf20Sopenharmony_ci struct file *file, void *fh, void *arg) 21208c2ecf20Sopenharmony_ci{ 21218c2ecf20Sopenharmony_ci struct v4l2_buffer *b = arg; 21228c2ecf20Sopenharmony_ci int ret = check_fmt(file, b->type); 21238c2ecf20Sopenharmony_ci 21248c2ecf20Sopenharmony_ci return ret ? ret : ops->vidioc_prepare_buf(file, fh, b); 21258c2ecf20Sopenharmony_ci} 21268c2ecf20Sopenharmony_ci 21278c2ecf20Sopenharmony_cistatic int v4l_g_parm(const struct v4l2_ioctl_ops *ops, 21288c2ecf20Sopenharmony_ci struct file *file, void *fh, void *arg) 21298c2ecf20Sopenharmony_ci{ 21308c2ecf20Sopenharmony_ci struct video_device *vfd = video_devdata(file); 21318c2ecf20Sopenharmony_ci struct v4l2_streamparm *p = arg; 21328c2ecf20Sopenharmony_ci v4l2_std_id std; 21338c2ecf20Sopenharmony_ci int ret = check_fmt(file, p->type); 21348c2ecf20Sopenharmony_ci 21358c2ecf20Sopenharmony_ci if (ret) 21368c2ecf20Sopenharmony_ci return ret; 21378c2ecf20Sopenharmony_ci if (ops->vidioc_g_parm) 21388c2ecf20Sopenharmony_ci return ops->vidioc_g_parm(file, fh, p); 21398c2ecf20Sopenharmony_ci if (p->type != V4L2_BUF_TYPE_VIDEO_CAPTURE && 21408c2ecf20Sopenharmony_ci p->type != V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) 21418c2ecf20Sopenharmony_ci return -EINVAL; 21428c2ecf20Sopenharmony_ci if (vfd->device_caps & V4L2_CAP_READWRITE) 21438c2ecf20Sopenharmony_ci p->parm.capture.readbuffers = 2; 21448c2ecf20Sopenharmony_ci ret = ops->vidioc_g_std(file, fh, &std); 21458c2ecf20Sopenharmony_ci if (ret == 0) 21468c2ecf20Sopenharmony_ci v4l2_video_std_frame_period(std, &p->parm.capture.timeperframe); 21478c2ecf20Sopenharmony_ci return ret; 21488c2ecf20Sopenharmony_ci} 21498c2ecf20Sopenharmony_ci 21508c2ecf20Sopenharmony_cistatic int v4l_s_parm(const struct v4l2_ioctl_ops *ops, 21518c2ecf20Sopenharmony_ci struct file *file, void *fh, void *arg) 21528c2ecf20Sopenharmony_ci{ 21538c2ecf20Sopenharmony_ci struct v4l2_streamparm *p = arg; 21548c2ecf20Sopenharmony_ci int ret = check_fmt(file, p->type); 21558c2ecf20Sopenharmony_ci 21568c2ecf20Sopenharmony_ci if (ret) 21578c2ecf20Sopenharmony_ci return ret; 21588c2ecf20Sopenharmony_ci 21598c2ecf20Sopenharmony_ci /* Note: extendedmode is never used in drivers */ 21608c2ecf20Sopenharmony_ci if (V4L2_TYPE_IS_OUTPUT(p->type)) { 21618c2ecf20Sopenharmony_ci memset(p->parm.output.reserved, 0, 21628c2ecf20Sopenharmony_ci sizeof(p->parm.output.reserved)); 21638c2ecf20Sopenharmony_ci p->parm.output.extendedmode = 0; 21648c2ecf20Sopenharmony_ci p->parm.output.outputmode &= V4L2_MODE_HIGHQUALITY; 21658c2ecf20Sopenharmony_ci } else { 21668c2ecf20Sopenharmony_ci memset(p->parm.capture.reserved, 0, 21678c2ecf20Sopenharmony_ci sizeof(p->parm.capture.reserved)); 21688c2ecf20Sopenharmony_ci p->parm.capture.extendedmode = 0; 21698c2ecf20Sopenharmony_ci p->parm.capture.capturemode &= V4L2_MODE_HIGHQUALITY; 21708c2ecf20Sopenharmony_ci } 21718c2ecf20Sopenharmony_ci return ops->vidioc_s_parm(file, fh, p); 21728c2ecf20Sopenharmony_ci} 21738c2ecf20Sopenharmony_ci 21748c2ecf20Sopenharmony_cistatic int v4l_queryctrl(const struct v4l2_ioctl_ops *ops, 21758c2ecf20Sopenharmony_ci struct file *file, void *fh, void *arg) 21768c2ecf20Sopenharmony_ci{ 21778c2ecf20Sopenharmony_ci struct video_device *vfd = video_devdata(file); 21788c2ecf20Sopenharmony_ci struct v4l2_queryctrl *p = arg; 21798c2ecf20Sopenharmony_ci struct v4l2_fh *vfh = 21808c2ecf20Sopenharmony_ci test_bit(V4L2_FL_USES_V4L2_FH, &vfd->flags) ? fh : NULL; 21818c2ecf20Sopenharmony_ci 21828c2ecf20Sopenharmony_ci if (vfh && vfh->ctrl_handler) 21838c2ecf20Sopenharmony_ci return v4l2_queryctrl(vfh->ctrl_handler, p); 21848c2ecf20Sopenharmony_ci if (vfd->ctrl_handler) 21858c2ecf20Sopenharmony_ci return v4l2_queryctrl(vfd->ctrl_handler, p); 21868c2ecf20Sopenharmony_ci if (ops->vidioc_queryctrl) 21878c2ecf20Sopenharmony_ci return ops->vidioc_queryctrl(file, fh, p); 21888c2ecf20Sopenharmony_ci return -ENOTTY; 21898c2ecf20Sopenharmony_ci} 21908c2ecf20Sopenharmony_ci 21918c2ecf20Sopenharmony_cistatic int v4l_query_ext_ctrl(const struct v4l2_ioctl_ops *ops, 21928c2ecf20Sopenharmony_ci struct file *file, void *fh, void *arg) 21938c2ecf20Sopenharmony_ci{ 21948c2ecf20Sopenharmony_ci struct video_device *vfd = video_devdata(file); 21958c2ecf20Sopenharmony_ci struct v4l2_query_ext_ctrl *p = arg; 21968c2ecf20Sopenharmony_ci struct v4l2_fh *vfh = 21978c2ecf20Sopenharmony_ci test_bit(V4L2_FL_USES_V4L2_FH, &vfd->flags) ? fh : NULL; 21988c2ecf20Sopenharmony_ci 21998c2ecf20Sopenharmony_ci if (vfh && vfh->ctrl_handler) 22008c2ecf20Sopenharmony_ci return v4l2_query_ext_ctrl(vfh->ctrl_handler, p); 22018c2ecf20Sopenharmony_ci if (vfd->ctrl_handler) 22028c2ecf20Sopenharmony_ci return v4l2_query_ext_ctrl(vfd->ctrl_handler, p); 22038c2ecf20Sopenharmony_ci if (ops->vidioc_query_ext_ctrl) 22048c2ecf20Sopenharmony_ci return ops->vidioc_query_ext_ctrl(file, fh, p); 22058c2ecf20Sopenharmony_ci return -ENOTTY; 22068c2ecf20Sopenharmony_ci} 22078c2ecf20Sopenharmony_ci 22088c2ecf20Sopenharmony_cistatic int v4l_querymenu(const struct v4l2_ioctl_ops *ops, 22098c2ecf20Sopenharmony_ci struct file *file, void *fh, void *arg) 22108c2ecf20Sopenharmony_ci{ 22118c2ecf20Sopenharmony_ci struct video_device *vfd = video_devdata(file); 22128c2ecf20Sopenharmony_ci struct v4l2_querymenu *p = arg; 22138c2ecf20Sopenharmony_ci struct v4l2_fh *vfh = 22148c2ecf20Sopenharmony_ci test_bit(V4L2_FL_USES_V4L2_FH, &vfd->flags) ? fh : NULL; 22158c2ecf20Sopenharmony_ci 22168c2ecf20Sopenharmony_ci if (vfh && vfh->ctrl_handler) 22178c2ecf20Sopenharmony_ci return v4l2_querymenu(vfh->ctrl_handler, p); 22188c2ecf20Sopenharmony_ci if (vfd->ctrl_handler) 22198c2ecf20Sopenharmony_ci return v4l2_querymenu(vfd->ctrl_handler, p); 22208c2ecf20Sopenharmony_ci if (ops->vidioc_querymenu) 22218c2ecf20Sopenharmony_ci return ops->vidioc_querymenu(file, fh, p); 22228c2ecf20Sopenharmony_ci return -ENOTTY; 22238c2ecf20Sopenharmony_ci} 22248c2ecf20Sopenharmony_ci 22258c2ecf20Sopenharmony_cistatic int v4l_g_ctrl(const struct v4l2_ioctl_ops *ops, 22268c2ecf20Sopenharmony_ci struct file *file, void *fh, void *arg) 22278c2ecf20Sopenharmony_ci{ 22288c2ecf20Sopenharmony_ci struct video_device *vfd = video_devdata(file); 22298c2ecf20Sopenharmony_ci struct v4l2_control *p = arg; 22308c2ecf20Sopenharmony_ci struct v4l2_fh *vfh = 22318c2ecf20Sopenharmony_ci test_bit(V4L2_FL_USES_V4L2_FH, &vfd->flags) ? fh : NULL; 22328c2ecf20Sopenharmony_ci struct v4l2_ext_controls ctrls; 22338c2ecf20Sopenharmony_ci struct v4l2_ext_control ctrl; 22348c2ecf20Sopenharmony_ci 22358c2ecf20Sopenharmony_ci if (vfh && vfh->ctrl_handler) 22368c2ecf20Sopenharmony_ci return v4l2_g_ctrl(vfh->ctrl_handler, p); 22378c2ecf20Sopenharmony_ci if (vfd->ctrl_handler) 22388c2ecf20Sopenharmony_ci return v4l2_g_ctrl(vfd->ctrl_handler, p); 22398c2ecf20Sopenharmony_ci if (ops->vidioc_g_ctrl) 22408c2ecf20Sopenharmony_ci return ops->vidioc_g_ctrl(file, fh, p); 22418c2ecf20Sopenharmony_ci if (ops->vidioc_g_ext_ctrls == NULL) 22428c2ecf20Sopenharmony_ci return -ENOTTY; 22438c2ecf20Sopenharmony_ci 22448c2ecf20Sopenharmony_ci ctrls.which = V4L2_CTRL_ID2WHICH(p->id); 22458c2ecf20Sopenharmony_ci ctrls.count = 1; 22468c2ecf20Sopenharmony_ci ctrls.controls = &ctrl; 22478c2ecf20Sopenharmony_ci ctrl.id = p->id; 22488c2ecf20Sopenharmony_ci ctrl.value = p->value; 22498c2ecf20Sopenharmony_ci if (check_ext_ctrls(&ctrls, VIDIOC_G_CTRL)) { 22508c2ecf20Sopenharmony_ci int ret = ops->vidioc_g_ext_ctrls(file, fh, &ctrls); 22518c2ecf20Sopenharmony_ci 22528c2ecf20Sopenharmony_ci if (ret == 0) 22538c2ecf20Sopenharmony_ci p->value = ctrl.value; 22548c2ecf20Sopenharmony_ci return ret; 22558c2ecf20Sopenharmony_ci } 22568c2ecf20Sopenharmony_ci return -EINVAL; 22578c2ecf20Sopenharmony_ci} 22588c2ecf20Sopenharmony_ci 22598c2ecf20Sopenharmony_cistatic int v4l_s_ctrl(const struct v4l2_ioctl_ops *ops, 22608c2ecf20Sopenharmony_ci struct file *file, void *fh, void *arg) 22618c2ecf20Sopenharmony_ci{ 22628c2ecf20Sopenharmony_ci struct video_device *vfd = video_devdata(file); 22638c2ecf20Sopenharmony_ci struct v4l2_control *p = arg; 22648c2ecf20Sopenharmony_ci struct v4l2_fh *vfh = 22658c2ecf20Sopenharmony_ci test_bit(V4L2_FL_USES_V4L2_FH, &vfd->flags) ? fh : NULL; 22668c2ecf20Sopenharmony_ci struct v4l2_ext_controls ctrls; 22678c2ecf20Sopenharmony_ci struct v4l2_ext_control ctrl; 22688c2ecf20Sopenharmony_ci int ret; 22698c2ecf20Sopenharmony_ci 22708c2ecf20Sopenharmony_ci if (vfh && vfh->ctrl_handler) 22718c2ecf20Sopenharmony_ci return v4l2_s_ctrl(vfh, vfh->ctrl_handler, p); 22728c2ecf20Sopenharmony_ci if (vfd->ctrl_handler) 22738c2ecf20Sopenharmony_ci return v4l2_s_ctrl(NULL, vfd->ctrl_handler, p); 22748c2ecf20Sopenharmony_ci if (ops->vidioc_s_ctrl) 22758c2ecf20Sopenharmony_ci return ops->vidioc_s_ctrl(file, fh, p); 22768c2ecf20Sopenharmony_ci if (ops->vidioc_s_ext_ctrls == NULL) 22778c2ecf20Sopenharmony_ci return -ENOTTY; 22788c2ecf20Sopenharmony_ci 22798c2ecf20Sopenharmony_ci ctrls.which = V4L2_CTRL_ID2WHICH(p->id); 22808c2ecf20Sopenharmony_ci ctrls.count = 1; 22818c2ecf20Sopenharmony_ci ctrls.controls = &ctrl; 22828c2ecf20Sopenharmony_ci ctrl.id = p->id; 22838c2ecf20Sopenharmony_ci ctrl.value = p->value; 22848c2ecf20Sopenharmony_ci if (!check_ext_ctrls(&ctrls, VIDIOC_S_CTRL)) 22858c2ecf20Sopenharmony_ci return -EINVAL; 22868c2ecf20Sopenharmony_ci ret = ops->vidioc_s_ext_ctrls(file, fh, &ctrls); 22878c2ecf20Sopenharmony_ci p->value = ctrl.value; 22888c2ecf20Sopenharmony_ci return ret; 22898c2ecf20Sopenharmony_ci} 22908c2ecf20Sopenharmony_ci 22918c2ecf20Sopenharmony_cistatic int v4l_g_ext_ctrls(const struct v4l2_ioctl_ops *ops, 22928c2ecf20Sopenharmony_ci struct file *file, void *fh, void *arg) 22938c2ecf20Sopenharmony_ci{ 22948c2ecf20Sopenharmony_ci struct video_device *vfd = video_devdata(file); 22958c2ecf20Sopenharmony_ci struct v4l2_ext_controls *p = arg; 22968c2ecf20Sopenharmony_ci struct v4l2_fh *vfh = 22978c2ecf20Sopenharmony_ci test_bit(V4L2_FL_USES_V4L2_FH, &vfd->flags) ? fh : NULL; 22988c2ecf20Sopenharmony_ci 22998c2ecf20Sopenharmony_ci p->error_idx = p->count; 23008c2ecf20Sopenharmony_ci if (vfh && vfh->ctrl_handler) 23018c2ecf20Sopenharmony_ci return v4l2_g_ext_ctrls(vfh->ctrl_handler, 23028c2ecf20Sopenharmony_ci vfd, vfd->v4l2_dev->mdev, p); 23038c2ecf20Sopenharmony_ci if (vfd->ctrl_handler) 23048c2ecf20Sopenharmony_ci return v4l2_g_ext_ctrls(vfd->ctrl_handler, 23058c2ecf20Sopenharmony_ci vfd, vfd->v4l2_dev->mdev, p); 23068c2ecf20Sopenharmony_ci if (ops->vidioc_g_ext_ctrls == NULL) 23078c2ecf20Sopenharmony_ci return -ENOTTY; 23088c2ecf20Sopenharmony_ci return check_ext_ctrls(p, VIDIOC_G_EXT_CTRLS) ? 23098c2ecf20Sopenharmony_ci ops->vidioc_g_ext_ctrls(file, fh, p) : -EINVAL; 23108c2ecf20Sopenharmony_ci} 23118c2ecf20Sopenharmony_ci 23128c2ecf20Sopenharmony_cistatic int v4l_s_ext_ctrls(const struct v4l2_ioctl_ops *ops, 23138c2ecf20Sopenharmony_ci struct file *file, void *fh, void *arg) 23148c2ecf20Sopenharmony_ci{ 23158c2ecf20Sopenharmony_ci struct video_device *vfd = video_devdata(file); 23168c2ecf20Sopenharmony_ci struct v4l2_ext_controls *p = arg; 23178c2ecf20Sopenharmony_ci struct v4l2_fh *vfh = 23188c2ecf20Sopenharmony_ci test_bit(V4L2_FL_USES_V4L2_FH, &vfd->flags) ? fh : NULL; 23198c2ecf20Sopenharmony_ci 23208c2ecf20Sopenharmony_ci p->error_idx = p->count; 23218c2ecf20Sopenharmony_ci if (vfh && vfh->ctrl_handler) 23228c2ecf20Sopenharmony_ci return v4l2_s_ext_ctrls(vfh, vfh->ctrl_handler, 23238c2ecf20Sopenharmony_ci vfd, vfd->v4l2_dev->mdev, p); 23248c2ecf20Sopenharmony_ci if (vfd->ctrl_handler) 23258c2ecf20Sopenharmony_ci return v4l2_s_ext_ctrls(NULL, vfd->ctrl_handler, 23268c2ecf20Sopenharmony_ci vfd, vfd->v4l2_dev->mdev, p); 23278c2ecf20Sopenharmony_ci if (ops->vidioc_s_ext_ctrls == NULL) 23288c2ecf20Sopenharmony_ci return -ENOTTY; 23298c2ecf20Sopenharmony_ci return check_ext_ctrls(p, VIDIOC_S_EXT_CTRLS) ? 23308c2ecf20Sopenharmony_ci ops->vidioc_s_ext_ctrls(file, fh, p) : -EINVAL; 23318c2ecf20Sopenharmony_ci} 23328c2ecf20Sopenharmony_ci 23338c2ecf20Sopenharmony_cistatic int v4l_try_ext_ctrls(const struct v4l2_ioctl_ops *ops, 23348c2ecf20Sopenharmony_ci struct file *file, void *fh, void *arg) 23358c2ecf20Sopenharmony_ci{ 23368c2ecf20Sopenharmony_ci struct video_device *vfd = video_devdata(file); 23378c2ecf20Sopenharmony_ci struct v4l2_ext_controls *p = arg; 23388c2ecf20Sopenharmony_ci struct v4l2_fh *vfh = 23398c2ecf20Sopenharmony_ci test_bit(V4L2_FL_USES_V4L2_FH, &vfd->flags) ? fh : NULL; 23408c2ecf20Sopenharmony_ci 23418c2ecf20Sopenharmony_ci p->error_idx = p->count; 23428c2ecf20Sopenharmony_ci if (vfh && vfh->ctrl_handler) 23438c2ecf20Sopenharmony_ci return v4l2_try_ext_ctrls(vfh->ctrl_handler, 23448c2ecf20Sopenharmony_ci vfd, vfd->v4l2_dev->mdev, p); 23458c2ecf20Sopenharmony_ci if (vfd->ctrl_handler) 23468c2ecf20Sopenharmony_ci return v4l2_try_ext_ctrls(vfd->ctrl_handler, 23478c2ecf20Sopenharmony_ci vfd, vfd->v4l2_dev->mdev, p); 23488c2ecf20Sopenharmony_ci if (ops->vidioc_try_ext_ctrls == NULL) 23498c2ecf20Sopenharmony_ci return -ENOTTY; 23508c2ecf20Sopenharmony_ci return check_ext_ctrls(p, VIDIOC_TRY_EXT_CTRLS) ? 23518c2ecf20Sopenharmony_ci ops->vidioc_try_ext_ctrls(file, fh, p) : -EINVAL; 23528c2ecf20Sopenharmony_ci} 23538c2ecf20Sopenharmony_ci 23548c2ecf20Sopenharmony_ci/* 23558c2ecf20Sopenharmony_ci * The selection API specified originally that the _MPLANE buffer types 23568c2ecf20Sopenharmony_ci * shouldn't be used. The reasons for this are lost in the mists of time 23578c2ecf20Sopenharmony_ci * (or just really crappy memories). Regardless, this is really annoying 23588c2ecf20Sopenharmony_ci * for userspace. So to keep things simple we map _MPLANE buffer types 23598c2ecf20Sopenharmony_ci * to their 'regular' counterparts before calling the driver. And we 23608c2ecf20Sopenharmony_ci * restore it afterwards. This way applications can use either buffer 23618c2ecf20Sopenharmony_ci * type and drivers don't need to check for both. 23628c2ecf20Sopenharmony_ci */ 23638c2ecf20Sopenharmony_cistatic int v4l_g_selection(const struct v4l2_ioctl_ops *ops, 23648c2ecf20Sopenharmony_ci struct file *file, void *fh, void *arg) 23658c2ecf20Sopenharmony_ci{ 23668c2ecf20Sopenharmony_ci struct v4l2_selection *p = arg; 23678c2ecf20Sopenharmony_ci u32 old_type = p->type; 23688c2ecf20Sopenharmony_ci int ret; 23698c2ecf20Sopenharmony_ci 23708c2ecf20Sopenharmony_ci if (p->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) 23718c2ecf20Sopenharmony_ci p->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 23728c2ecf20Sopenharmony_ci else if (p->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) 23738c2ecf20Sopenharmony_ci p->type = V4L2_BUF_TYPE_VIDEO_OUTPUT; 23748c2ecf20Sopenharmony_ci ret = ops->vidioc_g_selection(file, fh, p); 23758c2ecf20Sopenharmony_ci p->type = old_type; 23768c2ecf20Sopenharmony_ci return ret; 23778c2ecf20Sopenharmony_ci} 23788c2ecf20Sopenharmony_ci 23798c2ecf20Sopenharmony_cistatic int v4l_s_selection(const struct v4l2_ioctl_ops *ops, 23808c2ecf20Sopenharmony_ci struct file *file, void *fh, void *arg) 23818c2ecf20Sopenharmony_ci{ 23828c2ecf20Sopenharmony_ci struct v4l2_selection *p = arg; 23838c2ecf20Sopenharmony_ci u32 old_type = p->type; 23848c2ecf20Sopenharmony_ci int ret; 23858c2ecf20Sopenharmony_ci 23868c2ecf20Sopenharmony_ci if (p->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) 23878c2ecf20Sopenharmony_ci p->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 23888c2ecf20Sopenharmony_ci else if (p->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) 23898c2ecf20Sopenharmony_ci p->type = V4L2_BUF_TYPE_VIDEO_OUTPUT; 23908c2ecf20Sopenharmony_ci ret = ops->vidioc_s_selection(file, fh, p); 23918c2ecf20Sopenharmony_ci p->type = old_type; 23928c2ecf20Sopenharmony_ci return ret; 23938c2ecf20Sopenharmony_ci} 23948c2ecf20Sopenharmony_ci 23958c2ecf20Sopenharmony_cistatic int v4l_g_crop(const struct v4l2_ioctl_ops *ops, 23968c2ecf20Sopenharmony_ci struct file *file, void *fh, void *arg) 23978c2ecf20Sopenharmony_ci{ 23988c2ecf20Sopenharmony_ci struct video_device *vfd = video_devdata(file); 23998c2ecf20Sopenharmony_ci struct v4l2_crop *p = arg; 24008c2ecf20Sopenharmony_ci struct v4l2_selection s = { 24018c2ecf20Sopenharmony_ci .type = p->type, 24028c2ecf20Sopenharmony_ci }; 24038c2ecf20Sopenharmony_ci int ret; 24048c2ecf20Sopenharmony_ci 24058c2ecf20Sopenharmony_ci /* simulate capture crop using selection api */ 24068c2ecf20Sopenharmony_ci 24078c2ecf20Sopenharmony_ci /* crop means compose for output devices */ 24088c2ecf20Sopenharmony_ci if (V4L2_TYPE_IS_OUTPUT(p->type)) 24098c2ecf20Sopenharmony_ci s.target = V4L2_SEL_TGT_COMPOSE; 24108c2ecf20Sopenharmony_ci else 24118c2ecf20Sopenharmony_ci s.target = V4L2_SEL_TGT_CROP; 24128c2ecf20Sopenharmony_ci 24138c2ecf20Sopenharmony_ci if (test_bit(V4L2_FL_QUIRK_INVERTED_CROP, &vfd->flags)) 24148c2ecf20Sopenharmony_ci s.target = s.target == V4L2_SEL_TGT_COMPOSE ? 24158c2ecf20Sopenharmony_ci V4L2_SEL_TGT_CROP : V4L2_SEL_TGT_COMPOSE; 24168c2ecf20Sopenharmony_ci 24178c2ecf20Sopenharmony_ci ret = v4l_g_selection(ops, file, fh, &s); 24188c2ecf20Sopenharmony_ci 24198c2ecf20Sopenharmony_ci /* copying results to old structure on success */ 24208c2ecf20Sopenharmony_ci if (!ret) 24218c2ecf20Sopenharmony_ci p->c = s.r; 24228c2ecf20Sopenharmony_ci return ret; 24238c2ecf20Sopenharmony_ci} 24248c2ecf20Sopenharmony_ci 24258c2ecf20Sopenharmony_cistatic int v4l_s_crop(const struct v4l2_ioctl_ops *ops, 24268c2ecf20Sopenharmony_ci struct file *file, void *fh, void *arg) 24278c2ecf20Sopenharmony_ci{ 24288c2ecf20Sopenharmony_ci struct video_device *vfd = video_devdata(file); 24298c2ecf20Sopenharmony_ci struct v4l2_crop *p = arg; 24308c2ecf20Sopenharmony_ci struct v4l2_selection s = { 24318c2ecf20Sopenharmony_ci .type = p->type, 24328c2ecf20Sopenharmony_ci .r = p->c, 24338c2ecf20Sopenharmony_ci }; 24348c2ecf20Sopenharmony_ci 24358c2ecf20Sopenharmony_ci /* simulate capture crop using selection api */ 24368c2ecf20Sopenharmony_ci 24378c2ecf20Sopenharmony_ci /* crop means compose for output devices */ 24388c2ecf20Sopenharmony_ci if (V4L2_TYPE_IS_OUTPUT(p->type)) 24398c2ecf20Sopenharmony_ci s.target = V4L2_SEL_TGT_COMPOSE; 24408c2ecf20Sopenharmony_ci else 24418c2ecf20Sopenharmony_ci s.target = V4L2_SEL_TGT_CROP; 24428c2ecf20Sopenharmony_ci 24438c2ecf20Sopenharmony_ci if (test_bit(V4L2_FL_QUIRK_INVERTED_CROP, &vfd->flags)) 24448c2ecf20Sopenharmony_ci s.target = s.target == V4L2_SEL_TGT_COMPOSE ? 24458c2ecf20Sopenharmony_ci V4L2_SEL_TGT_CROP : V4L2_SEL_TGT_COMPOSE; 24468c2ecf20Sopenharmony_ci 24478c2ecf20Sopenharmony_ci return v4l_s_selection(ops, file, fh, &s); 24488c2ecf20Sopenharmony_ci} 24498c2ecf20Sopenharmony_ci 24508c2ecf20Sopenharmony_cistatic int v4l_cropcap(const struct v4l2_ioctl_ops *ops, 24518c2ecf20Sopenharmony_ci struct file *file, void *fh, void *arg) 24528c2ecf20Sopenharmony_ci{ 24538c2ecf20Sopenharmony_ci struct video_device *vfd = video_devdata(file); 24548c2ecf20Sopenharmony_ci struct v4l2_cropcap *p = arg; 24558c2ecf20Sopenharmony_ci struct v4l2_selection s = { .type = p->type }; 24568c2ecf20Sopenharmony_ci int ret = 0; 24578c2ecf20Sopenharmony_ci 24588c2ecf20Sopenharmony_ci /* setting trivial pixelaspect */ 24598c2ecf20Sopenharmony_ci p->pixelaspect.numerator = 1; 24608c2ecf20Sopenharmony_ci p->pixelaspect.denominator = 1; 24618c2ecf20Sopenharmony_ci 24628c2ecf20Sopenharmony_ci if (s.type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) 24638c2ecf20Sopenharmony_ci s.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 24648c2ecf20Sopenharmony_ci else if (s.type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) 24658c2ecf20Sopenharmony_ci s.type = V4L2_BUF_TYPE_VIDEO_OUTPUT; 24668c2ecf20Sopenharmony_ci 24678c2ecf20Sopenharmony_ci /* 24688c2ecf20Sopenharmony_ci * The determine_valid_ioctls() call already should ensure 24698c2ecf20Sopenharmony_ci * that this can never happen, but just in case... 24708c2ecf20Sopenharmony_ci */ 24718c2ecf20Sopenharmony_ci if (WARN_ON(!ops->vidioc_g_selection)) 24728c2ecf20Sopenharmony_ci return -ENOTTY; 24738c2ecf20Sopenharmony_ci 24748c2ecf20Sopenharmony_ci if (ops->vidioc_g_pixelaspect) 24758c2ecf20Sopenharmony_ci ret = ops->vidioc_g_pixelaspect(file, fh, s.type, 24768c2ecf20Sopenharmony_ci &p->pixelaspect); 24778c2ecf20Sopenharmony_ci 24788c2ecf20Sopenharmony_ci /* 24798c2ecf20Sopenharmony_ci * Ignore ENOTTY or ENOIOCTLCMD error returns, just use the 24808c2ecf20Sopenharmony_ci * square pixel aspect ratio in that case. 24818c2ecf20Sopenharmony_ci */ 24828c2ecf20Sopenharmony_ci if (ret && ret != -ENOTTY && ret != -ENOIOCTLCMD) 24838c2ecf20Sopenharmony_ci return ret; 24848c2ecf20Sopenharmony_ci 24858c2ecf20Sopenharmony_ci /* Use g_selection() to fill in the bounds and defrect rectangles */ 24868c2ecf20Sopenharmony_ci 24878c2ecf20Sopenharmony_ci /* obtaining bounds */ 24888c2ecf20Sopenharmony_ci if (V4L2_TYPE_IS_OUTPUT(p->type)) 24898c2ecf20Sopenharmony_ci s.target = V4L2_SEL_TGT_COMPOSE_BOUNDS; 24908c2ecf20Sopenharmony_ci else 24918c2ecf20Sopenharmony_ci s.target = V4L2_SEL_TGT_CROP_BOUNDS; 24928c2ecf20Sopenharmony_ci 24938c2ecf20Sopenharmony_ci if (test_bit(V4L2_FL_QUIRK_INVERTED_CROP, &vfd->flags)) 24948c2ecf20Sopenharmony_ci s.target = s.target == V4L2_SEL_TGT_COMPOSE_BOUNDS ? 24958c2ecf20Sopenharmony_ci V4L2_SEL_TGT_CROP_BOUNDS : V4L2_SEL_TGT_COMPOSE_BOUNDS; 24968c2ecf20Sopenharmony_ci 24978c2ecf20Sopenharmony_ci ret = v4l_g_selection(ops, file, fh, &s); 24988c2ecf20Sopenharmony_ci if (ret) 24998c2ecf20Sopenharmony_ci return ret; 25008c2ecf20Sopenharmony_ci p->bounds = s.r; 25018c2ecf20Sopenharmony_ci 25028c2ecf20Sopenharmony_ci /* obtaining defrect */ 25038c2ecf20Sopenharmony_ci if (s.target == V4L2_SEL_TGT_COMPOSE_BOUNDS) 25048c2ecf20Sopenharmony_ci s.target = V4L2_SEL_TGT_COMPOSE_DEFAULT; 25058c2ecf20Sopenharmony_ci else 25068c2ecf20Sopenharmony_ci s.target = V4L2_SEL_TGT_CROP_DEFAULT; 25078c2ecf20Sopenharmony_ci 25088c2ecf20Sopenharmony_ci ret = v4l_g_selection(ops, file, fh, &s); 25098c2ecf20Sopenharmony_ci if (ret) 25108c2ecf20Sopenharmony_ci return ret; 25118c2ecf20Sopenharmony_ci p->defrect = s.r; 25128c2ecf20Sopenharmony_ci 25138c2ecf20Sopenharmony_ci return 0; 25148c2ecf20Sopenharmony_ci} 25158c2ecf20Sopenharmony_ci 25168c2ecf20Sopenharmony_cistatic int v4l_log_status(const struct v4l2_ioctl_ops *ops, 25178c2ecf20Sopenharmony_ci struct file *file, void *fh, void *arg) 25188c2ecf20Sopenharmony_ci{ 25198c2ecf20Sopenharmony_ci struct video_device *vfd = video_devdata(file); 25208c2ecf20Sopenharmony_ci int ret; 25218c2ecf20Sopenharmony_ci 25228c2ecf20Sopenharmony_ci if (vfd->v4l2_dev) 25238c2ecf20Sopenharmony_ci pr_info("%s: ================= START STATUS =================\n", 25248c2ecf20Sopenharmony_ci vfd->v4l2_dev->name); 25258c2ecf20Sopenharmony_ci ret = ops->vidioc_log_status(file, fh); 25268c2ecf20Sopenharmony_ci if (vfd->v4l2_dev) 25278c2ecf20Sopenharmony_ci pr_info("%s: ================== END STATUS ==================\n", 25288c2ecf20Sopenharmony_ci vfd->v4l2_dev->name); 25298c2ecf20Sopenharmony_ci return ret; 25308c2ecf20Sopenharmony_ci} 25318c2ecf20Sopenharmony_ci 25328c2ecf20Sopenharmony_cistatic int v4l_dbg_g_register(const struct v4l2_ioctl_ops *ops, 25338c2ecf20Sopenharmony_ci struct file *file, void *fh, void *arg) 25348c2ecf20Sopenharmony_ci{ 25358c2ecf20Sopenharmony_ci#ifdef CONFIG_VIDEO_ADV_DEBUG 25368c2ecf20Sopenharmony_ci struct v4l2_dbg_register *p = arg; 25378c2ecf20Sopenharmony_ci struct video_device *vfd = video_devdata(file); 25388c2ecf20Sopenharmony_ci struct v4l2_subdev *sd; 25398c2ecf20Sopenharmony_ci int idx = 0; 25408c2ecf20Sopenharmony_ci 25418c2ecf20Sopenharmony_ci if (!capable(CAP_SYS_ADMIN)) 25428c2ecf20Sopenharmony_ci return -EPERM; 25438c2ecf20Sopenharmony_ci if (p->match.type == V4L2_CHIP_MATCH_SUBDEV) { 25448c2ecf20Sopenharmony_ci if (vfd->v4l2_dev == NULL) 25458c2ecf20Sopenharmony_ci return -EINVAL; 25468c2ecf20Sopenharmony_ci v4l2_device_for_each_subdev(sd, vfd->v4l2_dev) 25478c2ecf20Sopenharmony_ci if (p->match.addr == idx++) 25488c2ecf20Sopenharmony_ci return v4l2_subdev_call(sd, core, g_register, p); 25498c2ecf20Sopenharmony_ci return -EINVAL; 25508c2ecf20Sopenharmony_ci } 25518c2ecf20Sopenharmony_ci if (ops->vidioc_g_register && p->match.type == V4L2_CHIP_MATCH_BRIDGE && 25528c2ecf20Sopenharmony_ci (ops->vidioc_g_chip_info || p->match.addr == 0)) 25538c2ecf20Sopenharmony_ci return ops->vidioc_g_register(file, fh, p); 25548c2ecf20Sopenharmony_ci return -EINVAL; 25558c2ecf20Sopenharmony_ci#else 25568c2ecf20Sopenharmony_ci return -ENOTTY; 25578c2ecf20Sopenharmony_ci#endif 25588c2ecf20Sopenharmony_ci} 25598c2ecf20Sopenharmony_ci 25608c2ecf20Sopenharmony_cistatic int v4l_dbg_s_register(const struct v4l2_ioctl_ops *ops, 25618c2ecf20Sopenharmony_ci struct file *file, void *fh, void *arg) 25628c2ecf20Sopenharmony_ci{ 25638c2ecf20Sopenharmony_ci#ifdef CONFIG_VIDEO_ADV_DEBUG 25648c2ecf20Sopenharmony_ci const struct v4l2_dbg_register *p = arg; 25658c2ecf20Sopenharmony_ci struct video_device *vfd = video_devdata(file); 25668c2ecf20Sopenharmony_ci struct v4l2_subdev *sd; 25678c2ecf20Sopenharmony_ci int idx = 0; 25688c2ecf20Sopenharmony_ci 25698c2ecf20Sopenharmony_ci if (!capable(CAP_SYS_ADMIN)) 25708c2ecf20Sopenharmony_ci return -EPERM; 25718c2ecf20Sopenharmony_ci if (p->match.type == V4L2_CHIP_MATCH_SUBDEV) { 25728c2ecf20Sopenharmony_ci if (vfd->v4l2_dev == NULL) 25738c2ecf20Sopenharmony_ci return -EINVAL; 25748c2ecf20Sopenharmony_ci v4l2_device_for_each_subdev(sd, vfd->v4l2_dev) 25758c2ecf20Sopenharmony_ci if (p->match.addr == idx++) 25768c2ecf20Sopenharmony_ci return v4l2_subdev_call(sd, core, s_register, p); 25778c2ecf20Sopenharmony_ci return -EINVAL; 25788c2ecf20Sopenharmony_ci } 25798c2ecf20Sopenharmony_ci if (ops->vidioc_s_register && p->match.type == V4L2_CHIP_MATCH_BRIDGE && 25808c2ecf20Sopenharmony_ci (ops->vidioc_g_chip_info || p->match.addr == 0)) 25818c2ecf20Sopenharmony_ci return ops->vidioc_s_register(file, fh, p); 25828c2ecf20Sopenharmony_ci return -EINVAL; 25838c2ecf20Sopenharmony_ci#else 25848c2ecf20Sopenharmony_ci return -ENOTTY; 25858c2ecf20Sopenharmony_ci#endif 25868c2ecf20Sopenharmony_ci} 25878c2ecf20Sopenharmony_ci 25888c2ecf20Sopenharmony_cistatic int v4l_dbg_g_chip_info(const struct v4l2_ioctl_ops *ops, 25898c2ecf20Sopenharmony_ci struct file *file, void *fh, void *arg) 25908c2ecf20Sopenharmony_ci{ 25918c2ecf20Sopenharmony_ci#ifdef CONFIG_VIDEO_ADV_DEBUG 25928c2ecf20Sopenharmony_ci struct video_device *vfd = video_devdata(file); 25938c2ecf20Sopenharmony_ci struct v4l2_dbg_chip_info *p = arg; 25948c2ecf20Sopenharmony_ci struct v4l2_subdev *sd; 25958c2ecf20Sopenharmony_ci int idx = 0; 25968c2ecf20Sopenharmony_ci 25978c2ecf20Sopenharmony_ci switch (p->match.type) { 25988c2ecf20Sopenharmony_ci case V4L2_CHIP_MATCH_BRIDGE: 25998c2ecf20Sopenharmony_ci if (ops->vidioc_s_register) 26008c2ecf20Sopenharmony_ci p->flags |= V4L2_CHIP_FL_WRITABLE; 26018c2ecf20Sopenharmony_ci if (ops->vidioc_g_register) 26028c2ecf20Sopenharmony_ci p->flags |= V4L2_CHIP_FL_READABLE; 26038c2ecf20Sopenharmony_ci strscpy(p->name, vfd->v4l2_dev->name, sizeof(p->name)); 26048c2ecf20Sopenharmony_ci if (ops->vidioc_g_chip_info) 26058c2ecf20Sopenharmony_ci return ops->vidioc_g_chip_info(file, fh, arg); 26068c2ecf20Sopenharmony_ci if (p->match.addr) 26078c2ecf20Sopenharmony_ci return -EINVAL; 26088c2ecf20Sopenharmony_ci return 0; 26098c2ecf20Sopenharmony_ci 26108c2ecf20Sopenharmony_ci case V4L2_CHIP_MATCH_SUBDEV: 26118c2ecf20Sopenharmony_ci if (vfd->v4l2_dev == NULL) 26128c2ecf20Sopenharmony_ci break; 26138c2ecf20Sopenharmony_ci v4l2_device_for_each_subdev(sd, vfd->v4l2_dev) { 26148c2ecf20Sopenharmony_ci if (p->match.addr != idx++) 26158c2ecf20Sopenharmony_ci continue; 26168c2ecf20Sopenharmony_ci if (sd->ops->core && sd->ops->core->s_register) 26178c2ecf20Sopenharmony_ci p->flags |= V4L2_CHIP_FL_WRITABLE; 26188c2ecf20Sopenharmony_ci if (sd->ops->core && sd->ops->core->g_register) 26198c2ecf20Sopenharmony_ci p->flags |= V4L2_CHIP_FL_READABLE; 26208c2ecf20Sopenharmony_ci strscpy(p->name, sd->name, sizeof(p->name)); 26218c2ecf20Sopenharmony_ci return 0; 26228c2ecf20Sopenharmony_ci } 26238c2ecf20Sopenharmony_ci break; 26248c2ecf20Sopenharmony_ci } 26258c2ecf20Sopenharmony_ci return -EINVAL; 26268c2ecf20Sopenharmony_ci#else 26278c2ecf20Sopenharmony_ci return -ENOTTY; 26288c2ecf20Sopenharmony_ci#endif 26298c2ecf20Sopenharmony_ci} 26308c2ecf20Sopenharmony_ci 26318c2ecf20Sopenharmony_cistatic int v4l_dqevent(const struct v4l2_ioctl_ops *ops, 26328c2ecf20Sopenharmony_ci struct file *file, void *fh, void *arg) 26338c2ecf20Sopenharmony_ci{ 26348c2ecf20Sopenharmony_ci return v4l2_event_dequeue(fh, arg, file->f_flags & O_NONBLOCK); 26358c2ecf20Sopenharmony_ci} 26368c2ecf20Sopenharmony_ci 26378c2ecf20Sopenharmony_cistatic int v4l_subscribe_event(const struct v4l2_ioctl_ops *ops, 26388c2ecf20Sopenharmony_ci struct file *file, void *fh, void *arg) 26398c2ecf20Sopenharmony_ci{ 26408c2ecf20Sopenharmony_ci return ops->vidioc_subscribe_event(fh, arg); 26418c2ecf20Sopenharmony_ci} 26428c2ecf20Sopenharmony_ci 26438c2ecf20Sopenharmony_cistatic int v4l_unsubscribe_event(const struct v4l2_ioctl_ops *ops, 26448c2ecf20Sopenharmony_ci struct file *file, void *fh, void *arg) 26458c2ecf20Sopenharmony_ci{ 26468c2ecf20Sopenharmony_ci return ops->vidioc_unsubscribe_event(fh, arg); 26478c2ecf20Sopenharmony_ci} 26488c2ecf20Sopenharmony_ci 26498c2ecf20Sopenharmony_cistatic int v4l_g_sliced_vbi_cap(const struct v4l2_ioctl_ops *ops, 26508c2ecf20Sopenharmony_ci struct file *file, void *fh, void *arg) 26518c2ecf20Sopenharmony_ci{ 26528c2ecf20Sopenharmony_ci struct v4l2_sliced_vbi_cap *p = arg; 26538c2ecf20Sopenharmony_ci int ret = check_fmt(file, p->type); 26548c2ecf20Sopenharmony_ci 26558c2ecf20Sopenharmony_ci if (ret) 26568c2ecf20Sopenharmony_ci return ret; 26578c2ecf20Sopenharmony_ci 26588c2ecf20Sopenharmony_ci /* Clear up to type, everything after type is zeroed already */ 26598c2ecf20Sopenharmony_ci memset(p, 0, offsetof(struct v4l2_sliced_vbi_cap, type)); 26608c2ecf20Sopenharmony_ci 26618c2ecf20Sopenharmony_ci return ops->vidioc_g_sliced_vbi_cap(file, fh, p); 26628c2ecf20Sopenharmony_ci} 26638c2ecf20Sopenharmony_ci 26648c2ecf20Sopenharmony_cistatic int v4l_enum_freq_bands(const struct v4l2_ioctl_ops *ops, 26658c2ecf20Sopenharmony_ci struct file *file, void *fh, void *arg) 26668c2ecf20Sopenharmony_ci{ 26678c2ecf20Sopenharmony_ci struct video_device *vfd = video_devdata(file); 26688c2ecf20Sopenharmony_ci struct v4l2_frequency_band *p = arg; 26698c2ecf20Sopenharmony_ci enum v4l2_tuner_type type; 26708c2ecf20Sopenharmony_ci int err; 26718c2ecf20Sopenharmony_ci 26728c2ecf20Sopenharmony_ci if (vfd->vfl_type == VFL_TYPE_SDR) { 26738c2ecf20Sopenharmony_ci if (p->type != V4L2_TUNER_SDR && p->type != V4L2_TUNER_RF) 26748c2ecf20Sopenharmony_ci return -EINVAL; 26758c2ecf20Sopenharmony_ci type = p->type; 26768c2ecf20Sopenharmony_ci } else { 26778c2ecf20Sopenharmony_ci type = (vfd->vfl_type == VFL_TYPE_RADIO) ? 26788c2ecf20Sopenharmony_ci V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV; 26798c2ecf20Sopenharmony_ci if (type != p->type) 26808c2ecf20Sopenharmony_ci return -EINVAL; 26818c2ecf20Sopenharmony_ci } 26828c2ecf20Sopenharmony_ci if (ops->vidioc_enum_freq_bands) { 26838c2ecf20Sopenharmony_ci err = ops->vidioc_enum_freq_bands(file, fh, p); 26848c2ecf20Sopenharmony_ci if (err != -ENOTTY) 26858c2ecf20Sopenharmony_ci return err; 26868c2ecf20Sopenharmony_ci } 26878c2ecf20Sopenharmony_ci if (is_valid_ioctl(vfd, VIDIOC_G_TUNER)) { 26888c2ecf20Sopenharmony_ci struct v4l2_tuner t = { 26898c2ecf20Sopenharmony_ci .index = p->tuner, 26908c2ecf20Sopenharmony_ci .type = type, 26918c2ecf20Sopenharmony_ci }; 26928c2ecf20Sopenharmony_ci 26938c2ecf20Sopenharmony_ci if (p->index) 26948c2ecf20Sopenharmony_ci return -EINVAL; 26958c2ecf20Sopenharmony_ci err = ops->vidioc_g_tuner(file, fh, &t); 26968c2ecf20Sopenharmony_ci if (err) 26978c2ecf20Sopenharmony_ci return err; 26988c2ecf20Sopenharmony_ci p->capability = t.capability | V4L2_TUNER_CAP_FREQ_BANDS; 26998c2ecf20Sopenharmony_ci p->rangelow = t.rangelow; 27008c2ecf20Sopenharmony_ci p->rangehigh = t.rangehigh; 27018c2ecf20Sopenharmony_ci p->modulation = (type == V4L2_TUNER_RADIO) ? 27028c2ecf20Sopenharmony_ci V4L2_BAND_MODULATION_FM : V4L2_BAND_MODULATION_VSB; 27038c2ecf20Sopenharmony_ci return 0; 27048c2ecf20Sopenharmony_ci } 27058c2ecf20Sopenharmony_ci if (is_valid_ioctl(vfd, VIDIOC_G_MODULATOR)) { 27068c2ecf20Sopenharmony_ci struct v4l2_modulator m = { 27078c2ecf20Sopenharmony_ci .index = p->tuner, 27088c2ecf20Sopenharmony_ci }; 27098c2ecf20Sopenharmony_ci 27108c2ecf20Sopenharmony_ci if (type != V4L2_TUNER_RADIO) 27118c2ecf20Sopenharmony_ci return -EINVAL; 27128c2ecf20Sopenharmony_ci if (p->index) 27138c2ecf20Sopenharmony_ci return -EINVAL; 27148c2ecf20Sopenharmony_ci err = ops->vidioc_g_modulator(file, fh, &m); 27158c2ecf20Sopenharmony_ci if (err) 27168c2ecf20Sopenharmony_ci return err; 27178c2ecf20Sopenharmony_ci p->capability = m.capability | V4L2_TUNER_CAP_FREQ_BANDS; 27188c2ecf20Sopenharmony_ci p->rangelow = m.rangelow; 27198c2ecf20Sopenharmony_ci p->rangehigh = m.rangehigh; 27208c2ecf20Sopenharmony_ci p->modulation = (type == V4L2_TUNER_RADIO) ? 27218c2ecf20Sopenharmony_ci V4L2_BAND_MODULATION_FM : V4L2_BAND_MODULATION_VSB; 27228c2ecf20Sopenharmony_ci return 0; 27238c2ecf20Sopenharmony_ci } 27248c2ecf20Sopenharmony_ci return -ENOTTY; 27258c2ecf20Sopenharmony_ci} 27268c2ecf20Sopenharmony_ci 27278c2ecf20Sopenharmony_cistruct v4l2_ioctl_info { 27288c2ecf20Sopenharmony_ci unsigned int ioctl; 27298c2ecf20Sopenharmony_ci u32 flags; 27308c2ecf20Sopenharmony_ci const char * const name; 27318c2ecf20Sopenharmony_ci int (*func)(const struct v4l2_ioctl_ops *ops, struct file *file, 27328c2ecf20Sopenharmony_ci void *fh, void *p); 27338c2ecf20Sopenharmony_ci void (*debug)(const void *arg, bool write_only); 27348c2ecf20Sopenharmony_ci}; 27358c2ecf20Sopenharmony_ci 27368c2ecf20Sopenharmony_ci/* This control needs a priority check */ 27378c2ecf20Sopenharmony_ci#define INFO_FL_PRIO (1 << 0) 27388c2ecf20Sopenharmony_ci/* This control can be valid if the filehandle passes a control handler. */ 27398c2ecf20Sopenharmony_ci#define INFO_FL_CTRL (1 << 1) 27408c2ecf20Sopenharmony_ci/* Queuing ioctl */ 27418c2ecf20Sopenharmony_ci#define INFO_FL_QUEUE (1 << 2) 27428c2ecf20Sopenharmony_ci/* Always copy back result, even on error */ 27438c2ecf20Sopenharmony_ci#define INFO_FL_ALWAYS_COPY (1 << 3) 27448c2ecf20Sopenharmony_ci/* Zero struct from after the field to the end */ 27458c2ecf20Sopenharmony_ci#define INFO_FL_CLEAR(v4l2_struct, field) \ 27468c2ecf20Sopenharmony_ci ((offsetof(struct v4l2_struct, field) + \ 27478c2ecf20Sopenharmony_ci sizeof_field(struct v4l2_struct, field)) << 16) 27488c2ecf20Sopenharmony_ci#define INFO_FL_CLEAR_MASK (_IOC_SIZEMASK << 16) 27498c2ecf20Sopenharmony_ci 27508c2ecf20Sopenharmony_ci#define DEFINE_V4L_STUB_FUNC(_vidioc) \ 27518c2ecf20Sopenharmony_ci static int v4l_stub_ ## _vidioc( \ 27528c2ecf20Sopenharmony_ci const struct v4l2_ioctl_ops *ops, \ 27538c2ecf20Sopenharmony_ci struct file *file, void *fh, void *p) \ 27548c2ecf20Sopenharmony_ci { \ 27558c2ecf20Sopenharmony_ci return ops->vidioc_ ## _vidioc(file, fh, p); \ 27568c2ecf20Sopenharmony_ci } 27578c2ecf20Sopenharmony_ci 27588c2ecf20Sopenharmony_ci#define IOCTL_INFO(_ioctl, _func, _debug, _flags) \ 27598c2ecf20Sopenharmony_ci [_IOC_NR(_ioctl)] = { \ 27608c2ecf20Sopenharmony_ci .ioctl = _ioctl, \ 27618c2ecf20Sopenharmony_ci .flags = _flags, \ 27628c2ecf20Sopenharmony_ci .name = #_ioctl, \ 27638c2ecf20Sopenharmony_ci .func = _func, \ 27648c2ecf20Sopenharmony_ci .debug = _debug, \ 27658c2ecf20Sopenharmony_ci } 27668c2ecf20Sopenharmony_ci 27678c2ecf20Sopenharmony_ciDEFINE_V4L_STUB_FUNC(g_fbuf) 27688c2ecf20Sopenharmony_ciDEFINE_V4L_STUB_FUNC(s_fbuf) 27698c2ecf20Sopenharmony_ciDEFINE_V4L_STUB_FUNC(expbuf) 27708c2ecf20Sopenharmony_ciDEFINE_V4L_STUB_FUNC(g_std) 27718c2ecf20Sopenharmony_ciDEFINE_V4L_STUB_FUNC(g_audio) 27728c2ecf20Sopenharmony_ciDEFINE_V4L_STUB_FUNC(s_audio) 27738c2ecf20Sopenharmony_ciDEFINE_V4L_STUB_FUNC(g_edid) 27748c2ecf20Sopenharmony_ciDEFINE_V4L_STUB_FUNC(s_edid) 27758c2ecf20Sopenharmony_ciDEFINE_V4L_STUB_FUNC(g_audout) 27768c2ecf20Sopenharmony_ciDEFINE_V4L_STUB_FUNC(s_audout) 27778c2ecf20Sopenharmony_ciDEFINE_V4L_STUB_FUNC(g_jpegcomp) 27788c2ecf20Sopenharmony_ciDEFINE_V4L_STUB_FUNC(s_jpegcomp) 27798c2ecf20Sopenharmony_ciDEFINE_V4L_STUB_FUNC(enumaudio) 27808c2ecf20Sopenharmony_ciDEFINE_V4L_STUB_FUNC(enumaudout) 27818c2ecf20Sopenharmony_ciDEFINE_V4L_STUB_FUNC(enum_framesizes) 27828c2ecf20Sopenharmony_ciDEFINE_V4L_STUB_FUNC(enum_frameintervals) 27838c2ecf20Sopenharmony_ciDEFINE_V4L_STUB_FUNC(g_enc_index) 27848c2ecf20Sopenharmony_ciDEFINE_V4L_STUB_FUNC(encoder_cmd) 27858c2ecf20Sopenharmony_ciDEFINE_V4L_STUB_FUNC(try_encoder_cmd) 27868c2ecf20Sopenharmony_ciDEFINE_V4L_STUB_FUNC(decoder_cmd) 27878c2ecf20Sopenharmony_ciDEFINE_V4L_STUB_FUNC(try_decoder_cmd) 27888c2ecf20Sopenharmony_ciDEFINE_V4L_STUB_FUNC(s_dv_timings) 27898c2ecf20Sopenharmony_ciDEFINE_V4L_STUB_FUNC(g_dv_timings) 27908c2ecf20Sopenharmony_ciDEFINE_V4L_STUB_FUNC(enum_dv_timings) 27918c2ecf20Sopenharmony_ciDEFINE_V4L_STUB_FUNC(query_dv_timings) 27928c2ecf20Sopenharmony_ciDEFINE_V4L_STUB_FUNC(dv_timings_cap) 27938c2ecf20Sopenharmony_ci 27948c2ecf20Sopenharmony_cistatic const struct v4l2_ioctl_info v4l2_ioctls[] = { 27958c2ecf20Sopenharmony_ci IOCTL_INFO(VIDIOC_QUERYCAP, v4l_querycap, v4l_print_querycap, 0), 27968c2ecf20Sopenharmony_ci IOCTL_INFO(VIDIOC_ENUM_FMT, v4l_enum_fmt, v4l_print_fmtdesc, 0), 27978c2ecf20Sopenharmony_ci IOCTL_INFO(VIDIOC_G_FMT, v4l_g_fmt, v4l_print_format, 0), 27988c2ecf20Sopenharmony_ci IOCTL_INFO(VIDIOC_S_FMT, v4l_s_fmt, v4l_print_format, INFO_FL_PRIO), 27998c2ecf20Sopenharmony_ci IOCTL_INFO(VIDIOC_REQBUFS, v4l_reqbufs, v4l_print_requestbuffers, INFO_FL_PRIO | INFO_FL_QUEUE), 28008c2ecf20Sopenharmony_ci IOCTL_INFO(VIDIOC_QUERYBUF, v4l_querybuf, v4l_print_buffer, INFO_FL_QUEUE | INFO_FL_CLEAR(v4l2_buffer, length)), 28018c2ecf20Sopenharmony_ci IOCTL_INFO(VIDIOC_G_FBUF, v4l_stub_g_fbuf, v4l_print_framebuffer, 0), 28028c2ecf20Sopenharmony_ci IOCTL_INFO(VIDIOC_S_FBUF, v4l_stub_s_fbuf, v4l_print_framebuffer, INFO_FL_PRIO), 28038c2ecf20Sopenharmony_ci IOCTL_INFO(VIDIOC_OVERLAY, v4l_overlay, v4l_print_u32, INFO_FL_PRIO), 28048c2ecf20Sopenharmony_ci IOCTL_INFO(VIDIOC_QBUF, v4l_qbuf, v4l_print_buffer, INFO_FL_QUEUE), 28058c2ecf20Sopenharmony_ci IOCTL_INFO(VIDIOC_EXPBUF, v4l_stub_expbuf, v4l_print_exportbuffer, INFO_FL_QUEUE | INFO_FL_CLEAR(v4l2_exportbuffer, flags)), 28068c2ecf20Sopenharmony_ci IOCTL_INFO(VIDIOC_DQBUF, v4l_dqbuf, v4l_print_buffer, INFO_FL_QUEUE), 28078c2ecf20Sopenharmony_ci IOCTL_INFO(VIDIOC_STREAMON, v4l_streamon, v4l_print_buftype, INFO_FL_PRIO | INFO_FL_QUEUE), 28088c2ecf20Sopenharmony_ci IOCTL_INFO(VIDIOC_STREAMOFF, v4l_streamoff, v4l_print_buftype, INFO_FL_PRIO | INFO_FL_QUEUE), 28098c2ecf20Sopenharmony_ci IOCTL_INFO(VIDIOC_G_PARM, v4l_g_parm, v4l_print_streamparm, INFO_FL_CLEAR(v4l2_streamparm, type)), 28108c2ecf20Sopenharmony_ci IOCTL_INFO(VIDIOC_S_PARM, v4l_s_parm, v4l_print_streamparm, INFO_FL_PRIO), 28118c2ecf20Sopenharmony_ci IOCTL_INFO(VIDIOC_G_STD, v4l_stub_g_std, v4l_print_std, 0), 28128c2ecf20Sopenharmony_ci IOCTL_INFO(VIDIOC_S_STD, v4l_s_std, v4l_print_std, INFO_FL_PRIO), 28138c2ecf20Sopenharmony_ci IOCTL_INFO(VIDIOC_ENUMSTD, v4l_enumstd, v4l_print_standard, INFO_FL_CLEAR(v4l2_standard, index)), 28148c2ecf20Sopenharmony_ci IOCTL_INFO(VIDIOC_ENUMINPUT, v4l_enuminput, v4l_print_enuminput, INFO_FL_CLEAR(v4l2_input, index)), 28158c2ecf20Sopenharmony_ci IOCTL_INFO(VIDIOC_G_CTRL, v4l_g_ctrl, v4l_print_control, INFO_FL_CTRL | INFO_FL_CLEAR(v4l2_control, id)), 28168c2ecf20Sopenharmony_ci IOCTL_INFO(VIDIOC_S_CTRL, v4l_s_ctrl, v4l_print_control, INFO_FL_PRIO | INFO_FL_CTRL), 28178c2ecf20Sopenharmony_ci IOCTL_INFO(VIDIOC_G_TUNER, v4l_g_tuner, v4l_print_tuner, INFO_FL_CLEAR(v4l2_tuner, index)), 28188c2ecf20Sopenharmony_ci IOCTL_INFO(VIDIOC_S_TUNER, v4l_s_tuner, v4l_print_tuner, INFO_FL_PRIO), 28198c2ecf20Sopenharmony_ci IOCTL_INFO(VIDIOC_G_AUDIO, v4l_stub_g_audio, v4l_print_audio, 0), 28208c2ecf20Sopenharmony_ci IOCTL_INFO(VIDIOC_S_AUDIO, v4l_stub_s_audio, v4l_print_audio, INFO_FL_PRIO), 28218c2ecf20Sopenharmony_ci IOCTL_INFO(VIDIOC_QUERYCTRL, v4l_queryctrl, v4l_print_queryctrl, INFO_FL_CTRL | INFO_FL_CLEAR(v4l2_queryctrl, id)), 28228c2ecf20Sopenharmony_ci IOCTL_INFO(VIDIOC_QUERYMENU, v4l_querymenu, v4l_print_querymenu, INFO_FL_CTRL | INFO_FL_CLEAR(v4l2_querymenu, index)), 28238c2ecf20Sopenharmony_ci IOCTL_INFO(VIDIOC_G_INPUT, v4l_g_input, v4l_print_u32, 0), 28248c2ecf20Sopenharmony_ci IOCTL_INFO(VIDIOC_S_INPUT, v4l_s_input, v4l_print_u32, INFO_FL_PRIO), 28258c2ecf20Sopenharmony_ci IOCTL_INFO(VIDIOC_G_EDID, v4l_stub_g_edid, v4l_print_edid, INFO_FL_ALWAYS_COPY), 28268c2ecf20Sopenharmony_ci IOCTL_INFO(VIDIOC_S_EDID, v4l_stub_s_edid, v4l_print_edid, INFO_FL_PRIO | INFO_FL_ALWAYS_COPY), 28278c2ecf20Sopenharmony_ci IOCTL_INFO(VIDIOC_G_OUTPUT, v4l_g_output, v4l_print_u32, 0), 28288c2ecf20Sopenharmony_ci IOCTL_INFO(VIDIOC_S_OUTPUT, v4l_s_output, v4l_print_u32, INFO_FL_PRIO), 28298c2ecf20Sopenharmony_ci IOCTL_INFO(VIDIOC_ENUMOUTPUT, v4l_enumoutput, v4l_print_enumoutput, INFO_FL_CLEAR(v4l2_output, index)), 28308c2ecf20Sopenharmony_ci IOCTL_INFO(VIDIOC_G_AUDOUT, v4l_stub_g_audout, v4l_print_audioout, 0), 28318c2ecf20Sopenharmony_ci IOCTL_INFO(VIDIOC_S_AUDOUT, v4l_stub_s_audout, v4l_print_audioout, INFO_FL_PRIO), 28328c2ecf20Sopenharmony_ci IOCTL_INFO(VIDIOC_G_MODULATOR, v4l_g_modulator, v4l_print_modulator, INFO_FL_CLEAR(v4l2_modulator, index)), 28338c2ecf20Sopenharmony_ci IOCTL_INFO(VIDIOC_S_MODULATOR, v4l_s_modulator, v4l_print_modulator, INFO_FL_PRIO), 28348c2ecf20Sopenharmony_ci IOCTL_INFO(VIDIOC_G_FREQUENCY, v4l_g_frequency, v4l_print_frequency, INFO_FL_CLEAR(v4l2_frequency, tuner)), 28358c2ecf20Sopenharmony_ci IOCTL_INFO(VIDIOC_S_FREQUENCY, v4l_s_frequency, v4l_print_frequency, INFO_FL_PRIO), 28368c2ecf20Sopenharmony_ci IOCTL_INFO(VIDIOC_CROPCAP, v4l_cropcap, v4l_print_cropcap, INFO_FL_CLEAR(v4l2_cropcap, type)), 28378c2ecf20Sopenharmony_ci IOCTL_INFO(VIDIOC_G_CROP, v4l_g_crop, v4l_print_crop, INFO_FL_CLEAR(v4l2_crop, type)), 28388c2ecf20Sopenharmony_ci IOCTL_INFO(VIDIOC_S_CROP, v4l_s_crop, v4l_print_crop, INFO_FL_PRIO), 28398c2ecf20Sopenharmony_ci IOCTL_INFO(VIDIOC_G_SELECTION, v4l_g_selection, v4l_print_selection, INFO_FL_CLEAR(v4l2_selection, r)), 28408c2ecf20Sopenharmony_ci IOCTL_INFO(VIDIOC_S_SELECTION, v4l_s_selection, v4l_print_selection, INFO_FL_PRIO | INFO_FL_CLEAR(v4l2_selection, r)), 28418c2ecf20Sopenharmony_ci IOCTL_INFO(VIDIOC_G_JPEGCOMP, v4l_stub_g_jpegcomp, v4l_print_jpegcompression, 0), 28428c2ecf20Sopenharmony_ci IOCTL_INFO(VIDIOC_S_JPEGCOMP, v4l_stub_s_jpegcomp, v4l_print_jpegcompression, INFO_FL_PRIO), 28438c2ecf20Sopenharmony_ci IOCTL_INFO(VIDIOC_QUERYSTD, v4l_querystd, v4l_print_std, 0), 28448c2ecf20Sopenharmony_ci IOCTL_INFO(VIDIOC_TRY_FMT, v4l_try_fmt, v4l_print_format, 0), 28458c2ecf20Sopenharmony_ci IOCTL_INFO(VIDIOC_ENUMAUDIO, v4l_stub_enumaudio, v4l_print_audio, INFO_FL_CLEAR(v4l2_audio, index)), 28468c2ecf20Sopenharmony_ci IOCTL_INFO(VIDIOC_ENUMAUDOUT, v4l_stub_enumaudout, v4l_print_audioout, INFO_FL_CLEAR(v4l2_audioout, index)), 28478c2ecf20Sopenharmony_ci IOCTL_INFO(VIDIOC_G_PRIORITY, v4l_g_priority, v4l_print_u32, 0), 28488c2ecf20Sopenharmony_ci IOCTL_INFO(VIDIOC_S_PRIORITY, v4l_s_priority, v4l_print_u32, INFO_FL_PRIO), 28498c2ecf20Sopenharmony_ci 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)), 28508c2ecf20Sopenharmony_ci IOCTL_INFO(VIDIOC_LOG_STATUS, v4l_log_status, v4l_print_newline, 0), 28518c2ecf20Sopenharmony_ci IOCTL_INFO(VIDIOC_G_EXT_CTRLS, v4l_g_ext_ctrls, v4l_print_ext_controls, INFO_FL_CTRL), 28528c2ecf20Sopenharmony_ci IOCTL_INFO(VIDIOC_S_EXT_CTRLS, v4l_s_ext_ctrls, v4l_print_ext_controls, INFO_FL_PRIO | INFO_FL_CTRL), 28538c2ecf20Sopenharmony_ci IOCTL_INFO(VIDIOC_TRY_EXT_CTRLS, v4l_try_ext_ctrls, v4l_print_ext_controls, INFO_FL_CTRL), 28548c2ecf20Sopenharmony_ci IOCTL_INFO(VIDIOC_ENUM_FRAMESIZES, v4l_stub_enum_framesizes, v4l_print_frmsizeenum, INFO_FL_CLEAR(v4l2_frmsizeenum, pixel_format)), 28558c2ecf20Sopenharmony_ci IOCTL_INFO(VIDIOC_ENUM_FRAMEINTERVALS, v4l_stub_enum_frameintervals, v4l_print_frmivalenum, INFO_FL_CLEAR(v4l2_frmivalenum, height)), 28568c2ecf20Sopenharmony_ci IOCTL_INFO(VIDIOC_G_ENC_INDEX, v4l_stub_g_enc_index, v4l_print_enc_idx, 0), 28578c2ecf20Sopenharmony_ci IOCTL_INFO(VIDIOC_ENCODER_CMD, v4l_stub_encoder_cmd, v4l_print_encoder_cmd, INFO_FL_PRIO | INFO_FL_CLEAR(v4l2_encoder_cmd, flags)), 28588c2ecf20Sopenharmony_ci IOCTL_INFO(VIDIOC_TRY_ENCODER_CMD, v4l_stub_try_encoder_cmd, v4l_print_encoder_cmd, INFO_FL_CLEAR(v4l2_encoder_cmd, flags)), 28598c2ecf20Sopenharmony_ci IOCTL_INFO(VIDIOC_DECODER_CMD, v4l_stub_decoder_cmd, v4l_print_decoder_cmd, INFO_FL_PRIO), 28608c2ecf20Sopenharmony_ci IOCTL_INFO(VIDIOC_TRY_DECODER_CMD, v4l_stub_try_decoder_cmd, v4l_print_decoder_cmd, 0), 28618c2ecf20Sopenharmony_ci IOCTL_INFO(VIDIOC_DBG_S_REGISTER, v4l_dbg_s_register, v4l_print_dbg_register, 0), 28628c2ecf20Sopenharmony_ci IOCTL_INFO(VIDIOC_DBG_G_REGISTER, v4l_dbg_g_register, v4l_print_dbg_register, 0), 28638c2ecf20Sopenharmony_ci IOCTL_INFO(VIDIOC_S_HW_FREQ_SEEK, v4l_s_hw_freq_seek, v4l_print_hw_freq_seek, INFO_FL_PRIO), 28648c2ecf20Sopenharmony_ci 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)), 28658c2ecf20Sopenharmony_ci IOCTL_INFO(VIDIOC_G_DV_TIMINGS, v4l_stub_g_dv_timings, v4l_print_dv_timings, 0), 28668c2ecf20Sopenharmony_ci IOCTL_INFO(VIDIOC_DQEVENT, v4l_dqevent, v4l_print_event, 0), 28678c2ecf20Sopenharmony_ci IOCTL_INFO(VIDIOC_SUBSCRIBE_EVENT, v4l_subscribe_event, v4l_print_event_subscription, 0), 28688c2ecf20Sopenharmony_ci IOCTL_INFO(VIDIOC_UNSUBSCRIBE_EVENT, v4l_unsubscribe_event, v4l_print_event_subscription, 0), 28698c2ecf20Sopenharmony_ci IOCTL_INFO(VIDIOC_CREATE_BUFS, v4l_create_bufs, v4l_print_create_buffers, INFO_FL_PRIO | INFO_FL_QUEUE), 28708c2ecf20Sopenharmony_ci IOCTL_INFO(VIDIOC_PREPARE_BUF, v4l_prepare_buf, v4l_print_buffer, INFO_FL_QUEUE), 28718c2ecf20Sopenharmony_ci IOCTL_INFO(VIDIOC_ENUM_DV_TIMINGS, v4l_stub_enum_dv_timings, v4l_print_enum_dv_timings, INFO_FL_CLEAR(v4l2_enum_dv_timings, pad)), 28728c2ecf20Sopenharmony_ci IOCTL_INFO(VIDIOC_QUERY_DV_TIMINGS, v4l_stub_query_dv_timings, v4l_print_dv_timings, INFO_FL_ALWAYS_COPY), 28738c2ecf20Sopenharmony_ci IOCTL_INFO(VIDIOC_DV_TIMINGS_CAP, v4l_stub_dv_timings_cap, v4l_print_dv_timings_cap, INFO_FL_CLEAR(v4l2_dv_timings_cap, pad)), 28748c2ecf20Sopenharmony_ci IOCTL_INFO(VIDIOC_ENUM_FREQ_BANDS, v4l_enum_freq_bands, v4l_print_freq_band, 0), 28758c2ecf20Sopenharmony_ci 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)), 28768c2ecf20Sopenharmony_ci 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)), 28778c2ecf20Sopenharmony_ci}; 28788c2ecf20Sopenharmony_ci#define V4L2_IOCTLS ARRAY_SIZE(v4l2_ioctls) 28798c2ecf20Sopenharmony_ci 28808c2ecf20Sopenharmony_cistatic bool v4l2_is_known_ioctl(unsigned int cmd) 28818c2ecf20Sopenharmony_ci{ 28828c2ecf20Sopenharmony_ci if (_IOC_NR(cmd) >= V4L2_IOCTLS) 28838c2ecf20Sopenharmony_ci return false; 28848c2ecf20Sopenharmony_ci return v4l2_ioctls[_IOC_NR(cmd)].ioctl == cmd; 28858c2ecf20Sopenharmony_ci} 28868c2ecf20Sopenharmony_ci 28878c2ecf20Sopenharmony_cistatic struct mutex *v4l2_ioctl_get_lock(struct video_device *vdev, 28888c2ecf20Sopenharmony_ci struct v4l2_fh *vfh, unsigned int cmd, 28898c2ecf20Sopenharmony_ci void *arg) 28908c2ecf20Sopenharmony_ci{ 28918c2ecf20Sopenharmony_ci if (_IOC_NR(cmd) >= V4L2_IOCTLS) 28928c2ecf20Sopenharmony_ci return vdev->lock; 28938c2ecf20Sopenharmony_ci if (vfh && vfh->m2m_ctx && 28948c2ecf20Sopenharmony_ci (v4l2_ioctls[_IOC_NR(cmd)].flags & INFO_FL_QUEUE)) { 28958c2ecf20Sopenharmony_ci if (vfh->m2m_ctx->q_lock) 28968c2ecf20Sopenharmony_ci return vfh->m2m_ctx->q_lock; 28978c2ecf20Sopenharmony_ci } 28988c2ecf20Sopenharmony_ci if (vdev->queue && vdev->queue->lock && 28998c2ecf20Sopenharmony_ci (v4l2_ioctls[_IOC_NR(cmd)].flags & INFO_FL_QUEUE)) 29008c2ecf20Sopenharmony_ci return vdev->queue->lock; 29018c2ecf20Sopenharmony_ci return vdev->lock; 29028c2ecf20Sopenharmony_ci} 29038c2ecf20Sopenharmony_ci 29048c2ecf20Sopenharmony_ci/* Common ioctl debug function. This function can be used by 29058c2ecf20Sopenharmony_ci external ioctl messages as well as internal V4L ioctl */ 29068c2ecf20Sopenharmony_civoid v4l_printk_ioctl(const char *prefix, unsigned int cmd) 29078c2ecf20Sopenharmony_ci{ 29088c2ecf20Sopenharmony_ci const char *dir, *type; 29098c2ecf20Sopenharmony_ci 29108c2ecf20Sopenharmony_ci if (prefix) 29118c2ecf20Sopenharmony_ci printk(KERN_DEBUG "%s: ", prefix); 29128c2ecf20Sopenharmony_ci 29138c2ecf20Sopenharmony_ci switch (_IOC_TYPE(cmd)) { 29148c2ecf20Sopenharmony_ci case 'd': 29158c2ecf20Sopenharmony_ci type = "v4l2_int"; 29168c2ecf20Sopenharmony_ci break; 29178c2ecf20Sopenharmony_ci case 'V': 29188c2ecf20Sopenharmony_ci if (_IOC_NR(cmd) >= V4L2_IOCTLS) { 29198c2ecf20Sopenharmony_ci type = "v4l2"; 29208c2ecf20Sopenharmony_ci break; 29218c2ecf20Sopenharmony_ci } 29228c2ecf20Sopenharmony_ci pr_cont("%s", v4l2_ioctls[_IOC_NR(cmd)].name); 29238c2ecf20Sopenharmony_ci return; 29248c2ecf20Sopenharmony_ci default: 29258c2ecf20Sopenharmony_ci type = "unknown"; 29268c2ecf20Sopenharmony_ci break; 29278c2ecf20Sopenharmony_ci } 29288c2ecf20Sopenharmony_ci 29298c2ecf20Sopenharmony_ci switch (_IOC_DIR(cmd)) { 29308c2ecf20Sopenharmony_ci case _IOC_NONE: dir = "--"; break; 29318c2ecf20Sopenharmony_ci case _IOC_READ: dir = "r-"; break; 29328c2ecf20Sopenharmony_ci case _IOC_WRITE: dir = "-w"; break; 29338c2ecf20Sopenharmony_ci case _IOC_READ | _IOC_WRITE: dir = "rw"; break; 29348c2ecf20Sopenharmony_ci default: dir = "*ERR*"; break; 29358c2ecf20Sopenharmony_ci } 29368c2ecf20Sopenharmony_ci pr_cont("%s ioctl '%c', dir=%s, #%d (0x%08x)", 29378c2ecf20Sopenharmony_ci type, _IOC_TYPE(cmd), dir, _IOC_NR(cmd), cmd); 29388c2ecf20Sopenharmony_ci} 29398c2ecf20Sopenharmony_ciEXPORT_SYMBOL(v4l_printk_ioctl); 29408c2ecf20Sopenharmony_ci 29418c2ecf20Sopenharmony_cistatic long __video_do_ioctl(struct file *file, 29428c2ecf20Sopenharmony_ci unsigned int cmd, void *arg) 29438c2ecf20Sopenharmony_ci{ 29448c2ecf20Sopenharmony_ci struct video_device *vfd = video_devdata(file); 29458c2ecf20Sopenharmony_ci struct mutex *req_queue_lock = NULL; 29468c2ecf20Sopenharmony_ci struct mutex *lock; /* ioctl serialization mutex */ 29478c2ecf20Sopenharmony_ci const struct v4l2_ioctl_ops *ops = vfd->ioctl_ops; 29488c2ecf20Sopenharmony_ci bool write_only = false; 29498c2ecf20Sopenharmony_ci struct v4l2_ioctl_info default_info; 29508c2ecf20Sopenharmony_ci const struct v4l2_ioctl_info *info; 29518c2ecf20Sopenharmony_ci void *fh = file->private_data; 29528c2ecf20Sopenharmony_ci struct v4l2_fh *vfh = NULL; 29538c2ecf20Sopenharmony_ci int dev_debug = vfd->dev_debug; 29548c2ecf20Sopenharmony_ci long ret = -ENOTTY; 29558c2ecf20Sopenharmony_ci 29568c2ecf20Sopenharmony_ci if (ops == NULL) { 29578c2ecf20Sopenharmony_ci pr_warn("%s: has no ioctl_ops.\n", 29588c2ecf20Sopenharmony_ci video_device_node_name(vfd)); 29598c2ecf20Sopenharmony_ci return ret; 29608c2ecf20Sopenharmony_ci } 29618c2ecf20Sopenharmony_ci 29628c2ecf20Sopenharmony_ci if (test_bit(V4L2_FL_USES_V4L2_FH, &vfd->flags)) 29638c2ecf20Sopenharmony_ci vfh = file->private_data; 29648c2ecf20Sopenharmony_ci 29658c2ecf20Sopenharmony_ci /* 29668c2ecf20Sopenharmony_ci * We need to serialize streamon/off with queueing new requests. 29678c2ecf20Sopenharmony_ci * These ioctls may trigger the cancellation of a streaming 29688c2ecf20Sopenharmony_ci * operation, and that should not be mixed with queueing a new 29698c2ecf20Sopenharmony_ci * request at the same time. 29708c2ecf20Sopenharmony_ci */ 29718c2ecf20Sopenharmony_ci if (v4l2_device_supports_requests(vfd->v4l2_dev) && 29728c2ecf20Sopenharmony_ci (cmd == VIDIOC_STREAMON || cmd == VIDIOC_STREAMOFF)) { 29738c2ecf20Sopenharmony_ci req_queue_lock = &vfd->v4l2_dev->mdev->req_queue_mutex; 29748c2ecf20Sopenharmony_ci 29758c2ecf20Sopenharmony_ci if (mutex_lock_interruptible(req_queue_lock)) 29768c2ecf20Sopenharmony_ci return -ERESTARTSYS; 29778c2ecf20Sopenharmony_ci } 29788c2ecf20Sopenharmony_ci 29798c2ecf20Sopenharmony_ci lock = v4l2_ioctl_get_lock(vfd, vfh, cmd, arg); 29808c2ecf20Sopenharmony_ci 29818c2ecf20Sopenharmony_ci if (lock && mutex_lock_interruptible(lock)) { 29828c2ecf20Sopenharmony_ci if (req_queue_lock) 29838c2ecf20Sopenharmony_ci mutex_unlock(req_queue_lock); 29848c2ecf20Sopenharmony_ci return -ERESTARTSYS; 29858c2ecf20Sopenharmony_ci } 29868c2ecf20Sopenharmony_ci 29878c2ecf20Sopenharmony_ci if (!video_is_registered(vfd)) { 29888c2ecf20Sopenharmony_ci ret = -ENODEV; 29898c2ecf20Sopenharmony_ci goto unlock; 29908c2ecf20Sopenharmony_ci } 29918c2ecf20Sopenharmony_ci 29928c2ecf20Sopenharmony_ci if (v4l2_is_known_ioctl(cmd)) { 29938c2ecf20Sopenharmony_ci info = &v4l2_ioctls[_IOC_NR(cmd)]; 29948c2ecf20Sopenharmony_ci 29958c2ecf20Sopenharmony_ci if (!test_bit(_IOC_NR(cmd), vfd->valid_ioctls) && 29968c2ecf20Sopenharmony_ci !((info->flags & INFO_FL_CTRL) && vfh && vfh->ctrl_handler)) 29978c2ecf20Sopenharmony_ci goto done; 29988c2ecf20Sopenharmony_ci 29998c2ecf20Sopenharmony_ci if (vfh && (info->flags & INFO_FL_PRIO)) { 30008c2ecf20Sopenharmony_ci ret = v4l2_prio_check(vfd->prio, vfh->prio); 30018c2ecf20Sopenharmony_ci if (ret) 30028c2ecf20Sopenharmony_ci goto done; 30038c2ecf20Sopenharmony_ci } 30048c2ecf20Sopenharmony_ci } else { 30058c2ecf20Sopenharmony_ci default_info.ioctl = cmd; 30068c2ecf20Sopenharmony_ci default_info.flags = 0; 30078c2ecf20Sopenharmony_ci default_info.debug = v4l_print_default; 30088c2ecf20Sopenharmony_ci info = &default_info; 30098c2ecf20Sopenharmony_ci } 30108c2ecf20Sopenharmony_ci 30118c2ecf20Sopenharmony_ci write_only = _IOC_DIR(cmd) == _IOC_WRITE; 30128c2ecf20Sopenharmony_ci if (info != &default_info) { 30138c2ecf20Sopenharmony_ci ret = info->func(ops, file, fh, arg); 30148c2ecf20Sopenharmony_ci } else if (!ops->vidioc_default) { 30158c2ecf20Sopenharmony_ci ret = -ENOTTY; 30168c2ecf20Sopenharmony_ci } else { 30178c2ecf20Sopenharmony_ci ret = ops->vidioc_default(file, fh, 30188c2ecf20Sopenharmony_ci vfh ? v4l2_prio_check(vfd->prio, vfh->prio) >= 0 : 0, 30198c2ecf20Sopenharmony_ci cmd, arg); 30208c2ecf20Sopenharmony_ci } 30218c2ecf20Sopenharmony_ci 30228c2ecf20Sopenharmony_cidone: 30238c2ecf20Sopenharmony_ci if (dev_debug & (V4L2_DEV_DEBUG_IOCTL | V4L2_DEV_DEBUG_IOCTL_ARG)) { 30248c2ecf20Sopenharmony_ci if (!(dev_debug & V4L2_DEV_DEBUG_STREAMING) && 30258c2ecf20Sopenharmony_ci (cmd == VIDIOC_QBUF || cmd == VIDIOC_DQBUF)) 30268c2ecf20Sopenharmony_ci goto unlock; 30278c2ecf20Sopenharmony_ci 30288c2ecf20Sopenharmony_ci v4l_printk_ioctl(video_device_node_name(vfd), cmd); 30298c2ecf20Sopenharmony_ci if (ret < 0) 30308c2ecf20Sopenharmony_ci pr_cont(": error %ld", ret); 30318c2ecf20Sopenharmony_ci if (!(dev_debug & V4L2_DEV_DEBUG_IOCTL_ARG)) 30328c2ecf20Sopenharmony_ci pr_cont("\n"); 30338c2ecf20Sopenharmony_ci else if (_IOC_DIR(cmd) == _IOC_NONE) 30348c2ecf20Sopenharmony_ci info->debug(arg, write_only); 30358c2ecf20Sopenharmony_ci else { 30368c2ecf20Sopenharmony_ci pr_cont(": "); 30378c2ecf20Sopenharmony_ci info->debug(arg, write_only); 30388c2ecf20Sopenharmony_ci } 30398c2ecf20Sopenharmony_ci } 30408c2ecf20Sopenharmony_ci 30418c2ecf20Sopenharmony_ciunlock: 30428c2ecf20Sopenharmony_ci if (lock) 30438c2ecf20Sopenharmony_ci mutex_unlock(lock); 30448c2ecf20Sopenharmony_ci if (req_queue_lock) 30458c2ecf20Sopenharmony_ci mutex_unlock(req_queue_lock); 30468c2ecf20Sopenharmony_ci return ret; 30478c2ecf20Sopenharmony_ci} 30488c2ecf20Sopenharmony_ci 30498c2ecf20Sopenharmony_cistatic int check_array_args(unsigned int cmd, void *parg, size_t *array_size, 30508c2ecf20Sopenharmony_ci void __user **user_ptr, void ***kernel_ptr) 30518c2ecf20Sopenharmony_ci{ 30528c2ecf20Sopenharmony_ci int ret = 0; 30538c2ecf20Sopenharmony_ci 30548c2ecf20Sopenharmony_ci switch (cmd) { 30558c2ecf20Sopenharmony_ci case VIDIOC_PREPARE_BUF: 30568c2ecf20Sopenharmony_ci case VIDIOC_QUERYBUF: 30578c2ecf20Sopenharmony_ci case VIDIOC_QBUF: 30588c2ecf20Sopenharmony_ci case VIDIOC_DQBUF: { 30598c2ecf20Sopenharmony_ci struct v4l2_buffer *buf = parg; 30608c2ecf20Sopenharmony_ci 30618c2ecf20Sopenharmony_ci if (V4L2_TYPE_IS_MULTIPLANAR(buf->type) && buf->length > 0) { 30628c2ecf20Sopenharmony_ci if (buf->length > VIDEO_MAX_PLANES) { 30638c2ecf20Sopenharmony_ci ret = -EINVAL; 30648c2ecf20Sopenharmony_ci break; 30658c2ecf20Sopenharmony_ci } 30668c2ecf20Sopenharmony_ci *user_ptr = (void __user *)buf->m.planes; 30678c2ecf20Sopenharmony_ci *kernel_ptr = (void **)&buf->m.planes; 30688c2ecf20Sopenharmony_ci *array_size = sizeof(struct v4l2_plane) * buf->length; 30698c2ecf20Sopenharmony_ci ret = 1; 30708c2ecf20Sopenharmony_ci } 30718c2ecf20Sopenharmony_ci break; 30728c2ecf20Sopenharmony_ci } 30738c2ecf20Sopenharmony_ci 30748c2ecf20Sopenharmony_ci case VIDIOC_G_EDID: 30758c2ecf20Sopenharmony_ci case VIDIOC_S_EDID: { 30768c2ecf20Sopenharmony_ci struct v4l2_edid *edid = parg; 30778c2ecf20Sopenharmony_ci 30788c2ecf20Sopenharmony_ci if (edid->blocks) { 30798c2ecf20Sopenharmony_ci if (edid->blocks > 256) { 30808c2ecf20Sopenharmony_ci ret = -EINVAL; 30818c2ecf20Sopenharmony_ci break; 30828c2ecf20Sopenharmony_ci } 30838c2ecf20Sopenharmony_ci *user_ptr = (void __user *)edid->edid; 30848c2ecf20Sopenharmony_ci *kernel_ptr = (void **)&edid->edid; 30858c2ecf20Sopenharmony_ci *array_size = edid->blocks * 128; 30868c2ecf20Sopenharmony_ci ret = 1; 30878c2ecf20Sopenharmony_ci } 30888c2ecf20Sopenharmony_ci break; 30898c2ecf20Sopenharmony_ci } 30908c2ecf20Sopenharmony_ci 30918c2ecf20Sopenharmony_ci case VIDIOC_S_EXT_CTRLS: 30928c2ecf20Sopenharmony_ci case VIDIOC_G_EXT_CTRLS: 30938c2ecf20Sopenharmony_ci case VIDIOC_TRY_EXT_CTRLS: { 30948c2ecf20Sopenharmony_ci struct v4l2_ext_controls *ctrls = parg; 30958c2ecf20Sopenharmony_ci 30968c2ecf20Sopenharmony_ci if (ctrls->count != 0) { 30978c2ecf20Sopenharmony_ci if (ctrls->count > V4L2_CID_MAX_CTRLS) { 30988c2ecf20Sopenharmony_ci ret = -EINVAL; 30998c2ecf20Sopenharmony_ci break; 31008c2ecf20Sopenharmony_ci } 31018c2ecf20Sopenharmony_ci *user_ptr = (void __user *)ctrls->controls; 31028c2ecf20Sopenharmony_ci *kernel_ptr = (void **)&ctrls->controls; 31038c2ecf20Sopenharmony_ci *array_size = sizeof(struct v4l2_ext_control) 31048c2ecf20Sopenharmony_ci * ctrls->count; 31058c2ecf20Sopenharmony_ci ret = 1; 31068c2ecf20Sopenharmony_ci } 31078c2ecf20Sopenharmony_ci break; 31088c2ecf20Sopenharmony_ci } 31098c2ecf20Sopenharmony_ci } 31108c2ecf20Sopenharmony_ci 31118c2ecf20Sopenharmony_ci return ret; 31128c2ecf20Sopenharmony_ci} 31138c2ecf20Sopenharmony_ci 31148c2ecf20Sopenharmony_cistatic unsigned int video_translate_cmd(unsigned int cmd) 31158c2ecf20Sopenharmony_ci{ 31168c2ecf20Sopenharmony_ci switch (cmd) { 31178c2ecf20Sopenharmony_ci#ifdef CONFIG_COMPAT_32BIT_TIME 31188c2ecf20Sopenharmony_ci case VIDIOC_DQEVENT_TIME32: 31198c2ecf20Sopenharmony_ci return VIDIOC_DQEVENT; 31208c2ecf20Sopenharmony_ci case VIDIOC_QUERYBUF_TIME32: 31218c2ecf20Sopenharmony_ci return VIDIOC_QUERYBUF; 31228c2ecf20Sopenharmony_ci case VIDIOC_QBUF_TIME32: 31238c2ecf20Sopenharmony_ci return VIDIOC_QBUF; 31248c2ecf20Sopenharmony_ci case VIDIOC_DQBUF_TIME32: 31258c2ecf20Sopenharmony_ci return VIDIOC_DQBUF; 31268c2ecf20Sopenharmony_ci case VIDIOC_PREPARE_BUF_TIME32: 31278c2ecf20Sopenharmony_ci return VIDIOC_PREPARE_BUF; 31288c2ecf20Sopenharmony_ci#endif 31298c2ecf20Sopenharmony_ci } 31308c2ecf20Sopenharmony_ci 31318c2ecf20Sopenharmony_ci return cmd; 31328c2ecf20Sopenharmony_ci} 31338c2ecf20Sopenharmony_ci 31348c2ecf20Sopenharmony_cistatic int video_get_user(void __user *arg, void *parg, unsigned int cmd, 31358c2ecf20Sopenharmony_ci bool *always_copy) 31368c2ecf20Sopenharmony_ci{ 31378c2ecf20Sopenharmony_ci unsigned int n = _IOC_SIZE(cmd); 31388c2ecf20Sopenharmony_ci 31398c2ecf20Sopenharmony_ci if (!(_IOC_DIR(cmd) & _IOC_WRITE)) { 31408c2ecf20Sopenharmony_ci /* read-only ioctl */ 31418c2ecf20Sopenharmony_ci memset(parg, 0, n); 31428c2ecf20Sopenharmony_ci return 0; 31438c2ecf20Sopenharmony_ci } 31448c2ecf20Sopenharmony_ci 31458c2ecf20Sopenharmony_ci switch (cmd) { 31468c2ecf20Sopenharmony_ci#ifdef CONFIG_COMPAT_32BIT_TIME 31478c2ecf20Sopenharmony_ci case VIDIOC_QUERYBUF_TIME32: 31488c2ecf20Sopenharmony_ci case VIDIOC_QBUF_TIME32: 31498c2ecf20Sopenharmony_ci case VIDIOC_DQBUF_TIME32: 31508c2ecf20Sopenharmony_ci case VIDIOC_PREPARE_BUF_TIME32: { 31518c2ecf20Sopenharmony_ci struct v4l2_buffer_time32 vb32; 31528c2ecf20Sopenharmony_ci struct v4l2_buffer *vb = parg; 31538c2ecf20Sopenharmony_ci 31548c2ecf20Sopenharmony_ci if (copy_from_user(&vb32, arg, sizeof(vb32))) 31558c2ecf20Sopenharmony_ci return -EFAULT; 31568c2ecf20Sopenharmony_ci 31578c2ecf20Sopenharmony_ci *vb = (struct v4l2_buffer) { 31588c2ecf20Sopenharmony_ci .index = vb32.index, 31598c2ecf20Sopenharmony_ci .type = vb32.type, 31608c2ecf20Sopenharmony_ci .bytesused = vb32.bytesused, 31618c2ecf20Sopenharmony_ci .flags = vb32.flags, 31628c2ecf20Sopenharmony_ci .field = vb32.field, 31638c2ecf20Sopenharmony_ci .timestamp.tv_sec = vb32.timestamp.tv_sec, 31648c2ecf20Sopenharmony_ci .timestamp.tv_usec = vb32.timestamp.tv_usec, 31658c2ecf20Sopenharmony_ci .timecode = vb32.timecode, 31668c2ecf20Sopenharmony_ci .sequence = vb32.sequence, 31678c2ecf20Sopenharmony_ci .memory = vb32.memory, 31688c2ecf20Sopenharmony_ci .m.userptr = vb32.m.userptr, 31698c2ecf20Sopenharmony_ci .length = vb32.length, 31708c2ecf20Sopenharmony_ci .request_fd = vb32.request_fd, 31718c2ecf20Sopenharmony_ci }; 31728c2ecf20Sopenharmony_ci 31738c2ecf20Sopenharmony_ci if (cmd == VIDIOC_QUERYBUF_TIME32) 31748c2ecf20Sopenharmony_ci vb->request_fd = 0; 31758c2ecf20Sopenharmony_ci 31768c2ecf20Sopenharmony_ci break; 31778c2ecf20Sopenharmony_ci } 31788c2ecf20Sopenharmony_ci#endif 31798c2ecf20Sopenharmony_ci default: 31808c2ecf20Sopenharmony_ci /* 31818c2ecf20Sopenharmony_ci * In some cases, only a few fields are used as input, 31828c2ecf20Sopenharmony_ci * i.e. when the app sets "index" and then the driver 31838c2ecf20Sopenharmony_ci * fills in the rest of the structure for the thing 31848c2ecf20Sopenharmony_ci * with that index. We only need to copy up the first 31858c2ecf20Sopenharmony_ci * non-input field. 31868c2ecf20Sopenharmony_ci */ 31878c2ecf20Sopenharmony_ci if (v4l2_is_known_ioctl(cmd)) { 31888c2ecf20Sopenharmony_ci u32 flags = v4l2_ioctls[_IOC_NR(cmd)].flags; 31898c2ecf20Sopenharmony_ci 31908c2ecf20Sopenharmony_ci if (flags & INFO_FL_CLEAR_MASK) 31918c2ecf20Sopenharmony_ci n = (flags & INFO_FL_CLEAR_MASK) >> 16; 31928c2ecf20Sopenharmony_ci *always_copy = flags & INFO_FL_ALWAYS_COPY; 31938c2ecf20Sopenharmony_ci } 31948c2ecf20Sopenharmony_ci 31958c2ecf20Sopenharmony_ci if (copy_from_user(parg, (void __user *)arg, n)) 31968c2ecf20Sopenharmony_ci return -EFAULT; 31978c2ecf20Sopenharmony_ci 31988c2ecf20Sopenharmony_ci /* zero out anything we don't copy from userspace */ 31998c2ecf20Sopenharmony_ci if (n < _IOC_SIZE(cmd)) 32008c2ecf20Sopenharmony_ci memset((u8 *)parg + n, 0, _IOC_SIZE(cmd) - n); 32018c2ecf20Sopenharmony_ci break; 32028c2ecf20Sopenharmony_ci } 32038c2ecf20Sopenharmony_ci 32048c2ecf20Sopenharmony_ci return 0; 32058c2ecf20Sopenharmony_ci} 32068c2ecf20Sopenharmony_ci 32078c2ecf20Sopenharmony_cistatic int video_put_user(void __user *arg, void *parg, unsigned int cmd) 32088c2ecf20Sopenharmony_ci{ 32098c2ecf20Sopenharmony_ci if (!(_IOC_DIR(cmd) & _IOC_READ)) 32108c2ecf20Sopenharmony_ci return 0; 32118c2ecf20Sopenharmony_ci 32128c2ecf20Sopenharmony_ci switch (cmd) { 32138c2ecf20Sopenharmony_ci#ifdef CONFIG_COMPAT_32BIT_TIME 32148c2ecf20Sopenharmony_ci case VIDIOC_DQEVENT_TIME32: { 32158c2ecf20Sopenharmony_ci struct v4l2_event *ev = parg; 32168c2ecf20Sopenharmony_ci struct v4l2_event_time32 ev32; 32178c2ecf20Sopenharmony_ci 32188c2ecf20Sopenharmony_ci memset(&ev32, 0, sizeof(ev32)); 32198c2ecf20Sopenharmony_ci 32208c2ecf20Sopenharmony_ci ev32.type = ev->type; 32218c2ecf20Sopenharmony_ci ev32.pending = ev->pending; 32228c2ecf20Sopenharmony_ci ev32.sequence = ev->sequence; 32238c2ecf20Sopenharmony_ci ev32.timestamp.tv_sec = ev->timestamp.tv_sec; 32248c2ecf20Sopenharmony_ci ev32.timestamp.tv_nsec = ev->timestamp.tv_nsec; 32258c2ecf20Sopenharmony_ci ev32.id = ev->id; 32268c2ecf20Sopenharmony_ci 32278c2ecf20Sopenharmony_ci memcpy(&ev32.u, &ev->u, sizeof(ev->u)); 32288c2ecf20Sopenharmony_ci memcpy(&ev32.reserved, &ev->reserved, sizeof(ev->reserved)); 32298c2ecf20Sopenharmony_ci 32308c2ecf20Sopenharmony_ci if (copy_to_user(arg, &ev32, sizeof(ev32))) 32318c2ecf20Sopenharmony_ci return -EFAULT; 32328c2ecf20Sopenharmony_ci break; 32338c2ecf20Sopenharmony_ci } 32348c2ecf20Sopenharmony_ci case VIDIOC_QUERYBUF_TIME32: 32358c2ecf20Sopenharmony_ci case VIDIOC_QBUF_TIME32: 32368c2ecf20Sopenharmony_ci case VIDIOC_DQBUF_TIME32: 32378c2ecf20Sopenharmony_ci case VIDIOC_PREPARE_BUF_TIME32: { 32388c2ecf20Sopenharmony_ci struct v4l2_buffer *vb = parg; 32398c2ecf20Sopenharmony_ci struct v4l2_buffer_time32 vb32; 32408c2ecf20Sopenharmony_ci 32418c2ecf20Sopenharmony_ci memset(&vb32, 0, sizeof(vb32)); 32428c2ecf20Sopenharmony_ci 32438c2ecf20Sopenharmony_ci vb32.index = vb->index; 32448c2ecf20Sopenharmony_ci vb32.type = vb->type; 32458c2ecf20Sopenharmony_ci vb32.bytesused = vb->bytesused; 32468c2ecf20Sopenharmony_ci vb32.flags = vb->flags; 32478c2ecf20Sopenharmony_ci vb32.field = vb->field; 32488c2ecf20Sopenharmony_ci vb32.timestamp.tv_sec = vb->timestamp.tv_sec; 32498c2ecf20Sopenharmony_ci vb32.timestamp.tv_usec = vb->timestamp.tv_usec; 32508c2ecf20Sopenharmony_ci vb32.timecode = vb->timecode; 32518c2ecf20Sopenharmony_ci vb32.sequence = vb->sequence; 32528c2ecf20Sopenharmony_ci vb32.memory = vb->memory; 32538c2ecf20Sopenharmony_ci vb32.m.userptr = vb->m.userptr; 32548c2ecf20Sopenharmony_ci vb32.length = vb->length; 32558c2ecf20Sopenharmony_ci vb32.request_fd = vb->request_fd; 32568c2ecf20Sopenharmony_ci 32578c2ecf20Sopenharmony_ci if (copy_to_user(arg, &vb32, sizeof(vb32))) 32588c2ecf20Sopenharmony_ci return -EFAULT; 32598c2ecf20Sopenharmony_ci break; 32608c2ecf20Sopenharmony_ci } 32618c2ecf20Sopenharmony_ci#endif 32628c2ecf20Sopenharmony_ci default: 32638c2ecf20Sopenharmony_ci /* Copy results into user buffer */ 32648c2ecf20Sopenharmony_ci if (copy_to_user(arg, parg, _IOC_SIZE(cmd))) 32658c2ecf20Sopenharmony_ci return -EFAULT; 32668c2ecf20Sopenharmony_ci break; 32678c2ecf20Sopenharmony_ci } 32688c2ecf20Sopenharmony_ci 32698c2ecf20Sopenharmony_ci return 0; 32708c2ecf20Sopenharmony_ci} 32718c2ecf20Sopenharmony_ci 32728c2ecf20Sopenharmony_cilong 32738c2ecf20Sopenharmony_civideo_usercopy(struct file *file, unsigned int orig_cmd, unsigned long arg, 32748c2ecf20Sopenharmony_ci v4l2_kioctl func) 32758c2ecf20Sopenharmony_ci{ 32768c2ecf20Sopenharmony_ci char sbuf[128]; 32778c2ecf20Sopenharmony_ci void *mbuf = NULL, *array_buf = NULL; 32788c2ecf20Sopenharmony_ci void *parg = (void *)arg; 32798c2ecf20Sopenharmony_ci long err = -EINVAL; 32808c2ecf20Sopenharmony_ci bool has_array_args; 32818c2ecf20Sopenharmony_ci bool always_copy = false; 32828c2ecf20Sopenharmony_ci size_t array_size = 0; 32838c2ecf20Sopenharmony_ci void __user *user_ptr = NULL; 32848c2ecf20Sopenharmony_ci void **kernel_ptr = NULL; 32858c2ecf20Sopenharmony_ci unsigned int cmd = video_translate_cmd(orig_cmd); 32868c2ecf20Sopenharmony_ci const size_t ioc_size = _IOC_SIZE(cmd); 32878c2ecf20Sopenharmony_ci 32888c2ecf20Sopenharmony_ci /* Copy arguments into temp kernel buffer */ 32898c2ecf20Sopenharmony_ci if (_IOC_DIR(cmd) != _IOC_NONE) { 32908c2ecf20Sopenharmony_ci if (ioc_size <= sizeof(sbuf)) { 32918c2ecf20Sopenharmony_ci parg = sbuf; 32928c2ecf20Sopenharmony_ci } else { 32938c2ecf20Sopenharmony_ci /* too big to allocate from stack */ 32948c2ecf20Sopenharmony_ci mbuf = kvmalloc(ioc_size, GFP_KERNEL); 32958c2ecf20Sopenharmony_ci if (NULL == mbuf) 32968c2ecf20Sopenharmony_ci return -ENOMEM; 32978c2ecf20Sopenharmony_ci parg = mbuf; 32988c2ecf20Sopenharmony_ci } 32998c2ecf20Sopenharmony_ci 33008c2ecf20Sopenharmony_ci err = video_get_user((void __user *)arg, parg, orig_cmd, 33018c2ecf20Sopenharmony_ci &always_copy); 33028c2ecf20Sopenharmony_ci if (err) 33038c2ecf20Sopenharmony_ci goto out; 33048c2ecf20Sopenharmony_ci } 33058c2ecf20Sopenharmony_ci 33068c2ecf20Sopenharmony_ci err = check_array_args(cmd, parg, &array_size, &user_ptr, &kernel_ptr); 33078c2ecf20Sopenharmony_ci if (err < 0) 33088c2ecf20Sopenharmony_ci goto out; 33098c2ecf20Sopenharmony_ci has_array_args = err; 33108c2ecf20Sopenharmony_ci 33118c2ecf20Sopenharmony_ci if (has_array_args) { 33128c2ecf20Sopenharmony_ci array_buf = kvmalloc(array_size, GFP_KERNEL); 33138c2ecf20Sopenharmony_ci err = -ENOMEM; 33148c2ecf20Sopenharmony_ci if (array_buf == NULL) 33158c2ecf20Sopenharmony_ci goto out_array_args; 33168c2ecf20Sopenharmony_ci err = -EFAULT; 33178c2ecf20Sopenharmony_ci if (copy_from_user(array_buf, user_ptr, array_size)) 33188c2ecf20Sopenharmony_ci goto out_array_args; 33198c2ecf20Sopenharmony_ci *kernel_ptr = array_buf; 33208c2ecf20Sopenharmony_ci } 33218c2ecf20Sopenharmony_ci 33228c2ecf20Sopenharmony_ci /* Handles IOCTL */ 33238c2ecf20Sopenharmony_ci err = func(file, cmd, parg); 33248c2ecf20Sopenharmony_ci if (err == -ENOTTY || err == -ENOIOCTLCMD) { 33258c2ecf20Sopenharmony_ci err = -ENOTTY; 33268c2ecf20Sopenharmony_ci goto out; 33278c2ecf20Sopenharmony_ci } 33288c2ecf20Sopenharmony_ci 33298c2ecf20Sopenharmony_ci if (err == 0) { 33308c2ecf20Sopenharmony_ci if (cmd == VIDIOC_DQBUF) 33318c2ecf20Sopenharmony_ci trace_v4l2_dqbuf(video_devdata(file)->minor, parg); 33328c2ecf20Sopenharmony_ci else if (cmd == VIDIOC_QBUF) 33338c2ecf20Sopenharmony_ci trace_v4l2_qbuf(video_devdata(file)->minor, parg); 33348c2ecf20Sopenharmony_ci } 33358c2ecf20Sopenharmony_ci 33368c2ecf20Sopenharmony_ci if (has_array_args) { 33378c2ecf20Sopenharmony_ci *kernel_ptr = (void __force *)user_ptr; 33388c2ecf20Sopenharmony_ci if (copy_to_user(user_ptr, array_buf, array_size)) 33398c2ecf20Sopenharmony_ci err = -EFAULT; 33408c2ecf20Sopenharmony_ci goto out_array_args; 33418c2ecf20Sopenharmony_ci } 33428c2ecf20Sopenharmony_ci /* 33438c2ecf20Sopenharmony_ci * Some ioctls can return an error, but still have valid 33448c2ecf20Sopenharmony_ci * results that must be returned. 33458c2ecf20Sopenharmony_ci */ 33468c2ecf20Sopenharmony_ci if (err < 0 && !always_copy) 33478c2ecf20Sopenharmony_ci goto out; 33488c2ecf20Sopenharmony_ci 33498c2ecf20Sopenharmony_ciout_array_args: 33508c2ecf20Sopenharmony_ci if (video_put_user((void __user *)arg, parg, orig_cmd)) 33518c2ecf20Sopenharmony_ci err = -EFAULT; 33528c2ecf20Sopenharmony_ciout: 33538c2ecf20Sopenharmony_ci kvfree(array_buf); 33548c2ecf20Sopenharmony_ci kvfree(mbuf); 33558c2ecf20Sopenharmony_ci return err; 33568c2ecf20Sopenharmony_ci} 33578c2ecf20Sopenharmony_ci 33588c2ecf20Sopenharmony_cilong video_ioctl2(struct file *file, 33598c2ecf20Sopenharmony_ci unsigned int cmd, unsigned long arg) 33608c2ecf20Sopenharmony_ci{ 33618c2ecf20Sopenharmony_ci return video_usercopy(file, cmd, arg, __video_do_ioctl); 33628c2ecf20Sopenharmony_ci} 33638c2ecf20Sopenharmony_ciEXPORT_SYMBOL(video_ioctl2); 3364