msm_fb: HDMI: Export interface for setting Audio info frame

The Audio InfoFrame contains information that allows for the format
of the digital audio streams to be identified more quickly via
out-of-band information and, for multi-channel uncompressed audio
provides channel allocation information for the sink device's speakers.
Currently audio info frame is hard coded to support 2-ch PCM. To Support
Multi channel PCM, correct channel allocation information has to be sent
to HDMI sink. So export the interface for setting audio info frame to
HDMI audio driver.

Change-Id: I7d0d5cf9f8792250bfd6e5eb003a8360ccb9707a
Signed-off-by: Kiran Kandi <kkandi@codeaurora.org>
This commit is contained in:
Kiran Kandi
2012-01-31 00:18:33 -08:00
parent ed1e2dd6d8
commit 94f25dcbd1
3 changed files with 44 additions and 10 deletions

View File

@@ -1,4 +1,4 @@
/* Copyright (c) 2011, Code Aurora Forum. All rights reserved. /* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and * it under the terms of the GNU General Public License version 2 and
@@ -13,6 +13,15 @@
#ifndef __MSM_HDMI_AUDIO_H #ifndef __MSM_HDMI_AUDIO_H
#define __MSM_HDMI_AUDIO_H #define __MSM_HDMI_AUDIO_H
/* Supported HDMI Audio channels */
#define MSM_HDMI_AUDIO_CHANNEL_2 0
#define MSM_HDMI_AUDIO_CHANNEL_4 1
#define MSM_HDMI_AUDIO_CHANNEL_6 2
#define MSM_HDMI_AUDIO_CHANNEL_8 3
#define TRUE 1
#define FALSE 0
enum hdmi_supported_sample_rates { enum hdmi_supported_sample_rates {
HDMI_SAMPLE_RATE_32KHZ, HDMI_SAMPLE_RATE_32KHZ,
HDMI_SAMPLE_RATE_44_1KHZ, HDMI_SAMPLE_RATE_44_1KHZ,
@@ -27,5 +36,7 @@ int hdmi_audio_enable(bool on , u32 fifo_water_mark);
int hdmi_audio_packet_enable(bool on); int hdmi_audio_packet_enable(bool on);
void hdmi_msm_audio_sample_rate_reset(int rate); void hdmi_msm_audio_sample_rate_reset(int rate);
int hdmi_msm_audio_get_sample_rate(void); int hdmi_msm_audio_get_sample_rate(void);
int hdmi_msm_audio_info_setup(bool enabled, u32 num_of_channels,
u32 channel_allocation, u32 level_shift, bool down_mix);
#endif /* __MSM_HDMI_AUDIO_H*/ #endif /* __MSM_HDMI_AUDIO_H*/

View File

@@ -1,4 +1,4 @@
/* Copyright (c) 2010, Code Aurora Forum. All rights reserved. /* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and * it under the terms of the GNU General Public License version 2 and
@@ -1000,14 +1000,15 @@ static void hdmi_edid_extract_speaker_allocation_data(const uint8 *in_buf)
return; return;
external_common_state->speaker_allocation_block = sad[1]; external_common_state->speaker_allocation_block = sad[1];
DEV_DBG("EDID: speaker allocation data=%s%s%s%s%s%s%s\n", 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(0)) ? "FL/FR," : "",
(sad[1] & BIT(1)) ? "LFE," : "", (sad[1] & BIT(1)) ? "LFE," : "",
(sad[1] & BIT(2)) ? "FC," : "", (sad[1] & BIT(2)) ? "FC," : "",
(sad[1] & BIT(3)) ? "RL/RR," : "", (sad[1] & BIT(3)) ? "RL/RR," : "",
(sad[1] & BIT(4)) ? "RC," : "", (sad[1] & BIT(4)) ? "RC," : "",
(sad[1] & BIT(5)) ? "FLC/FRC," : "", (sad[1] & BIT(5)) ? "FLC/FRC," : "",
(sad[1] & BIT(6)) ? "LFE," : ""); (sad[1] & BIT(6)) ? "RLC/RRC," : "");
} }
static void hdmi_edid_extract_audio_data_blocks(const uint8 *in_buf) static void hdmi_edid_extract_audio_data_blocks(const uint8 *in_buf)

View File

@@ -64,6 +64,8 @@ DEFINE_MUTEX(hdmi_msm_state_mutex);
EXPORT_SYMBOL(hdmi_msm_state_mutex); EXPORT_SYMBOL(hdmi_msm_state_mutex);
static DEFINE_MUTEX(hdcp_auth_state_mutex); static DEFINE_MUTEX(hdcp_auth_state_mutex);
static void hdmi_msm_dump_regs(const char *prefix);
#ifdef CONFIG_FB_MSM_HDMI_MSM_PANEL_HDCP_SUPPORT #ifdef CONFIG_FB_MSM_HDMI_MSM_PANEL_HDCP_SUPPORT
static void hdmi_msm_hdcp_enable(void); static void hdmi_msm_hdcp_enable(void);
#else #else
@@ -3280,14 +3282,23 @@ int hdmi_audio_packet_enable(bool on)
} }
EXPORT_SYMBOL(hdmi_audio_packet_enable); EXPORT_SYMBOL(hdmi_audio_packet_enable);
static void hdmi_msm_audio_info_setup(boolean enabled, int num_of_channels,
int level_shift, boolean down_mix) /* TO-DO: return -EINVAL when num_of_channels and channel_allocation
* does not match CEA 861-D spec.
*/
int hdmi_msm_audio_info_setup(bool enabled, u32 num_of_channels,
u32 channel_allocation, u32 level_shift, bool down_mix)
{ {
uint32 channel_allocation = 0; /* Default to FR,FL */
uint32 channel_count = 1; /* Default to 2 channels uint32 channel_count = 1; /* Default to 2 channels
-> See Table 17 in CEA-D spec */ -> See Table 17 in CEA-D spec */
uint32 check_sum, audio_info_0_reg, audio_info_1_reg; uint32 check_sum, audio_info_0_reg, audio_info_1_reg;
uint32 audio_info_ctrl_reg; uint32 audio_info_ctrl_reg;
u32 aud_pck_ctrl_2_reg;
u32 layout;
layout = (MSM_HDMI_AUDIO_CHANNEL_2 == num_of_channels) ? 0 : 1;
aud_pck_ctrl_2_reg = 1 | (layout << 1);
HDMI_OUTP(0x00044, aud_pck_ctrl_2_reg);
/* Please see table 20 Audio InfoFrame in HDMI spec /* Please see table 20 Audio InfoFrame in HDMI spec
FL = front left FL = front left
@@ -3310,6 +3321,7 @@ static void hdmi_msm_audio_info_setup(boolean enabled, int num_of_channels,
if (enabled) { if (enabled) {
switch (num_of_channels) { switch (num_of_channels) {
case MSM_HDMI_AUDIO_CHANNEL_2: case MSM_HDMI_AUDIO_CHANNEL_2:
channel_allocation = 0; /* Default to FR,FL */
break; break;
case MSM_HDMI_AUDIO_CHANNEL_4: case MSM_HDMI_AUDIO_CHANNEL_4:
channel_count = 3; channel_count = 3;
@@ -3327,6 +3339,9 @@ static void hdmi_msm_audio_info_setup(boolean enabled, int num_of_channels,
channel_allocation = 0x1f; channel_allocation = 0x1f;
break; break;
default: default:
pr_err("%s(): Unsupported num_of_channels = %u\n",
__func__, num_of_channels);
return -EINVAL;
break; break;
} }
@@ -3382,7 +3397,14 @@ static void hdmi_msm_audio_info_setup(boolean enabled, int num_of_channels,
} }
/* HDMI_INFOFRAME_CTRL0[0x002C] */ /* HDMI_INFOFRAME_CTRL0[0x002C] */
HDMI_OUTP(0x002C, audio_info_ctrl_reg); HDMI_OUTP(0x002C, audio_info_ctrl_reg);
hdmi_msm_dump_regs("HDMI-AUDIO-ON: ");
return 0;
} }
EXPORT_SYMBOL(hdmi_msm_audio_info_setup);
static void hdmi_msm_en_gc_packet(boolean av_mute_is_requested) static void hdmi_msm_en_gc_packet(boolean av_mute_is_requested)
{ {
@@ -3488,7 +3510,7 @@ static void hdmi_msm_audio_setup(void)
hdmi_msm_audio_acr_setup(TRUE, hdmi_msm_audio_acr_setup(TRUE,
external_common_state->video_resolution, external_common_state->video_resolution,
msm_hdmi_sample_rate, channels); msm_hdmi_sample_rate, channels);
hdmi_msm_audio_info_setup(TRUE, channels, 0, FALSE); hdmi_msm_audio_info_setup(TRUE, channels, 0, 0, FALSE);
/* Turn on Audio FIFO and SAM DROP ISR */ /* Turn on Audio FIFO and SAM DROP ISR */
HDMI_OUTP(0x02CC, HDMI_INP(0x02CC) | BIT(1) | BIT(3)); HDMI_OUTP(0x02CC, HDMI_INP(0x02CC) | BIT(1) | BIT(3));
@@ -3519,7 +3541,7 @@ static int hdmi_msm_audio_off(void)
return -ETIMEDOUT; return -ETIMEDOUT;
} }
} }
hdmi_msm_audio_info_setup(FALSE, 0, 0, FALSE); hdmi_msm_audio_info_setup(FALSE, 0, 0, 0, FALSE);
hdmi_msm_audio_acr_setup(FALSE, 0, 0, 0); hdmi_msm_audio_acr_setup(FALSE, 0, 0, 0);
DEV_INFO("HDMI Audio: Disabled\n"); DEV_INFO("HDMI Audio: Disabled\n");
return 0; return 0;
@@ -4042,7 +4064,7 @@ static int hdmi_msm_power_on(struct platform_device *pdev)
return rc; return rc;
} }
} }
hdmi_msm_audio_info_setup(TRUE, 0, 0, FALSE); hdmi_msm_audio_info_setup(TRUE, 0, 0, 0, FALSE);
mutex_lock(&external_common_state_hpd_mutex); mutex_lock(&external_common_state_hpd_mutex);
hdmi_msm_state->panel_power_on = TRUE; hdmi_msm_state->panel_power_on = TRUE;