summaryrefslogtreecommitdiffstats
path: root/kernel/drivers/media/v4l2-core/v4l2-ioctl.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/drivers/media/v4l2-core/v4l2-ioctl.c')
-rw-r--r--kernel/drivers/media/v4l2-core/v4l2-ioctl.c271
1 files changed, 251 insertions, 20 deletions
diff --git a/kernel/drivers/media/v4l2-core/v4l2-ioctl.c b/kernel/drivers/media/v4l2-core/v4l2-ioctl.c
index aa407cb5f..7486af2c8 100644
--- a/kernel/drivers/media/v4l2-core/v4l2-ioctl.c
+++ b/kernel/drivers/media/v4l2-core/v4l2-ioctl.c
@@ -26,9 +26,8 @@
#include <media/v4l2-fh.h>
#include <media/v4l2-event.h>
#include <media/v4l2-device.h>
-#include <media/videobuf2-core.h>
+#include <media/videobuf2-v4l2.h>
-#define CREATE_TRACE_POINTS
#include <trace/events/v4l2.h>
/* Zero out the end of the struct pointed to by p. Everything after, but
@@ -142,6 +141,7 @@ const char *v4l2_field_names[] = {
EXPORT_SYMBOL(v4l2_field_names);
const char *v4l2_type_names[] = {
+ [0] = "0",
[V4L2_BUF_TYPE_VIDEO_CAPTURE] = "vid-cap",
[V4L2_BUF_TYPE_VIDEO_OVERLAY] = "vid-overlay",
[V4L2_BUF_TYPE_VIDEO_OUTPUT] = "vid-out",
@@ -153,6 +153,7 @@ const char *v4l2_type_names[] = {
[V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE] = "vid-cap-mplane",
[V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE] = "vid-out-mplane",
[V4L2_BUF_TYPE_SDR_CAPTURE] = "sdr-cap",
+ [V4L2_BUF_TYPE_SDR_OUTPUT] = "sdr-out",
};
EXPORT_SYMBOL(v4l2_type_names);
@@ -257,7 +258,8 @@ static void v4l_print_format(const void *arg, bool write_only)
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\n",
+ "flags=0x%x, ycbcr_enc=%u, quantization=%u, "
+ "xfer_func=%u\n",
pix->width, pix->height,
(pix->pixelformat & 0xff),
(pix->pixelformat >> 8) & 0xff,
@@ -266,7 +268,7 @@ static void v4l_print_format(const void *arg, bool write_only)
prt_names(pix->field, v4l2_field_names),
pix->bytesperline, pix->sizeimage,
pix->colorspace, pix->flags, pix->ycbcr_enc,
- pix->quantization);
+ pix->quantization, pix->xfer_func);
break;
case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
@@ -274,7 +276,7 @@ static void v4l_print_format(const void *arg, bool write_only)
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\n",
+ "ycbcr_enc=%u, quantization=%u, xfer_func=%u\n",
mp->width, mp->height,
(mp->pixelformat & 0xff),
(mp->pixelformat >> 8) & 0xff,
@@ -282,7 +284,7 @@ static void v4l_print_format(const void *arg, bool write_only)
(mp->pixelformat >> 24) & 0xff,
prt_names(mp->field, v4l2_field_names),
mp->colorspace, mp->num_planes, mp->flags,
- mp->ycbcr_enc, mp->quantization);
+ mp->ycbcr_enc, mp->quantization, mp->xfer_func);
for (i = 0; i < mp->num_planes; i++)
printk(KERN_DEBUG "plane %u: bytesperline=%u sizeimage=%u\n", i,
mp->plane_fmt[i].bytesperline,
@@ -325,6 +327,7 @@ static void v4l_print_format(const void *arg, bool write_only)
sliced->service_lines[1][i]);
break;
case V4L2_BUF_TYPE_SDR_CAPTURE:
+ case V4L2_BUF_TYPE_SDR_OUTPUT:
sdr = &p->fmt.sdr;
pr_cont(", pixelformat=%c%c%c%c\n",
(sdr->pixelformat >> 0) & 0xff,
@@ -973,6 +976,10 @@ static int check_fmt(struct file *file, enum v4l2_buf_type type)
if (is_sdr && is_rx && ops->vidioc_g_fmt_sdr_cap)
return 0;
break;
+ case V4L2_BUF_TYPE_SDR_OUTPUT:
+ if (is_sdr && is_tx && ops->vidioc_g_fmt_sdr_out)
+ return 0;
+ break;
default:
break;
}
@@ -1023,8 +1030,9 @@ static int v4l_querycap(const struct v4l2_ioctl_ops *ops,
* Drivers MUST fill in device_caps, so check for this and
* warn if it was forgotten.
*/
- WARN_ON(!(cap->capabilities & V4L2_CAP_DEVICE_CAPS) ||
- !cap->device_caps);
+ WARN(!(cap->capabilities & V4L2_CAP_DEVICE_CAPS) ||
+ !cap->device_caps, "Bad caps for driver %s, %x %x",
+ cap->driver, cap->capabilities, cap->device_caps);
cap->device_caps |= V4L2_CAP_EXT_PIX_FORMAT;
return ret;
@@ -1103,6 +1111,183 @@ static int v4l_enumoutput(const struct v4l2_ioctl_ops *ops,
return ops->vidioc_enum_output(file, fh, p);
}
+static void v4l_fill_fmtdesc(struct v4l2_fmtdesc *fmt)
+{
+ const unsigned sz = sizeof(fmt->description);
+ const char *descr = NULL;
+ u32 flags = 0;
+
+ /*
+ * We depart from the normal coding style here since the descriptions
+ * should be aligned so it is easy to see which descriptions will be
+ * longer than 31 characters (the max length for a description).
+ * And frankly, this is easier to read anyway.
+ *
+ * Note that gcc will use O(log N) comparisons to find the right case.
+ */
+ switch (fmt->pixelformat) {
+ /* Max description length mask: descr = "0123456789012345678901234567890" */
+ case V4L2_PIX_FMT_RGB332: descr = "8-bit RGB 3-3-2"; break;
+ case V4L2_PIX_FMT_RGB444: descr = "16-bit A/XRGB 4-4-4-4"; break;
+ case V4L2_PIX_FMT_ARGB444: descr = "16-bit ARGB 4-4-4-4"; break;
+ case V4L2_PIX_FMT_XRGB444: descr = "16-bit XRGB 4-4-4-4"; break;
+ case V4L2_PIX_FMT_RGB555: descr = "16-bit A/XRGB 1-5-5-5"; break;
+ case V4L2_PIX_FMT_ARGB555: descr = "16-bit ARGB 1-5-5-5"; break;
+ case V4L2_PIX_FMT_XRGB555: descr = "16-bit XRGB 1-5-5-5"; break;
+ case V4L2_PIX_FMT_RGB565: descr = "16-bit RGB 5-6-5"; break;
+ case V4L2_PIX_FMT_RGB555X: descr = "16-bit A/XRGB 1-5-5-5 BE"; break;
+ case V4L2_PIX_FMT_ARGB555X: descr = "16-bit ARGB 1-5-5-5 BE"; break;
+ case V4L2_PIX_FMT_XRGB555X: descr = "16-bit XRGB 1-5-5-5 BE"; break;
+ case V4L2_PIX_FMT_RGB565X: descr = "16-bit RGB 5-6-5 BE"; break;
+ case V4L2_PIX_FMT_BGR666: descr = "18-bit BGRX 6-6-6-14"; break;
+ case V4L2_PIX_FMT_BGR24: descr = "24-bit BGR 8-8-8"; break;
+ case V4L2_PIX_FMT_RGB24: descr = "24-bit RGB 8-8-8"; break;
+ case V4L2_PIX_FMT_BGR32: descr = "32-bit BGRA/X 8-8-8-8"; break;
+ case V4L2_PIX_FMT_ABGR32: descr = "32-bit BGRA 8-8-8-8"; break;
+ case V4L2_PIX_FMT_XBGR32: descr = "32-bit BGRX 8-8-8-8"; break;
+ case V4L2_PIX_FMT_RGB32: descr = "32-bit A/XRGB 8-8-8-8"; break;
+ case V4L2_PIX_FMT_ARGB32: descr = "32-bit ARGB 8-8-8-8"; break;
+ case V4L2_PIX_FMT_XRGB32: descr = "32-bit XRGB 8-8-8-8"; break;
+ case V4L2_PIX_FMT_GREY: descr = "8-bit Greyscale"; break;
+ case V4L2_PIX_FMT_Y4: descr = "4-bit Greyscale"; break;
+ case V4L2_PIX_FMT_Y6: descr = "6-bit Greyscale"; break;
+ case V4L2_PIX_FMT_Y10: descr = "10-bit Greyscale"; break;
+ case V4L2_PIX_FMT_Y12: descr = "12-bit Greyscale"; break;
+ case V4L2_PIX_FMT_Y16: descr = "16-bit Greyscale"; break;
+ case V4L2_PIX_FMT_Y16_BE: descr = "16-bit Greyscale BE"; break;
+ case V4L2_PIX_FMT_Y10BPACK: descr = "10-bit Greyscale (Packed)"; break;
+ case V4L2_PIX_FMT_PAL8: descr = "8-bit Palette"; break;
+ case V4L2_PIX_FMT_UV8: descr = "8-bit Chrominance UV 4-4"; break;
+ case V4L2_PIX_FMT_YVU410: descr = "Planar YVU 4:1:0"; break;
+ case V4L2_PIX_FMT_YVU420: descr = "Planar YVU 4:2:0"; break;
+ case V4L2_PIX_FMT_YUYV: descr = "YUYV 4:2:2"; break;
+ case V4L2_PIX_FMT_YYUV: descr = "YYUV 4:2:2"; break;
+ case V4L2_PIX_FMT_YVYU: descr = "YVYU 4:2:2"; break;
+ case V4L2_PIX_FMT_UYVY: descr = "UYVY 4:2:2"; break;
+ case V4L2_PIX_FMT_VYUY: descr = "VYUY 4:2:2"; break;
+ case V4L2_PIX_FMT_YUV422P: descr = "Planar YVU 4:2:2"; break;
+ case V4L2_PIX_FMT_YUV411P: descr = "Planar YUV 4:1:1"; break;
+ case V4L2_PIX_FMT_Y41P: descr = "YUV 4:1:1 (Packed)"; break;
+ case V4L2_PIX_FMT_YUV444: descr = "16-bit A/XYUV 4-4-4-4"; break;
+ case V4L2_PIX_FMT_YUV555: descr = "16-bit A/XYUV 1-5-5-5"; break;
+ case V4L2_PIX_FMT_YUV565: descr = "16-bit YUV 5-6-5"; break;
+ case V4L2_PIX_FMT_YUV32: descr = "32-bit A/XYUV 8-8-8-8"; break;
+ case V4L2_PIX_FMT_YUV410: descr = "Planar YUV 4:1:0"; break;
+ case V4L2_PIX_FMT_YUV420: descr = "Planar YUV 4:2:0"; break;
+ case V4L2_PIX_FMT_HI240: descr = "8-bit Dithered RGB (BTTV)"; break;
+ case V4L2_PIX_FMT_HM12: descr = "YUV 4:2:0 (16x16 Macroblocks)"; break;
+ case V4L2_PIX_FMT_M420: descr = "YUV 4:2:0 (M420)"; break;
+ case V4L2_PIX_FMT_NV12: descr = "Y/CbCr 4:2:0"; break;
+ case V4L2_PIX_FMT_NV21: descr = "Y/CrCb 4:2:0"; break;
+ case V4L2_PIX_FMT_NV16: descr = "Y/CbCr 4:2:2"; break;
+ case V4L2_PIX_FMT_NV61: descr = "Y/CrCb 4:2:2"; break;
+ case V4L2_PIX_FMT_NV24: descr = "Y/CbCr 4:4:4"; break;
+ case V4L2_PIX_FMT_NV42: descr = "Y/CrCb 4:4:4"; break;
+ case V4L2_PIX_FMT_NV12M: descr = "Y/CbCr 4:2:0 (N-C)"; break;
+ case V4L2_PIX_FMT_NV21M: descr = "Y/CrCb 4:2:0 (N-C)"; break;
+ case V4L2_PIX_FMT_NV16M: descr = "Y/CbCr 4:2:2 (N-C)"; break;
+ case V4L2_PIX_FMT_NV61M: descr = "Y/CrCb 4:2:2 (N-C)"; break;
+ case V4L2_PIX_FMT_NV12MT: descr = "Y/CbCr 4:2:0 (64x32 MB, N-C)"; break;
+ case V4L2_PIX_FMT_NV12MT_16X16: descr = "Y/CbCr 4:2:0 (16x16 MB, N-C)"; break;
+ case V4L2_PIX_FMT_YUV420M: descr = "Planar YUV 4:2:0 (N-C)"; break;
+ case V4L2_PIX_FMT_YVU420M: descr = "Planar YVU 4:2:0 (N-C)"; break;
+ case V4L2_PIX_FMT_SBGGR8: descr = "8-bit Bayer BGBG/GRGR"; break;
+ case V4L2_PIX_FMT_SGBRG8: descr = "8-bit Bayer GBGB/RGRG"; break;
+ case V4L2_PIX_FMT_SGRBG8: descr = "8-bit Bayer GRGR/BGBG"; break;
+ case V4L2_PIX_FMT_SRGGB8: descr = "8-bit Bayer RGRG/GBGB"; break;
+ case V4L2_PIX_FMT_SBGGR10: descr = "10-bit Bayer BGBG/GRGR"; break;
+ case V4L2_PIX_FMT_SGBRG10: descr = "10-bit Bayer GBGB/RGRG"; break;
+ case V4L2_PIX_FMT_SGRBG10: descr = "10-bit Bayer GRGR/BGBG"; break;
+ case V4L2_PIX_FMT_SRGGB10: descr = "10-bit Bayer RGRG/GBGB"; break;
+ case V4L2_PIX_FMT_SBGGR12: descr = "12-bit Bayer BGBG/GRGR"; break;
+ case V4L2_PIX_FMT_SGBRG12: descr = "12-bit Bayer GBGB/RGRG"; break;
+ case V4L2_PIX_FMT_SGRBG12: descr = "12-bit Bayer GRGR/BGBG"; break;
+ case V4L2_PIX_FMT_SRGGB12: descr = "12-bit Bayer RGRG/GBGB"; break;
+ case V4L2_PIX_FMT_SBGGR10P: descr = "10-bit Bayer BGBG/GRGR Packed"; break;
+ case V4L2_PIX_FMT_SGBRG10P: descr = "10-bit Bayer GBGB/RGRG Packed"; break;
+ case V4L2_PIX_FMT_SGRBG10P: descr = "10-bit Bayer GRGR/BGBG Packed"; break;
+ case V4L2_PIX_FMT_SRGGB10P: descr = "10-bit Bayer RGRG/GBGB Packed"; break;
+ case V4L2_PIX_FMT_SBGGR10ALAW8: descr = "8-bit Bayer BGBG/GRGR (A-law)"; break;
+ case V4L2_PIX_FMT_SGBRG10ALAW8: descr = "8-bit Bayer GBGB/RGRG (A-law)"; break;
+ case V4L2_PIX_FMT_SGRBG10ALAW8: descr = "8-bit Bayer GRGR/BGBG (A-law)"; break;
+ case V4L2_PIX_FMT_SRGGB10ALAW8: descr = "8-bit Bayer RGRG/GBGB (A-law)"; break;
+ case V4L2_PIX_FMT_SBGGR10DPCM8: descr = "8-bit Bayer BGBG/GRGR (DPCM)"; break;
+ case V4L2_PIX_FMT_SGBRG10DPCM8: descr = "8-bit Bayer GBGB/RGRG (DPCM)"; break;
+ case V4L2_PIX_FMT_SGRBG10DPCM8: descr = "8-bit Bayer GRGR/BGBG (DPCM)"; break;
+ case V4L2_PIX_FMT_SRGGB10DPCM8: descr = "8-bit Bayer RGRG/GBGB (DPCM)"; break;
+ case V4L2_PIX_FMT_SBGGR16: descr = "16-bit Bayer BGBG/GRGR (Exp.)"; break;
+ case V4L2_PIX_FMT_SN9C20X_I420: descr = "GSPCA SN9C20X I420"; break;
+ case V4L2_PIX_FMT_SPCA501: descr = "GSPCA SPCA501"; break;
+ case V4L2_PIX_FMT_SPCA505: descr = "GSPCA SPCA505"; break;
+ case V4L2_PIX_FMT_SPCA508: descr = "GSPCA SPCA508"; break;
+ case V4L2_PIX_FMT_STV0680: descr = "GSPCA STV0680"; break;
+ case V4L2_PIX_FMT_TM6000: descr = "A/V + VBI Mux Packet"; break;
+ case V4L2_PIX_FMT_CIT_YYVYUY: descr = "GSPCA CIT YYVYUY"; break;
+ case V4L2_PIX_FMT_KONICA420: descr = "GSPCA KONICA420"; break;
+ case V4L2_SDR_FMT_CU8: descr = "Complex U8"; break;
+ case V4L2_SDR_FMT_CU16LE: descr = "Complex U16LE"; break;
+ case V4L2_SDR_FMT_CS8: descr = "Complex S8"; break;
+ case V4L2_SDR_FMT_CS14LE: descr = "Complex S14LE"; break;
+ case V4L2_SDR_FMT_RU12LE: descr = "Real U12LE"; break;
+
+ default:
+ /* Compressed formats */
+ flags = V4L2_FMT_FLAG_COMPRESSED;
+ switch (fmt->pixelformat) {
+ /* Max description length mask: descr = "0123456789012345678901234567890" */
+ case V4L2_PIX_FMT_MJPEG: descr = "Motion-JPEG"; break;
+ case V4L2_PIX_FMT_JPEG: descr = "JFIF JPEG"; break;
+ case V4L2_PIX_FMT_DV: descr = "1394"; break;
+ case V4L2_PIX_FMT_MPEG: descr = "MPEG-1/2/4"; break;
+ case V4L2_PIX_FMT_H264: descr = "H.264"; break;
+ case V4L2_PIX_FMT_H264_NO_SC: descr = "H.264 (No Start Codes)"; break;
+ case V4L2_PIX_FMT_H264_MVC: descr = "H.264 MVC"; break;
+ case V4L2_PIX_FMT_H263: descr = "H.263"; break;
+ case V4L2_PIX_FMT_MPEG1: descr = "MPEG-1 ES"; break;
+ case V4L2_PIX_FMT_MPEG2: descr = "MPEG-2 ES"; break;
+ case V4L2_PIX_FMT_MPEG4: descr = "MPEG-4 part 2 ES"; break;
+ case V4L2_PIX_FMT_XVID: descr = "Xvid"; break;
+ case V4L2_PIX_FMT_VC1_ANNEX_G: descr = "VC-1 (SMPTE 412M Annex G)"; break;
+ case V4L2_PIX_FMT_VC1_ANNEX_L: descr = "VC-1 (SMPTE 412M Annex L)"; break;
+ case V4L2_PIX_FMT_VP8: descr = "VP8"; break;
+ case V4L2_PIX_FMT_CPIA1: descr = "GSPCA CPiA YUV"; break;
+ case V4L2_PIX_FMT_WNVA: descr = "WNVA"; break;
+ case V4L2_PIX_FMT_SN9C10X: descr = "GSPCA SN9C10X"; break;
+ case V4L2_PIX_FMT_PWC1: descr = "Raw Philips Webcam Type (Old)"; break;
+ case V4L2_PIX_FMT_PWC2: descr = "Raw Philips Webcam Type (New)"; break;
+ case V4L2_PIX_FMT_ET61X251: descr = "GSPCA ET61X251"; break;
+ case V4L2_PIX_FMT_SPCA561: descr = "GSPCA SPCA561"; break;
+ case V4L2_PIX_FMT_PAC207: descr = "GSPCA PAC207"; break;
+ case V4L2_PIX_FMT_MR97310A: descr = "GSPCA MR97310A"; break;
+ case V4L2_PIX_FMT_JL2005BCD: descr = "GSPCA JL2005BCD"; break;
+ case V4L2_PIX_FMT_SN9C2028: descr = "GSPCA SN9C2028"; break;
+ case V4L2_PIX_FMT_SQ905C: descr = "GSPCA SQ905C"; break;
+ case V4L2_PIX_FMT_PJPG: descr = "GSPCA PJPG"; break;
+ case V4L2_PIX_FMT_OV511: descr = "GSPCA OV511"; break;
+ case V4L2_PIX_FMT_OV518: descr = "GSPCA OV518"; break;
+ case V4L2_PIX_FMT_JPGL: descr = "JPEG Lite"; break;
+ case V4L2_PIX_FMT_SE401: descr = "GSPCA SE401"; break;
+ case V4L2_PIX_FMT_S5C_UYVY_JPG: descr = "S5C73MX interleaved UYVY/JPEG"; break;
+ default:
+ WARN(1, "Unknown pixelformat 0x%08x\n", fmt->pixelformat);
+ if (fmt->description[0])
+ return;
+ flags = 0;
+ snprintf(fmt->description, sz, "%c%c%c%c%s",
+ (char)(fmt->pixelformat & 0x7f),
+ (char)((fmt->pixelformat >> 8) & 0x7f),
+ (char)((fmt->pixelformat >> 16) & 0x7f),
+ (char)((fmt->pixelformat >> 24) & 0x7f),
+ (fmt->pixelformat & (1 << 31)) ? "-BE" : "");
+ break;
+ }
+ }
+
+ if (descr)
+ WARN_ON(strlcpy(fmt->description, descr, sz) >= sz);
+ fmt->flags = flags;
+}
+
static int v4l_enum_fmt(const struct v4l2_ioctl_ops *ops,
struct file *file, void *fh, void *arg)
{
@@ -1112,34 +1297,48 @@ static int v4l_enum_fmt(const struct v4l2_ioctl_ops *ops,
bool is_sdr = vfd->vfl_type == VFL_TYPE_SDR;
bool is_rx = vfd->vfl_dir != VFL_DIR_TX;
bool is_tx = vfd->vfl_dir != VFL_DIR_RX;
+ int ret = -EINVAL;
switch (p->type) {
case V4L2_BUF_TYPE_VIDEO_CAPTURE:
if (unlikely(!is_rx || !is_vid || !ops->vidioc_enum_fmt_vid_cap))
break;
- return ops->vidioc_enum_fmt_vid_cap(file, fh, arg);
+ ret = ops->vidioc_enum_fmt_vid_cap(file, fh, arg);
+ break;
case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
if (unlikely(!is_rx || !is_vid || !ops->vidioc_enum_fmt_vid_cap_mplane))
break;
- return ops->vidioc_enum_fmt_vid_cap_mplane(file, fh, arg);
+ ret = ops->vidioc_enum_fmt_vid_cap_mplane(file, fh, arg);
+ break;
case V4L2_BUF_TYPE_VIDEO_OVERLAY:
if (unlikely(!is_rx || !is_vid || !ops->vidioc_enum_fmt_vid_overlay))
break;
- return ops->vidioc_enum_fmt_vid_overlay(file, fh, arg);
+ ret = ops->vidioc_enum_fmt_vid_overlay(file, fh, arg);
+ break;
case V4L2_BUF_TYPE_VIDEO_OUTPUT:
if (unlikely(!is_tx || !is_vid || !ops->vidioc_enum_fmt_vid_out))
break;
- return ops->vidioc_enum_fmt_vid_out(file, fh, arg);
+ ret = ops->vidioc_enum_fmt_vid_out(file, fh, arg);
+ break;
case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
if (unlikely(!is_tx || !is_vid || !ops->vidioc_enum_fmt_vid_out_mplane))
break;
- return ops->vidioc_enum_fmt_vid_out_mplane(file, fh, arg);
+ ret = ops->vidioc_enum_fmt_vid_out_mplane(file, fh, arg);
+ break;
case V4L2_BUF_TYPE_SDR_CAPTURE:
if (unlikely(!is_rx || !is_sdr || !ops->vidioc_enum_fmt_sdr_cap))
break;
- return ops->vidioc_enum_fmt_sdr_cap(file, fh, arg);
+ ret = ops->vidioc_enum_fmt_sdr_cap(file, fh, arg);
+ break;
+ case V4L2_BUF_TYPE_SDR_OUTPUT:
+ if (unlikely(!is_tx || !is_sdr || !ops->vidioc_enum_fmt_sdr_out))
+ break;
+ ret = ops->vidioc_enum_fmt_sdr_out(file, fh, arg);
+ break;
}
- return -EINVAL;
+ if (ret == 0)
+ v4l_fill_fmtdesc(p);
+ return ret;
}
static int v4l_g_fmt(const struct v4l2_ioctl_ops *ops,
@@ -1230,6 +1429,10 @@ static int v4l_g_fmt(const struct v4l2_ioctl_ops *ops,
if (unlikely(!is_rx || !is_sdr || !ops->vidioc_g_fmt_sdr_cap))
break;
return ops->vidioc_g_fmt_sdr_cap(file, fh, arg);
+ case V4L2_BUF_TYPE_SDR_OUTPUT:
+ if (unlikely(!is_tx || !is_sdr || !ops->vidioc_g_fmt_sdr_out))
+ break;
+ return ops->vidioc_g_fmt_sdr_out(file, fh, arg);
}
return -EINVAL;
}
@@ -1309,6 +1512,11 @@ static int v4l_s_fmt(const struct v4l2_ioctl_ops *ops,
break;
CLEAR_AFTER_FIELD(p, fmt.sdr);
return ops->vidioc_s_fmt_sdr_cap(file, fh, arg);
+ case V4L2_BUF_TYPE_SDR_OUTPUT:
+ if (unlikely(!is_tx || !is_sdr || !ops->vidioc_s_fmt_sdr_out))
+ break;
+ CLEAR_AFTER_FIELD(p, fmt.sdr);
+ return ops->vidioc_s_fmt_sdr_out(file, fh, arg);
}
return -EINVAL;
}
@@ -1388,6 +1596,11 @@ static int v4l_try_fmt(const struct v4l2_ioctl_ops *ops,
break;
CLEAR_AFTER_FIELD(p, fmt.sdr);
return ops->vidioc_try_fmt_sdr_cap(file, fh, arg);
+ case V4L2_BUF_TYPE_SDR_OUTPUT:
+ if (unlikely(!is_tx || !is_sdr || !ops->vidioc_try_fmt_sdr_out))
+ break;
+ CLEAR_AFTER_FIELD(p, fmt.sdr);
+ return ops->vidioc_try_fmt_sdr_out(file, fh, arg);
}
return -EINVAL;
}
@@ -1433,15 +1646,31 @@ static int v4l_s_tuner(const struct v4l2_ioctl_ops *ops,
static int v4l_g_modulator(const struct v4l2_ioctl_ops *ops,
struct file *file, void *fh, void *arg)
{
+ struct video_device *vfd = video_devdata(file);
struct v4l2_modulator *p = arg;
int err;
+ if (vfd->vfl_type == VFL_TYPE_RADIO)
+ p->type = V4L2_TUNER_RADIO;
+
err = ops->vidioc_g_modulator(file, fh, p);
if (!err)
p->capability |= V4L2_TUNER_CAP_FREQ_BANDS;
return err;
}
+static int v4l_s_modulator(const struct v4l2_ioctl_ops *ops,
+ struct file *file, void *fh, void *arg)
+{
+ struct video_device *vfd = video_devdata(file);
+ struct v4l2_modulator *p = arg;
+
+ if (vfd->vfl_type == VFL_TYPE_RADIO)
+ p->type = V4L2_TUNER_RADIO;
+
+ return ops->vidioc_s_modulator(file, fh, p);
+}
+
static int v4l_g_frequency(const struct v4l2_ioctl_ops *ops,
struct file *file, void *fh, void *arg)
{
@@ -1449,7 +1678,7 @@ static int v4l_g_frequency(const struct v4l2_ioctl_ops *ops,
struct v4l2_frequency *p = arg;
if (vfd->vfl_type == VFL_TYPE_SDR)
- p->type = V4L2_TUNER_ADC;
+ p->type = V4L2_TUNER_SDR;
else
p->type = (vfd->vfl_type == VFL_TYPE_RADIO) ?
V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV;
@@ -1464,7 +1693,7 @@ static int v4l_s_frequency(const struct v4l2_ioctl_ops *ops,
enum v4l2_tuner_type type;
if (vfd->vfl_type == VFL_TYPE_SDR) {
- if (p->type != V4L2_TUNER_ADC && p->type != V4L2_TUNER_RF)
+ if (p->type != V4L2_TUNER_SDR && p->type != V4L2_TUNER_RF)
return -EINVAL;
} else {
type = (vfd->vfl_type == VFL_TYPE_RADIO) ?
@@ -1618,6 +1847,8 @@ static int v4l_create_bufs(const struct v4l2_ioctl_ops *ops,
if (ret)
return ret;
+ CLEAR_AFTER_FIELD(create, format);
+
v4l_sanitize_format(&create->format);
ret = ops->vidioc_create_bufs(file, fh, create);
@@ -2087,7 +2318,7 @@ static int v4l_enum_freq_bands(const struct v4l2_ioctl_ops *ops,
int err;
if (vfd->vfl_type == VFL_TYPE_SDR) {
- if (p->type != V4L2_TUNER_ADC && p->type != V4L2_TUNER_RF)
+ if (p->type != V4L2_TUNER_SDR && p->type != V4L2_TUNER_RF)
return -EINVAL;
type = p->type;
} else {
@@ -2226,7 +2457,7 @@ static struct v4l2_ioctl_info v4l2_ioctls[] = {
IOCTL_INFO_STD(VIDIOC_G_AUDOUT, vidioc_g_audout, v4l_print_audioout, 0),
IOCTL_INFO_STD(VIDIOC_S_AUDOUT, vidioc_s_audout, v4l_print_audioout, INFO_FL_PRIO),
IOCTL_INFO_FNC(VIDIOC_G_MODULATOR, v4l_g_modulator, v4l_print_modulator, INFO_FL_CLEAR(v4l2_modulator, index)),
- IOCTL_INFO_STD(VIDIOC_S_MODULATOR, vidioc_s_modulator, v4l_print_modulator, INFO_FL_PRIO),
+ IOCTL_INFO_FNC(VIDIOC_S_MODULATOR, v4l_s_modulator, v4l_print_modulator, INFO_FL_PRIO),
IOCTL_INFO_FNC(VIDIOC_G_FREQUENCY, v4l_g_frequency, v4l_print_frequency, INFO_FL_CLEAR(v4l2_frequency, tuner)),
IOCTL_INFO_FNC(VIDIOC_S_FREQUENCY, v4l_s_frequency, v4l_print_frequency, INFO_FL_PRIO),
IOCTL_INFO_FNC(VIDIOC_CROPCAP, v4l_cropcap, v4l_print_cropcap, INFO_FL_CLEAR(v4l2_cropcap, type)),
@@ -2354,7 +2585,7 @@ static long __video_do_ioctl(struct file *file,
if (v4l2_is_known_ioctl(cmd)) {
info = &v4l2_ioctls[_IOC_NR(cmd)];
- if (!test_bit(_IOC_NR(cmd), vfd->valid_ioctls) &&
+ if (!test_bit(_IOC_NR(cmd), vfd->valid_ioctls) &&
!((info->flags & INFO_FL_CTRL) && vfh && vfh->ctrl_handler))
goto done;