Merge tag 'dm-4.9-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/device...
[cascardo/linux.git] / drivers / media / v4l2-core / v4l2-ioctl.c
index 51a0fa1..c52d94c 100644 (file)
@@ -924,6 +924,7 @@ static int check_fmt(struct file *file, enum v4l2_buf_type type)
        bool is_vid = vfd->vfl_type == VFL_TYPE_GRABBER;
        bool is_vbi = vfd->vfl_type == VFL_TYPE_VBI;
        bool is_sdr = vfd->vfl_type == VFL_TYPE_SDR;
+       bool is_tch = vfd->vfl_type == VFL_TYPE_TOUCH;
        bool is_rx = vfd->vfl_dir != VFL_DIR_TX;
        bool is_tx = vfd->vfl_dir != VFL_DIR_RX;
 
@@ -932,7 +933,7 @@ static int check_fmt(struct file *file, enum v4l2_buf_type type)
 
        switch (type) {
        case V4L2_BUF_TYPE_VIDEO_CAPTURE:
-               if (is_vid && is_rx &&
+               if ((is_vid || is_tch) && is_rx &&
                    (ops->vidioc_g_fmt_vid_cap || ops->vidioc_g_fmt_vid_cap_mplane))
                        return 0;
                break;
@@ -1243,6 +1244,10 @@ static void v4l_fill_fmtdesc(struct v4l2_fmtdesc *fmt)
        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;
+       case V4L2_TCH_FMT_DELTA_TD16:   descr = "16-bit signed deltas"; break;
+       case V4L2_TCH_FMT_DELTA_TD08:   descr = "8-bit signed deltas"; break;
+       case V4L2_TCH_FMT_TU16:         descr = "16-bit unsigned touch data"; break;
+       case V4L2_TCH_FMT_TU08:         descr = "8-bit unsigned touch data"; break;
 
        default:
                /* Compressed formats */
@@ -1309,13 +1314,14 @@ static int v4l_enum_fmt(const struct v4l2_ioctl_ops *ops,
        struct video_device *vfd = video_devdata(file);
        bool is_vid = vfd->vfl_type == VFL_TYPE_GRABBER;
        bool is_sdr = vfd->vfl_type == VFL_TYPE_SDR;
+       bool is_tch = vfd->vfl_type == VFL_TYPE_TOUCH;
        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))
+               if (unlikely(!is_rx || (!is_vid && !is_tch) || !ops->vidioc_enum_fmt_vid_cap))
                        break;
                ret = ops->vidioc_enum_fmt_vid_cap(file, fh, arg);
                break;
@@ -1362,6 +1368,7 @@ static int v4l_g_fmt(const struct v4l2_ioctl_ops *ops,
        struct video_device *vfd = video_devdata(file);
        bool is_vid = vfd->vfl_type == VFL_TYPE_GRABBER;
        bool is_sdr = vfd->vfl_type == VFL_TYPE_SDR;
+       bool is_tch = vfd->vfl_type == VFL_TYPE_TOUCH;
        bool is_rx = vfd->vfl_dir != VFL_DIR_TX;
        bool is_tx = vfd->vfl_dir != VFL_DIR_RX;
        int ret;
@@ -1392,7 +1399,7 @@ static int v4l_g_fmt(const struct v4l2_ioctl_ops *ops,
 
        switch (p->type) {
        case V4L2_BUF_TYPE_VIDEO_CAPTURE:
-               if (unlikely(!is_rx || !is_vid || !ops->vidioc_g_fmt_vid_cap))
+               if (unlikely(!is_rx || (!is_vid && !is_tch) || !ops->vidioc_g_fmt_vid_cap))
                        break;
                p->fmt.pix.priv = V4L2_PIX_FMT_PRIV_MAGIC;
                ret = ops->vidioc_g_fmt_vid_cap(file, fh, arg);
@@ -1451,6 +1458,21 @@ static int v4l_g_fmt(const struct v4l2_ioctl_ops *ops,
        return -EINVAL;
 }
 
+static void v4l_pix_format_touch(struct v4l2_pix_format *p)
+{
+       /*
+        * The v4l2_pix_format structure contains fields that make no sense for
+        * touch. Set them to default values in this case.
+        */
+
+       p->field = V4L2_FIELD_NONE;
+       p->colorspace = V4L2_COLORSPACE_RAW;
+       p->flags = 0;
+       p->ycbcr_enc = 0;
+       p->quantization = 0;
+       p->xfer_func = 0;
+}
+
 static int v4l_s_fmt(const struct v4l2_ioctl_ops *ops,
                                struct file *file, void *fh, void *arg)
 {
@@ -1458,6 +1480,7 @@ static int v4l_s_fmt(const struct v4l2_ioctl_ops *ops,
        struct video_device *vfd = video_devdata(file);
        bool is_vid = vfd->vfl_type == VFL_TYPE_GRABBER;
        bool is_sdr = vfd->vfl_type == VFL_TYPE_SDR;
+       bool is_tch = vfd->vfl_type == VFL_TYPE_TOUCH;
        bool is_rx = vfd->vfl_dir != VFL_DIR_TX;
        bool is_tx = vfd->vfl_dir != VFL_DIR_RX;
        int ret;
@@ -1469,17 +1492,19 @@ static int v4l_s_fmt(const struct v4l2_ioctl_ops *ops,
 
        switch (p->type) {
        case V4L2_BUF_TYPE_VIDEO_CAPTURE:
-               if (unlikely(!is_rx || !is_vid || !ops->vidioc_s_fmt_vid_cap))
+               if (unlikely(!is_rx || (!is_vid && !is_tch) || !ops->vidioc_s_fmt_vid_cap))
                        break;
                CLEAR_AFTER_FIELD(p, fmt.pix);
                ret = ops->vidioc_s_fmt_vid_cap(file, fh, arg);
                /* just in case the driver zeroed it again */
                p->fmt.pix.priv = V4L2_PIX_FMT_PRIV_MAGIC;
+               if (is_tch)
+                       v4l_pix_format_touch(&p->fmt.pix);
                return ret;
        case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
                if (unlikely(!is_rx || !is_vid || !ops->vidioc_s_fmt_vid_cap_mplane))
                        break;
-               CLEAR_AFTER_FIELD(p, fmt.pix_mp);
+               CLEAR_AFTER_FIELD(p, fmt.pix_mp.xfer_func);
                return ops->vidioc_s_fmt_vid_cap_mplane(file, fh, arg);
        case V4L2_BUF_TYPE_VIDEO_OVERLAY:
                if (unlikely(!is_rx || !is_vid || !ops->vidioc_s_fmt_vid_overlay))
@@ -1507,7 +1532,7 @@ static int v4l_s_fmt(const struct v4l2_ioctl_ops *ops,
        case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
                if (unlikely(!is_tx || !is_vid || !ops->vidioc_s_fmt_vid_out_mplane))
                        break;
-               CLEAR_AFTER_FIELD(p, fmt.pix_mp);
+               CLEAR_AFTER_FIELD(p, fmt.pix_mp.xfer_func);
                return ops->vidioc_s_fmt_vid_out_mplane(file, fh, arg);
        case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
                if (unlikely(!is_tx || !is_vid || !ops->vidioc_s_fmt_vid_out_overlay))
@@ -1545,6 +1570,7 @@ static int v4l_try_fmt(const struct v4l2_ioctl_ops *ops,
        struct video_device *vfd = video_devdata(file);
        bool is_vid = vfd->vfl_type == VFL_TYPE_GRABBER;
        bool is_sdr = vfd->vfl_type == VFL_TYPE_SDR;
+       bool is_tch = vfd->vfl_type == VFL_TYPE_TOUCH;
        bool is_rx = vfd->vfl_dir != VFL_DIR_TX;
        bool is_tx = vfd->vfl_dir != VFL_DIR_RX;
        int ret;
@@ -1553,7 +1579,7 @@ static int v4l_try_fmt(const struct v4l2_ioctl_ops *ops,
 
        switch (p->type) {
        case V4L2_BUF_TYPE_VIDEO_CAPTURE:
-               if (unlikely(!is_rx || !is_vid || !ops->vidioc_try_fmt_vid_cap))
+               if (unlikely(!is_rx || (!is_vid && !is_tch) || !ops->vidioc_try_fmt_vid_cap))
                        break;
                CLEAR_AFTER_FIELD(p, fmt.pix);
                ret = ops->vidioc_try_fmt_vid_cap(file, fh, arg);
@@ -1563,7 +1589,7 @@ static int v4l_try_fmt(const struct v4l2_ioctl_ops *ops,
        case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
                if (unlikely(!is_rx || !is_vid || !ops->vidioc_try_fmt_vid_cap_mplane))
                        break;
-               CLEAR_AFTER_FIELD(p, fmt.pix_mp);
+               CLEAR_AFTER_FIELD(p, fmt.pix_mp.xfer_func);
                return ops->vidioc_try_fmt_vid_cap_mplane(file, fh, arg);
        case V4L2_BUF_TYPE_VIDEO_OVERLAY:
                if (unlikely(!is_rx || !is_vid || !ops->vidioc_try_fmt_vid_overlay))
@@ -1591,7 +1617,7 @@ static int v4l_try_fmt(const struct v4l2_ioctl_ops *ops,
        case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
                if (unlikely(!is_tx || !is_vid || !ops->vidioc_try_fmt_vid_out_mplane))
                        break;
-               CLEAR_AFTER_FIELD(p, fmt.pix_mp);
+               CLEAR_AFTER_FIELD(p, fmt.pix_mp.xfer_func);
                return ops->vidioc_try_fmt_vid_out_mplane(file, fh, arg);
        case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
                if (unlikely(!is_tx || !is_vid || !ops->vidioc_try_fmt_vid_out_overlay))