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>
diff --git a/drivers/video/msm/external_common.c b/drivers/video/msm/external_common.c
index 7fd4c56..07a075c 100644
--- a/drivers/video/msm/external_common.c
+++ b/drivers/video/msm/external_common.c
@@ -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
  * it under the terms of the GNU General Public License version 2 and
@@ -1000,14 +1000,15 @@
 		return;
 
 	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(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)) ? "LFE," : "");
+		(sad[1] & BIT(6)) ? "RLC/RRC," : "");
 }
 
 static void hdmi_edid_extract_audio_data_blocks(const uint8 *in_buf)
diff --git a/drivers/video/msm/hdmi_msm.c b/drivers/video/msm/hdmi_msm.c
index 56a6483..93e6d40 100644
--- a/drivers/video/msm/hdmi_msm.c
+++ b/drivers/video/msm/hdmi_msm.c
@@ -64,6 +64,8 @@
 EXPORT_SYMBOL(hdmi_msm_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
 static void hdmi_msm_hdcp_enable(void);
 #else
@@ -3280,14 +3282,23 @@
 }
 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
 					   -> See Table 17 in CEA-D spec */
 	uint32 check_sum, audio_info_0_reg, audio_info_1_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
 	   FL  = front left
@@ -3310,6 +3321,7 @@
 	if (enabled) {
 		switch (num_of_channels) {
 		case MSM_HDMI_AUDIO_CHANNEL_2:
+			channel_allocation = 0;	/* Default to FR,FL */
 			break;
 		case MSM_HDMI_AUDIO_CHANNEL_4:
 			channel_count = 3;
@@ -3327,6 +3339,9 @@
 			channel_allocation = 0x1f;
 			break;
 		default:
+			pr_err("%s(): Unsupported num_of_channels = %u\n",
+					__func__, num_of_channels);
+			return -EINVAL;
 			break;
 		}
 
@@ -3382,7 +3397,14 @@
 	}
 	/* HDMI_INFOFRAME_CTRL0[0x002C] */
 	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)
 {
@@ -3488,7 +3510,7 @@
 	hdmi_msm_audio_acr_setup(TRUE,
 		external_common_state->video_resolution,
 		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 */
 	HDMI_OUTP(0x02CC, HDMI_INP(0x02CC) | BIT(1) | BIT(3));
@@ -3519,7 +3541,7 @@
 			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);
 	DEV_INFO("HDMI Audio: Disabled\n");
 	return 0;
@@ -4042,7 +4064,7 @@
 			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);
 	hdmi_msm_state->panel_power_on = TRUE;