[media] adv7842: fix G/S_EDID behavior
authorHans Verkuil <hans.verkuil@cisco.com>
Fri, 7 Nov 2014 12:34:55 +0000 (09:34 -0300)
committerMauro Carvalho Chehab <mchehab@osg.samsung.com>
Tue, 11 Nov 2014 10:57:43 +0000 (08:57 -0200)
Make this pass the v4l2-compliance test.

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

index 48b628bc6714ecae53144f4bf90fa64d0454c90e..bed0586f72eb9321016f98e733ab6eb084d69f8f 100644 (file)
@@ -2028,16 +2028,7 @@ static int adv7842_get_edid(struct v4l2_subdev *sd, struct v4l2_edid *edid)
        struct adv7842_state *state = to_state(sd);
        u8 *data = NULL;
 
-       if (edid->pad > ADV7842_EDID_PORT_VGA)
-               return -EINVAL;
-       if (edid->blocks == 0)
-               return -EINVAL;
-       if (edid->blocks > 2)
-               return -EINVAL;
-       if (edid->start_block > 1)
-               return -EINVAL;
-       if (edid->start_block == 1)
-               edid->blocks = 1;
+       memset(edid->reserved, 0, sizeof(edid->reserved));
 
        switch (edid->pad) {
        case ADV7842_EDID_PORT_A:
@@ -2052,12 +2043,23 @@ static int adv7842_get_edid(struct v4l2_subdev *sd, struct v4l2_edid *edid)
        default:
                return -EINVAL;
        }
+
+       if (edid->start_block == 0 && edid->blocks == 0) {
+               edid->blocks = data ? 2 : 0;
+               return 0;
+       }
+
        if (!data)
                return -ENODATA;
 
-       memcpy(edid->edid,
-              data + edid->start_block * 128,
-              edid->blocks * 128);
+       if (edid->start_block >= 2)
+               return -EINVAL;
+
+       if (edid->start_block + edid->blocks > 2)
+               edid->blocks = 2 - edid->start_block;
+
+       memcpy(edid->edid, data + edid->start_block * 128, edid->blocks * 128);
+
        return 0;
 }
 
@@ -2066,12 +2068,16 @@ static int adv7842_set_edid(struct v4l2_subdev *sd, struct v4l2_edid *e)
        struct adv7842_state *state = to_state(sd);
        int err = 0;
 
+       memset(e->reserved, 0, sizeof(e->reserved));
+
        if (e->pad > ADV7842_EDID_PORT_VGA)
                return -EINVAL;
        if (e->start_block != 0)
                return -EINVAL;
-       if (e->blocks > 2)
+       if (e->blocks > 2) {
+               e->blocks = 2;
                return -E2BIG;
+       }
 
        /* todo, per edid */
        state->aspect_ratio = v4l2_calc_aspect_ratio(e->edid[0x15],