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:
committed by
Iliyan Malchev
parent
07cd434307
commit
59a8a43802
@@ -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)) {
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user