These changes are the raw update to linux-4.4.6-rt14. Kernel sources
[kvmfornfv.git] / kernel / drivers / media / v4l2-core / v4l2-ioctl.c
index aa407cb..7486af2 100644 (file)
@@ -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;