v4l2-compliance: add G/S_EDID tests.
authorHans Verkuil <hans.verkuil@cisco.com>
Fri, 14 Mar 2014 14:56:05 +0000 (15:56 +0100)
committerHans Verkuil <hans.verkuil@cisco.com>
Fri, 14 Mar 2014 14:56:05 +0000 (15:56 +0100)
Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
utils/v4l2-compliance/v4l2-compliance.cpp
utils/v4l2-compliance/v4l2-compliance.h
utils/v4l2-compliance/v4l2-test-io-config.cpp

index 285ddbd..34ef0d3 100644 (file)
@@ -824,6 +824,7 @@ int main(int argc, char **argv)
        printf("\ttest VIDIOC_ENUM/G/S/QUERY_STD: %s\n", ok(testStd(&node)));
        printf("\ttest VIDIOC_ENUM/G/S/QUERY_DV_TIMINGS: %s\n", ok(testTimings(&node)));
        printf("\ttest VIDIOC_DV_TIMINGS_CAP: %s\n", ok(testTimingsCap(&node)));
+       printf("\ttest VIDIOC_G/S_EDID: %s\n", ok(testEdid(&node)));
        printf("\n");
 
        /* Format ioctls */
index 2906f49..0802298 100644 (file)
@@ -186,6 +186,7 @@ int testJpegComp(struct node *node);
 int testStd(struct node *node);
 int testTimings(struct node *node);
 int testTimingsCap(struct node *node);
+int testEdid(struct node *node);
 
 // Format ioctl tests
 int testEnumFormats(struct node *node);
index da29a03..eeb2877 100644 (file)
@@ -234,7 +234,7 @@ int testTimings(struct node *node)
                if (input.capabilities & V4L2_IN_CAP_DV_TIMINGS)
                        has_timings = true;
                if (checkTimings(node, input.capabilities & V4L2_IN_CAP_DV_TIMINGS, true))
-                       return fail("Timings failed for input %d.\n", i);
+                       return fail("Timings check failed for input %d.\n", i);
        }
 
        for (o = 0; o < node->outputs; o++) {
@@ -318,3 +318,99 @@ int testTimingsCap(struct node *node)
        }
        return has_timings ? 0 : ENOTTY;
 }
+
+static int checkEdid(struct node *node, unsigned pad, bool is_input)
+{
+       struct v4l2_edid edid;
+       __u8 data[256 * 128];
+       unsigned blocks;
+       int ret;
+
+       memset(edid.reserved, 0xff, sizeof(edid.reserved));
+       edid.pad = pad;
+       edid.start_block = 0;
+       edid.blocks = 0;
+       edid.edid = (__u8 *)0xdeadbeef;
+       ret = doioctl(node, VIDIOC_G_EDID, &edid);
+       if (ret == ENOTTY) {
+               memset(&edid, 0, sizeof(edid));
+               edid.pad = pad;
+               fail_on_test(doioctl(node, VIDIOC_S_EDID, &edid) != ENOTTY);
+               return 0;
+       }
+       fail_on_test(ret);
+       fail_on_test(check_0(edid.reserved, sizeof(edid.reserved)));
+       fail_on_test(edid.start_block);
+       fail_on_test(edid.blocks > 256);
+       blocks = edid.blocks;
+       edid.edid = data;
+       fail_on_test(doioctl(node, VIDIOC_G_EDID, &edid));
+       fail_on_test(edid.blocks != blocks);
+       edid.start_block = edid.blocks ? edid.blocks : 1;
+       ret = doioctl(node, VIDIOC_G_EDID, &edid);
+       fail_on_test(ret != EINVAL && ret != ENODATA);
+       if (blocks > 1) {
+               edid.start_block = 1;
+               edid.blocks = blocks;
+               fail_on_test(doioctl(node, VIDIOC_G_EDID, &edid));
+               fail_on_test(edid.blocks != blocks - 1);
+       }
+       edid.start_block = 0;
+       edid.blocks = 256;
+       ret = doioctl(node, VIDIOC_G_EDID, &edid);
+       fail_on_test(ret && ret != ENODATA);
+       if (!ret)
+               fail_on_test(edid.blocks != blocks);
+
+       memset(edid.reserved, 0xff, sizeof(edid.reserved));
+       edid.blocks = blocks;
+       ret = doioctl(node, VIDIOC_S_EDID, &edid);
+       if (ret == ENOTTY)
+               return 0;
+       fail_on_test(!is_input);
+       fail_on_test(ret);
+       fail_on_test(check_0(edid.reserved, sizeof(edid.reserved)));
+       return 0;
+}
+
+int testEdid(struct node *node)
+{
+       bool has_edid = false;
+       unsigned i, o;
+       int ret;
+
+       for (i = 0; i < node->inputs; i++) {
+               struct v4l2_input input;
+
+               input.index = i;
+               ret = doioctl(node, VIDIOC_ENUMINPUT, &input);
+               if (ret)
+                       return fail("could not enumerate input %d?!\n", i);
+               ret = doioctl(node, VIDIOC_S_INPUT, &input.index);
+               if (ret)
+                       return fail("could not select input %d.\n", i);
+               if (input.capabilities & V4L2_IN_CAP_DV_TIMINGS) {
+                       if (checkEdid(node, i, true))
+                               return fail("EDID check failed for input %d.\n", i);
+                       has_edid = true;
+               }
+       }
+
+       for (o = 0; o < node->outputs; o++) {
+               struct v4l2_output output;
+
+               output.index = o;
+               ret = doioctl(node, VIDIOC_ENUMOUTPUT, &output);
+               if (ret)
+                       return fail("could not enumerate output %d?!\n", o);
+               ret = doioctl(node, VIDIOC_S_OUTPUT, &output.index);
+               if (ret)
+                       return fail("could not select output %d.\n", o);
+               if (output.capabilities & V4L2_OUT_CAP_DV_TIMINGS) {
+                       if (checkEdid(node, o, false))
+                               return fail("EDID check failed for output %d.\n", o);
+                       has_edid = true;
+               }
+       }
+       return has_edid ? 0 : ENOTTY;
+}