All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] ALSA: HDMI - Enable HBR feature on Intel chips
@ 2012-08-28  6:46 Wang Xingchao
  2012-08-28  7:53 ` Fengguang Wu
  2012-08-28  8:00 ` Anssi Hannula
  0 siblings, 2 replies; 8+ messages in thread
From: Wang Xingchao @ 2012-08-28  6:46 UTC (permalink / raw)
  To: alsa-devel; +Cc: tiwai, anssi.hannula, fengguang.wu, alanwww1, Wang Xingchao

HDMI channel remapping apparently effects HBR packets on Intel's chips.
For compressed non-PCM audio, use "straight-through" channel mapping.
For uncompressed multi-channel pcm audio, use normal mapping.

Signed-off-by: Wang Xingchao <xingchao.wang@intel.com>
Signed-off-by: Anssi Hannula <anssi.hannula@iki.fi>
---
 sound/pci/hda/patch_hdmi.c |   50 +++++++++++++++++++++++++++-----------------
 1 file changed, 31 insertions(+), 19 deletions(-)

diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c
index d9439c5..fda89e3 100644
--- a/sound/pci/hda/patch_hdmi.c
+++ b/sound/pci/hda/patch_hdmi.c
@@ -231,6 +231,11 @@ static struct cea_channel_speaker_allocation channel_allocations[] = {
 { .ca_index = 0x01,  .speakers = {   0,    0,   0,   0,   0,  LFE,  FR,  FL } },
 				 /* Dolby Surround */
 { .ca_index = 0x02,  .speakers = {   0,    0,   0,   0,  FC,    0,  FR,  FL } },
+{ .ca_index = 0x03,  .speakers = {   0,    0,   0,   0,  FC,  LFE,  FR,  FL } },
+{ .ca_index = 0x04,  .speakers = {   0,    0,   0,  RC,   0,    0,  FR,  FL } },
+{ .ca_index = 0x05,  .speakers = {   0,    0,   0,  RC,   0,  LFE,  FR,  FL } },
+{ .ca_index = 0x06,  .speakers = {   0,    0,   0,  RC,  FC,    0,  FR,  FL } },
+{ .ca_index = 0x07,  .speakers = {   0,    0,   0,  RC,  FC,  LFE,  FR,  FL } },
 				 /* surround40 */
 { .ca_index = 0x08,  .speakers = {   0,    0,  RR,  RL,   0,    0,  FR,  FL } },
 				 /* surround41 */
@@ -239,22 +244,15 @@ static struct cea_channel_speaker_allocation channel_allocations[] = {
 { .ca_index = 0x0a,  .speakers = {   0,    0,  RR,  RL,  FC,    0,  FR,  FL } },
 				 /* surround51 */
 { .ca_index = 0x0b,  .speakers = {   0,    0,  RR,  RL,  FC,  LFE,  FR,  FL } },
-				 /* 6.1 */
-{ .ca_index = 0x0f,  .speakers = {   0,   RC,  RR,  RL,  FC,  LFE,  FR,  FL } },
-				 /* surround71 */
-{ .ca_index = 0x13,  .speakers = { RRC,  RLC,  RR,  RL,  FC,  LFE,  FR,  FL } },
-
-{ .ca_index = 0x03,  .speakers = {   0,    0,   0,   0,  FC,  LFE,  FR,  FL } },
-{ .ca_index = 0x04,  .speakers = {   0,    0,   0,  RC,   0,    0,  FR,  FL } },
-{ .ca_index = 0x05,  .speakers = {   0,    0,   0,  RC,   0,  LFE,  FR,  FL } },
-{ .ca_index = 0x06,  .speakers = {   0,    0,   0,  RC,  FC,    0,  FR,  FL } },
-{ .ca_index = 0x07,  .speakers = {   0,    0,   0,  RC,  FC,  LFE,  FR,  FL } },
 { .ca_index = 0x0c,  .speakers = {   0,   RC,  RR,  RL,   0,    0,  FR,  FL } },
 { .ca_index = 0x0d,  .speakers = {   0,   RC,  RR,  RL,   0,  LFE,  FR,  FL } },
 { .ca_index = 0x0e,  .speakers = {   0,   RC,  RR,  RL,  FC,    0,  FR,  FL } },
+{ .ca_index = 0x0f,  .speakers = {   0,   RC,  RR,  RL,  FC,  LFE,  FR,  FL } },
 { .ca_index = 0x10,  .speakers = { RRC,  RLC,  RR,  RL,   0,    0,  FR,  FL } },
 { .ca_index = 0x11,  .speakers = { RRC,  RLC,  RR,  RL,   0,  LFE,  FR,  FL } },
 { .ca_index = 0x12,  .speakers = { RRC,  RLC,  RR,  RL,  FC,    0,  FR,  FL } },
+				 /* surround71 */
+{ .ca_index = 0x13,  .speakers = { RRC,  RLC,  RR,  RL,  FC,  LFE,  FR,  FL } },
 { .ca_index = 0x14,  .speakers = { FRC,  FLC,   0,   0,   0,    0,  FR,  FL } },
 { .ca_index = 0x15,  .speakers = { FRC,  FLC,   0,   0,   0,  LFE,  FR,  FL } },
 { .ca_index = 0x16,  .speakers = { FRC,  FLC,   0,   0,  FC,    0,  FR,  FL } },
@@ -537,22 +535,36 @@ static void hdmi_debug_channel_mapping(struct hda_codec *codec,
 
 static void hdmi_setup_channel_mapping(struct hda_codec *codec,
 				       hda_nid_t pin_nid,
+				       hda_nid_t cvt_nid,
 				       int ca)
 {
 	int i;
 	int err;
-
-	if (hdmi_channel_mapping[ca][1] == 0) {
-		for (i = 0; i < channel_allocations[ca].channels; i++)
-			hdmi_channel_mapping[ca][i] = i | (i << 4);
+	unsigned short val;
+	int tmp_mapping[8];
+	bool non_pcm = false;
+
+	val = snd_hda_codec_read(codec, cvt_nid, 0, AC_VERB_GET_DIGI_CONVERT_1, 0);
+	non_pcm = !!(val & AC_DIG1_NONAUDIO);
+
+	if (hdmi_channel_mapping[ca][1] == 0 || non_pcm) {
+		for (i = 0; i < channel_allocations[ca].channels; i++) {
+			if (non_pcm)
+				tmp_mapping[i] = i | (i << 4);
+			else
+				hdmi_channel_mapping[ca][i] = i | (i << 4);
+		}
 		for (; i < 8; i++)
-			hdmi_channel_mapping[ca][i] = 0xf | (i << 4);
+			if (non_pcm)
+				tmp_mapping[i] = 0xf | (i << 4);
+			else
+				hdmi_channel_mapping[ca][i] = 0xf | (i << 4);
 	}
 
 	for (i = 0; i < 8; i++) {
 		err = snd_hda_codec_write(codec, pin_nid, 0,
 					  AC_VERB_SET_HDMI_CHAN_SLOT,
-					  hdmi_channel_mapping[ca][i]);
+					  non_pcm ? tmp_mapping[i] : hdmi_channel_mapping[ca][i]);
 		if (err) {
 			snd_printdd(KERN_NOTICE
 				    "HDMI: channel mapping failed\n");
@@ -686,7 +698,7 @@ static bool hdmi_infoframe_uptodate(struct hda_codec *codec, hda_nid_t pin_nid,
 }
 
 static void hdmi_setup_audio_infoframe(struct hda_codec *codec, int pin_idx,
-					struct snd_pcm_substream *substream)
+					hda_nid_t cvt_nid, struct snd_pcm_substream *substream)
 {
 	struct hdmi_spec *spec = codec->spec;
 	struct hdmi_spec_per_pin *per_pin = &spec->pins[pin_idx];
@@ -731,13 +743,13 @@ static void hdmi_setup_audio_infoframe(struct hda_codec *codec, int pin_idx,
 	 * sizeof(*dp_ai) to avoid partial match/update problems when
 	 * the user switches between HDMI/DP monitors.
 	 */
+	hdmi_setup_channel_mapping(codec, pin_nid, cvt_nid, ca);
 	if (!hdmi_infoframe_uptodate(codec, pin_nid, ai.bytes,
 					sizeof(ai))) {
 		snd_printdd("hdmi_setup_audio_infoframe: "
 			    "pin=%d channels=%d\n",
 			    pin_nid,
 			    channels);
-		hdmi_setup_channel_mapping(codec, pin_nid, ca);
 		hdmi_stop_infoframe_trans(codec, pin_nid);
 		hdmi_fill_audio_infoframe(codec, pin_nid,
 					    ai.bytes, sizeof(ai));
@@ -1151,7 +1163,7 @@ static int generic_hdmi_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
 
 	hdmi_set_channel_count(codec, cvt_nid, substream->runtime->channels);
 
-	hdmi_setup_audio_infoframe(codec, pin_idx, substream);
+	hdmi_setup_audio_infoframe(codec, pin_idx, cvt_nid, substream);
 
 	pinctl = snd_hda_codec_read(codec, pin_nid, 0,
 				    AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2012-09-05  5:54 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2012-08-28  6:46 [PATCH] ALSA: HDMI - Enable HBR feature on Intel chips Wang Xingchao
2012-08-28  7:53 ` Fengguang Wu
2012-08-28  8:45   ` Wang, Xingchao
2012-08-28  8:00 ` Anssi Hannula
2012-08-28  8:30   ` Wang, Xingchao
2012-09-03  8:36     ` Takashi Iwai
2012-09-05  5:08       ` Wang Xingchao
2012-09-05  5:54         ` Takashi Iwai

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.