diff options
author | Hans Verkuil <hans.verkuil@cisco.com> | 2014-11-07 09:34:57 -0300 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@osg.samsung.com> | 2014-11-11 09:02:05 -0200 |
commit | dd9ac11aefd8f9286d3bc8988ca5a052312c3de6 (patch) | |
tree | 9078b4a81396f93c5faef87b3a7104249365cdd6 /drivers/media/i2c | |
parent | c81285ae4780e5df83f191f545c156435fdb01ba (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.c | 37 |
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); |