From bafd5d79fbc764f9dd977737e3b25d480ade2d5a Mon Sep 17 00:00:00 2001 From: Mats Randgaard Date: Thu, 5 Dec 2013 07:33:08 -0300 Subject: [media] ad9389b: verify EDID header Ignore EDIDs where the header is wrong. Signed-off-by: Mats Randgaard Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/i2c/ad9389b.c | 26 +++++++++++++++++++++++--- 1 file changed, 23 insertions(+), 3 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/i2c/ad9389b.c b/drivers/media/i2c/ad9389b.c index b06a7e54ee0d..e7f7171f9303 100644 --- a/drivers/media/i2c/ad9389b.c +++ b/drivers/media/i2c/ad9389b.c @@ -978,7 +978,7 @@ static bool edid_block_verify_crc(u8 *edid_block) return sum == 0; } -static bool edid_segment_verify_crc(struct v4l2_subdev *sd, u32 segment) +static bool edid_verify_crc(struct v4l2_subdev *sd, u32 segment) { struct ad9389b_state *state = get_ad9389b_state(sd); u32 blocks = state->edid.blocks; @@ -992,6 +992,25 @@ static bool edid_segment_verify_crc(struct v4l2_subdev *sd, u32 segment) return false; } +static bool edid_verify_header(struct v4l2_subdev *sd, u32 segment) +{ + static const u8 hdmi_header[] = { + 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00 + }; + struct ad9389b_state *state = get_ad9389b_state(sd); + u8 *data = state->edid.data; + int i; + + if (segment) + return true; + + for (i = 0; i < ARRAY_SIZE(hdmi_header); i++) + if (data[i] != hdmi_header[i]) + return false; + + return true; +} + static bool ad9389b_check_edid_status(struct v4l2_subdev *sd) { struct ad9389b_state *state = get_ad9389b_state(sd); @@ -1019,9 +1038,10 @@ static bool ad9389b_check_edid_status(struct v4l2_subdev *sd) v4l2_dbg(1, debug, sd, "%s: %d blocks in total\n", __func__, state->edid.blocks); } - if (!edid_segment_verify_crc(sd, segment)) { + if (!edid_verify_crc(sd, segment) || + !edid_verify_header(sd, segment)) { /* edid crc error, force reread of edid segment */ - v4l2_err(sd, "%s: edid crc error\n", __func__); + v4l2_err(sd, "%s: edid crc or header error\n", __func__); state->have_monitor = false; ad9389b_s_power(sd, false); ad9389b_s_power(sd, true); -- cgit v1.2.3