diff --git a/drivers/video/msm/external_common.c b/drivers/video/msm/external_common.c index e701e46f658..48d2c71a925 100644 --- a/drivers/video/msm/external_common.c +++ b/drivers/video/msm/external_common.c @@ -1206,45 +1206,33 @@ static void hdmi_edid_extract_latency_fields(const uint8 *in_buf) static void hdmi_edid_extract_speaker_allocation_data(const uint8 *in_buf) { uint8 len; - const uint8 *sad = hdmi_edid_find_block(in_buf, DBC_START_OFFSET, 4, + const uint8 *sadb = hdmi_edid_find_block(in_buf, DBC_START_OFFSET, 4, &len); - if (sad == NULL) + if (sadb == NULL) return; - external_common_state->speaker_allocation_block = sad[1]; - DEV_DBG("EDID: speaker allocation data SP byte = %08x %s%s%s%s%s%s%s\n", - sad[1], - (sad[1] & BIT(0)) ? "FL/FR," : "", - (sad[1] & BIT(1)) ? "LFE," : "", - (sad[1] & BIT(2)) ? "FC," : "", - (sad[1] & BIT(3)) ? "RL/RR," : "", - (sad[1] & BIT(4)) ? "RC," : "", - (sad[1] & BIT(5)) ? "FLC/FRC," : "", - (sad[1] & BIT(6)) ? "RLC/RRC," : ""); + if (len != MAX_SPKR_ALLOC_DATA_BLOCK_SIZE) + return; + + memcpy(external_common_state->spkr_alloc_data_block, sadb + 1, len); + external_common_state->sadb_size = len; } static void hdmi_edid_extract_audio_data_blocks(const uint8 *in_buf) { uint8 len; - const uint8 *sad = hdmi_edid_find_block(in_buf, DBC_START_OFFSET, 1, + const uint8 *adb = hdmi_edid_find_block(in_buf, DBC_START_OFFSET, 1, &len); - uint32 *adb = external_common_state->audio_data_blocks; - if (sad == NULL) + if (external_common_state->audio_data_block == NULL) return; - external_common_state->audio_data_block_cnt = 0; - while (len >= 3 && external_common_state->audio_data_block_cnt < 16) { - DEV_DBG("EDID: Audio Data Block=\n", - (sad[1] & 0x7)+1, sad[1] >> 3, sad[2], sad[3]); - *adb++ = (uint32)sad[1] + ((uint32)sad[2] << 8) - + ((uint32)sad[2] << 16); - ++external_common_state->audio_data_block_cnt; - len -= 3; - sad += 3; - } + if (len > MAX_AUDIO_DATA_BLOCK_SIZE) + return; + + memcpy(external_common_state->audio_data_block, adb + 1, len); + external_common_state->adb_size = len; } static void hdmi_edid_extract_extended_data_blocks(const uint8 *in_buf) @@ -1900,6 +1888,12 @@ int hdmi_common_read_edid(void) memset(&external_common_state->disp_mode_list, 0, sizeof(external_common_state->disp_mode_list)); memset(edid_buf, 0, sizeof(edid_buf)); + memset(external_common_state->audio_data_block, 0, + sizeof(external_common_state->audio_data_block)); + memset(external_common_state->spkr_alloc_data_block, 0, + sizeof(external_common_state->spkr_alloc_data_block)); + external_common_state->adb_size = 0; + external_common_state->sadb_size = 0; status = hdmi_common_read_edid_block(0, edid_buf); if (status || !check_edid_header(edid_buf)) { diff --git a/drivers/video/msm/external_common.h b/drivers/video/msm/external_common.h index 43a879477a2..911fcb89e1f 100644 --- a/drivers/video/msm/external_common.h +++ b/drivers/video/msm/external_common.h @@ -206,6 +206,14 @@ struct hdmi_disp_mode_list_type { }; #endif +/* + * As per the CEA-861E spec, there can be a total of 10 short audio + * descriptors with each SAD being 3 bytes long. + * Thus, the maximum length of the audio data block would be 30 bytes + */ +#define MAX_AUDIO_DATA_BLOCK_SIZE 30 +#define MAX_SPKR_ALLOC_DATA_BLOCK_SIZE 3 + struct external_common_state_type { boolean hpd_state; struct kobject *uevent_kobj; @@ -221,9 +229,7 @@ struct external_common_state_type { boolean hpd_feature_on; boolean hdmi_sink; struct hdmi_disp_mode_list_type disp_mode_list; - uint8 speaker_allocation_block; uint16 video_latency, audio_latency; - uint8 audio_data_block_cnt; uint16 physical_address; uint32 preferred_video_format; uint8 pt_scan_info; @@ -233,7 +239,10 @@ struct external_common_state_type { uint8 spd_product_description[16]; boolean present_3d; boolean present_hdcp; - uint32 audio_data_blocks[16]; + uint8 audio_data_block[MAX_AUDIO_DATA_BLOCK_SIZE]; + int adb_size; + uint8 spkr_alloc_data_block[MAX_SPKR_ALLOC_DATA_BLOCK_SIZE]; + int sadb_size; int (*read_edid_block)(int block, uint8 *edid_buf); int (*hpd_feature)(int on); #endif