[media] adv7511: fix G/S_EDID behavior
authorHans Verkuil <hans.verkuil@cisco.com>
Fri, 7 Nov 2014 12:34:56 +0000 (09:34 -0300)
committerMauro Carvalho Chehab <mchehab@osg.samsung.com>
Tue, 11 Nov 2014 10:58:25 +0000 (08:58 -0200)
This fixes the v4l2-compliance failures.

Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@osg.samsung.com>
drivers/media/i2c/adv7511.c

index f98acf4..8acc8c5 100644 (file)
@@ -779,21 +779,28 @@ static int adv7511_get_edid(struct v4l2_subdev *sd, struct v4l2_edid *edid)
 {
        struct adv7511_state *state = get_adv7511_state(sd);
 
+       memset(edid->reserved, 0, sizeof(edid->reserved));
+
        if (edid->pad != 0)
                return -EINVAL;
-       if ((edid->blocks == 0) || (edid->blocks > 256))
-               return -EINVAL;
-       if (!state->edid.segments) {
-               v4l2_dbg(1, debug, sd, "EDID segment 0 not found\n");
-               return -ENODATA;
+
+       if (edid->start_block == 0 && edid->blocks == 0) {
+               edid->blocks = state->edid.segments * 2;
+               return 0;
        }
+
+       if (state->edid.segments == 0)
+               return -ENODATA;
+
        if (edid->start_block >= state->edid.segments * 2)
-               return -E2BIG;
-       if ((edid->blocks + edid->start_block) >= state->edid.segments * 2)
+               return -EINVAL;
+
+       if (edid->start_block + edid->blocks > state->edid.segments * 2)
                edid->blocks = state->edid.segments * 2 - edid->start_block;
 
        memcpy(edid->edid, &state->edid.data[edid->start_block * 128],
                        128 * edid->blocks);
+
        return 0;
 }