msm_fb: hdmi: Fix parsing of audio capabilities

Fix bugs in the parsing of the Audio Data Blocks and the
Speaker Allocation Data Blocks in the EDID data.

Change-Id: I666cf82d149c8ebb02d3bca3a053e494890870c0
Signed-off-by: Ajay Singh Parmar <aparmar@codeaurora.org>
Signed-off-by: Aravind Venkateswaran <aravindh@codeaurora.org>
Signed-off-by: Naseer Ahmed <naseer@codeaurora.org>
This commit is contained in:
Naseer Ahmed
2012-09-26 23:56:24 -04:00
committed by Iliyan Malchev
parent 07cd434307
commit 59a8a43802
2 changed files with 32 additions and 29 deletions

View File

@@ -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=<ch=%d, format=%d "
"sampling=0x%02x bit-depth=0x%02x>\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)) {

View File

@@ -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