summaryrefslogtreecommitdiff
path: root/drivers/media/i2c
diff options
context:
space:
mode:
authorHans Verkuil <hans.verkuil@cisco.com>2014-11-07 09:34:57 -0300
committerMauro Carvalho Chehab <mchehab@osg.samsung.com>2014-11-11 09:02:05 -0200
commitdd9ac11aefd8f9286d3bc8988ca5a052312c3de6 (patch)
tree9078b4a81396f93c5faef87b3a7104249365cdd6 /drivers/media/i2c
parentc81285ae4780e5df83f191f545c156435fdb01ba (diff)
[media] adv7604: Correct G/S_EDID behaviour
In order to have v4l2-compliance tool pass the G/S_EDID some modifications where needed in the driver. In particular, the edid.reserved zone must be blanked. Based on a patch from Jean-Michel Hautbois <jean-michel.hautbois@vodalys.com>, but reworked it a bit. It should use 'data' (which depends on edid.present) instead of edid.blocks as the check whether edid data is present. Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@osg.samsung.com>
Diffstat (limited to 'drivers/media/i2c')
-rw-r--r--drivers/media/i2c/adv7604.c37
1 files changed, 18 insertions, 19 deletions
diff --git a/drivers/media/i2c/adv7604.c b/drivers/media/i2c/adv7604.c
index 47795ff71688..22e550acd233 100644
--- a/drivers/media/i2c/adv7604.c
+++ b/drivers/media/i2c/adv7604.c
@@ -1997,19 +1997,7 @@ static int adv7604_get_edid(struct v4l2_subdev *sd, struct v4l2_edid *edid)
struct adv7604_state *state = to_state(sd);
u8 *data = NULL;
- if (edid->pad > ADV7604_PAD_HDMI_PORT_D)
- 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;
-
- if (edid->blocks > state->edid.blocks)
- edid->blocks = state->edid.blocks;
+ memset(edid->reserved, 0, sizeof(edid->reserved));
switch (edid->pad) {
case ADV7604_PAD_HDMI_PORT_A:
@@ -2021,14 +2009,24 @@ static int adv7604_get_edid(struct v4l2_subdev *sd, struct v4l2_edid *edid)
break;
default:
return -EINVAL;
- break;
}
- if (!data)
+
+ if (edid->start_block == 0 && edid->blocks == 0) {
+ edid->blocks = data ? state->edid.blocks : 0;
+ return 0;
+ }
+
+ if (data == NULL)
return -ENODATA;
- memcpy(edid->edid,
- data + edid->start_block * 128,
- edid->blocks * 128);
+ if (edid->start_block >= state->edid.blocks)
+ return -EINVAL;
+
+ if (edid->start_block + edid->blocks > state->edid.blocks)
+ edid->blocks = state->edid.blocks - edid->start_block;
+
+ memcpy(edid->edid, data + edid->start_block * 128, edid->blocks * 128);
+
return 0;
}
@@ -2068,6 +2066,8 @@ static int adv7604_set_edid(struct v4l2_subdev *sd, struct v4l2_edid *edid)
int err;
int i;
+ memset(edid->reserved, 0, sizeof(edid->reserved));
+
if (edid->pad > ADV7604_PAD_HDMI_PORT_D)
return -EINVAL;
if (edid->start_block != 0)
@@ -2164,7 +2164,6 @@ static int adv7604_set_edid(struct v4l2_subdev *sd, struct v4l2_edid *edid)
return -EIO;
}
-
/* enable hotplug after 100 ms */
queue_delayed_work(state->work_queues,
&state->delayed_work_enable_hotplug, HZ / 10);