requested_sizes[0] = f->fmt.sdr.buffersize;
                break;
        case V4L2_BUF_TYPE_META_CAPTURE:
+       case V4L2_BUF_TYPE_META_OUTPUT:
                requested_sizes[0] = f->fmt.meta.buffersize;
                break;
        default:
 
                return copy_in_user(&p64->fmt.sdr, &p32->fmt.sdr,
                                    sizeof(p64->fmt.sdr)) ? -EFAULT : 0;
        case V4L2_BUF_TYPE_META_CAPTURE:
+       case V4L2_BUF_TYPE_META_OUTPUT:
                return copy_in_user(&p64->fmt.meta, &p32->fmt.meta,
                                    sizeof(p64->fmt.meta)) ? -EFAULT : 0;
        default:
                return copy_in_user(&p32->fmt.sdr, &p64->fmt.sdr,
                                    sizeof(p64->fmt.sdr)) ? -EFAULT : 0;
        case V4L2_BUF_TYPE_META_CAPTURE:
+       case V4L2_BUF_TYPE_META_OUTPUT:
                return copy_in_user(&p32->fmt.meta, &p64->fmt.meta,
                                    sizeof(p64->fmt.meta)) ? -EFAULT : 0;
        default:
 
                               ops->vidioc_enum_fmt_vid_overlay ||
                               ops->vidioc_enum_fmt_meta_cap)) ||
                    (is_tx && (ops->vidioc_enum_fmt_vid_out ||
-                              ops->vidioc_enum_fmt_vid_out_mplane)))
+                              ops->vidioc_enum_fmt_vid_out_mplane ||
+                              ops->vidioc_enum_fmt_meta_out)))
                        set_bit(_IOC_NR(VIDIOC_ENUM_FMT), valid_ioctls);
                if ((is_rx && (ops->vidioc_g_fmt_vid_cap ||
                               ops->vidioc_g_fmt_vid_cap_mplane ||
                               ops->vidioc_g_fmt_meta_cap)) ||
                    (is_tx && (ops->vidioc_g_fmt_vid_out ||
                               ops->vidioc_g_fmt_vid_out_mplane ||
-                              ops->vidioc_g_fmt_vid_out_overlay)))
+                              ops->vidioc_g_fmt_vid_out_overlay ||
+                              ops->vidioc_g_fmt_meta_out)))
                         set_bit(_IOC_NR(VIDIOC_G_FMT), valid_ioctls);
                if ((is_rx && (ops->vidioc_s_fmt_vid_cap ||
                               ops->vidioc_s_fmt_vid_cap_mplane ||
                               ops->vidioc_s_fmt_meta_cap)) ||
                    (is_tx && (ops->vidioc_s_fmt_vid_out ||
                               ops->vidioc_s_fmt_vid_out_mplane ||
-                              ops->vidioc_s_fmt_vid_out_overlay)))
+                              ops->vidioc_s_fmt_vid_out_overlay ||
+                              ops->vidioc_s_fmt_meta_out)))
                         set_bit(_IOC_NR(VIDIOC_S_FMT), valid_ioctls);
                if ((is_rx && (ops->vidioc_try_fmt_vid_cap ||
                               ops->vidioc_try_fmt_vid_cap_mplane ||
                               ops->vidioc_try_fmt_meta_cap)) ||
                    (is_tx && (ops->vidioc_try_fmt_vid_out ||
                               ops->vidioc_try_fmt_vid_out_mplane ||
-                              ops->vidioc_try_fmt_vid_out_overlay)))
+                              ops->vidioc_try_fmt_vid_out_overlay ||
+                              ops->vidioc_try_fmt_meta_out)))
                         set_bit(_IOC_NR(VIDIOC_TRY_FMT), valid_ioctls);
                SET_VALID_IOCTL(ops, VIDIOC_OVERLAY, vidioc_overlay);
                SET_VALID_IOCTL(ops, VIDIOC_G_FBUF, vidioc_g_fbuf);
 
        [V4L2_BUF_TYPE_SDR_CAPTURE]        = "sdr-cap",
        [V4L2_BUF_TYPE_SDR_OUTPUT]         = "sdr-out",
        [V4L2_BUF_TYPE_META_CAPTURE]       = "meta-cap",
+       [V4L2_BUF_TYPE_META_OUTPUT]        = "meta-out",
 };
 EXPORT_SYMBOL(v4l2_type_names);
 
                        (sdr->pixelformat >> 24) & 0xff);
                break;
        case V4L2_BUF_TYPE_META_CAPTURE:
+       case V4L2_BUF_TYPE_META_OUTPUT:
                meta = &p->fmt.meta;
                pr_cont(", dataformat=%c%c%c%c, buffersize=%u\n",
                        (meta->dataformat >>  0) & 0xff,
                if (is_vid && is_rx && ops->vidioc_g_fmt_meta_cap)
                        return 0;
                break;
+       case V4L2_BUF_TYPE_META_OUTPUT:
+               if (is_vid && is_tx && ops->vidioc_g_fmt_meta_out)
+                       return 0;
+               break;
        default:
                break;
        }
                        break;
                ret = ops->vidioc_enum_fmt_meta_cap(file, fh, arg);
                break;
+       case V4L2_BUF_TYPE_META_OUTPUT:
+               if (unlikely(!ops->vidioc_enum_fmt_meta_out))
+                       break;
+               ret = ops->vidioc_enum_fmt_meta_out(file, fh, arg);
+               break;
        }
        if (ret == 0)
                v4l_fill_fmtdesc(p);
                return ops->vidioc_g_fmt_sdr_out(file, fh, arg);
        case V4L2_BUF_TYPE_META_CAPTURE:
                return ops->vidioc_g_fmt_meta_cap(file, fh, arg);
+       case V4L2_BUF_TYPE_META_OUTPUT:
+               return ops->vidioc_g_fmt_meta_out(file, fh, arg);
        }
        return -EINVAL;
 }
                        break;
                CLEAR_AFTER_FIELD(p, fmt.meta);
                return ops->vidioc_s_fmt_meta_cap(file, fh, arg);
+       case V4L2_BUF_TYPE_META_OUTPUT:
+               if (unlikely(!ops->vidioc_s_fmt_meta_out))
+                       break;
+               CLEAR_AFTER_FIELD(p, fmt.meta);
+               return ops->vidioc_s_fmt_meta_out(file, fh, arg);
        }
        return -EINVAL;
 }
                        break;
                CLEAR_AFTER_FIELD(p, fmt.meta);
                return ops->vidioc_try_fmt_meta_cap(file, fh, arg);
+       case V4L2_BUF_TYPE_META_OUTPUT:
+               if (unlikely(!ops->vidioc_try_fmt_meta_out))
+                       break;
+               CLEAR_AFTER_FIELD(p, fmt.meta);
+               return ops->vidioc_try_fmt_meta_out(file, fh, arg);
        }
        return -EINVAL;
 }
 
  * @vidioc_enum_fmt_meta_cap: pointer to the function that implements
  *     :ref:`VIDIOC_ENUM_FMT <vidioc_enum_fmt>` ioctl logic
  *     for metadata capture
+ * @vidioc_enum_fmt_meta_out: pointer to the function that implements
+ *     :ref:`VIDIOC_ENUM_FMT <vidioc_enum_fmt>` ioctl logic
+ *     for metadata output
  * @vidioc_g_fmt_vid_cap: pointer to the function that implements
  *     :ref:`VIDIOC_G_FMT <vidioc_g_fmt>` ioctl logic for video capture
  *     in single plane mode
  *     Radio output
  * @vidioc_g_fmt_meta_cap: pointer to the function that implements
  *     :ref:`VIDIOC_G_FMT <vidioc_g_fmt>` ioctl logic for metadata capture
+ * @vidioc_g_fmt_meta_out: pointer to the function that implements
+ *     :ref:`VIDIOC_G_FMT <vidioc_g_fmt>` ioctl logic for metadata output
  * @vidioc_s_fmt_vid_cap: pointer to the function that implements
  *     :ref:`VIDIOC_S_FMT <vidioc_g_fmt>` ioctl logic for video capture
  *     in single plane mode
  *     Radio output
  * @vidioc_s_fmt_meta_cap: pointer to the function that implements
  *     :ref:`VIDIOC_S_FMT <vidioc_g_fmt>` ioctl logic for metadata capture
+ * @vidioc_s_fmt_meta_out: pointer to the function that implements
+ *     :ref:`VIDIOC_S_FMT <vidioc_g_fmt>` ioctl logic for metadata output
  * @vidioc_try_fmt_vid_cap: pointer to the function that implements
  *     :ref:`VIDIOC_TRY_FMT <vidioc_g_fmt>` ioctl logic for video capture
  *     in single plane mode
  *     Radio output
  * @vidioc_try_fmt_meta_cap: pointer to the function that implements
  *     :ref:`VIDIOC_TRY_FMT <vidioc_g_fmt>` ioctl logic for metadata capture
+ * @vidioc_try_fmt_meta_out: pointer to the function that implements
+ *     :ref:`VIDIOC_TRY_FMT <vidioc_g_fmt>` ioctl logic for metadata output
  * @vidioc_reqbufs: pointer to the function that implements
  *     :ref:`VIDIOC_REQBUFS <vidioc_reqbufs>` ioctl
  * @vidioc_querybuf: pointer to the function that implements
                                       struct v4l2_fmtdesc *f);
        int (*vidioc_enum_fmt_meta_cap)(struct file *file, void *fh,
                                        struct v4l2_fmtdesc *f);
+       int (*vidioc_enum_fmt_meta_out)(struct file *file, void *fh,
+                                       struct v4l2_fmtdesc *f);
 
        /* VIDIOC_G_FMT handlers */
        int (*vidioc_g_fmt_vid_cap)(struct file *file, void *fh,
                                    struct v4l2_format *f);
        int (*vidioc_g_fmt_meta_cap)(struct file *file, void *fh,
                                     struct v4l2_format *f);
+       int (*vidioc_g_fmt_meta_out)(struct file *file, void *fh,
+                                    struct v4l2_format *f);
 
        /* VIDIOC_S_FMT handlers */
        int (*vidioc_s_fmt_vid_cap)(struct file *file, void *fh,
                                    struct v4l2_format *f);
        int (*vidioc_s_fmt_meta_cap)(struct file *file, void *fh,
                                     struct v4l2_format *f);
+       int (*vidioc_s_fmt_meta_out)(struct file *file, void *fh,
+                                    struct v4l2_format *f);
 
        /* VIDIOC_TRY_FMT handlers */
        int (*vidioc_try_fmt_vid_cap)(struct file *file, void *fh,
                                      struct v4l2_format *f);
        int (*vidioc_try_fmt_meta_cap)(struct file *file, void *fh,
                                       struct v4l2_format *f);
+       int (*vidioc_try_fmt_meta_out)(struct file *file, void *fh,
+                                      struct v4l2_format *f);
 
        /* Buffer handlers */
        int (*vidioc_reqbufs)(struct file *file, void *fh,
 
        V4L2_BUF_TYPE_SDR_CAPTURE          = 11,
        V4L2_BUF_TYPE_SDR_OUTPUT           = 12,
        V4L2_BUF_TYPE_META_CAPTURE         = 13,
+       V4L2_BUF_TYPE_META_OUTPUT          = 14,
        /* Deprecated, do not use */
        V4L2_BUF_TYPE_PRIVATE              = 0x80,
 };
 #define V4L2_CAP_READWRITE              0x01000000  /* read/write systemcalls */
 #define V4L2_CAP_ASYNCIO                0x02000000  /* async I/O */
 #define V4L2_CAP_STREAMING              0x04000000  /* streaming I/O ioctls */
+#define V4L2_CAP_META_OUTPUT           0x08000000  /* Is a metadata output device */
 
 #define V4L2_CAP_TOUCH                  0x10000000  /* Is a touch device */