aboutsummaryrefslogtreecommitdiffstats
path: root/sound/pci/hda
diff options
context:
space:
mode:
authorWang Xingchao <xingchao.wang@intel.com>2012-09-05 22:02:37 -0400
committerTakashi Iwai <tiwai@suse.de>2012-09-06 02:50:33 -0400
commit433968da4d93a194b79da552f4ca707f979ef33b (patch)
tree848adec2f796dc999f2bbaff2c061db23810521d /sound/pci/hda
parent72357c78b75d39ee9e8d9fb4308957d9525aa674 (diff)
ALSA: HDMI - Enable HBR feature on Intel chips
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 channel mapping. Signed-off-by: Wang Xingchao <xingchao.wang@intel.com> Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound/pci/hda')
-rw-r--r--sound/pci/hda/patch_hdmi.c36
1 files changed, 32 insertions, 4 deletions
diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c
index 4fb8199d813a..a6835bd9d9b5 100644
--- a/sound/pci/hda/patch_hdmi.c
+++ b/sound/pci/hda/patch_hdmi.c
@@ -34,6 +34,7 @@
34#include <linux/module.h> 34#include <linux/module.h>
35#include <sound/core.h> 35#include <sound/core.h>
36#include <sound/jack.h> 36#include <sound/jack.h>
37#include <sound/asoundef.h>
37#include "hda_codec.h" 38#include "hda_codec.h"
38#include "hda_local.h" 39#include "hda_local.h"
39#include "hda_jack.h" 40#include "hda_jack.h"
@@ -60,6 +61,7 @@ struct hdmi_spec_per_cvt {
60 u32 rates; 61 u32 rates;
61 u64 formats; 62 u64 formats;
62 unsigned int maxbps; 63 unsigned int maxbps;
64 bool non_pcm;
63}; 65};
64 66
65struct hdmi_spec_per_pin { 67struct hdmi_spec_per_pin {
@@ -548,13 +550,17 @@ static void hdmi_debug_channel_mapping(struct hda_codec *codec,
548 550
549static void hdmi_setup_channel_mapping(struct hda_codec *codec, 551static void hdmi_setup_channel_mapping(struct hda_codec *codec,
550 hda_nid_t pin_nid, 552 hda_nid_t pin_nid,
553 hda_nid_t cvt_nid,
554 bool non_pcm,
551 int ca) 555 int ca)
552{ 556{
553 int i; 557 int i;
554 int err; 558 int err;
555 int order; 559 int order;
560 int non_pcm_mapping[8];
556 561
557 order = get_channel_allocation_order(ca); 562 order = get_channel_allocation_order(ca);
563
558 if (hdmi_channel_mapping[ca][1] == 0) { 564 if (hdmi_channel_mapping[ca][1] == 0) {
559 for (i = 0; i < channel_allocations[order].channels; i++) 565 for (i = 0; i < channel_allocations[order].channels; i++)
560 hdmi_channel_mapping[ca][i] = i | (i << 4); 566 hdmi_channel_mapping[ca][i] = i | (i << 4);
@@ -562,10 +568,17 @@ static void hdmi_setup_channel_mapping(struct hda_codec *codec,
562 hdmi_channel_mapping[ca][i] = 0xf | (i << 4); 568 hdmi_channel_mapping[ca][i] = 0xf | (i << 4);
563 } 569 }
564 570
571 if (non_pcm) {
572 for (i = 0; i < channel_allocations[order].channels; i++)
573 non_pcm_mapping[i] = i | (i << 4);
574 for (; i < 8; i++)
575 non_pcm_mapping[i] = 0xf | (i << 4);
576 }
577
565 for (i = 0; i < 8; i++) { 578 for (i = 0; i < 8; i++) {
566 err = snd_hda_codec_write(codec, pin_nid, 0, 579 err = snd_hda_codec_write(codec, pin_nid, 0,
567 AC_VERB_SET_HDMI_CHAN_SLOT, 580 AC_VERB_SET_HDMI_CHAN_SLOT,
568 hdmi_channel_mapping[ca][i]); 581 non_pcm ? non_pcm_mapping[i] : hdmi_channel_mapping[ca][i]);
569 if (err) { 582 if (err) {
570 snd_printdd(KERN_NOTICE 583 snd_printdd(KERN_NOTICE
571 "HDMI: channel mapping failed\n"); 584 "HDMI: channel mapping failed\n");
@@ -699,15 +712,27 @@ static bool hdmi_infoframe_uptodate(struct hda_codec *codec, hda_nid_t pin_nid,
699} 712}
700 713
701static void hdmi_setup_audio_infoframe(struct hda_codec *codec, int pin_idx, 714static void hdmi_setup_audio_infoframe(struct hda_codec *codec, int pin_idx,
702 struct snd_pcm_substream *substream) 715 hda_nid_t cvt_nid, struct snd_pcm_substream *substream)
703{ 716{
704 struct hdmi_spec *spec = codec->spec; 717 struct hdmi_spec *spec = codec->spec;
705 struct hdmi_spec_per_pin *per_pin = &spec->pins[pin_idx]; 718 struct hdmi_spec_per_pin *per_pin = &spec->pins[pin_idx];
719 struct hdmi_spec_per_cvt *per_cvt;
720 struct hda_spdif_out *spdif;
706 hda_nid_t pin_nid = per_pin->pin_nid; 721 hda_nid_t pin_nid = per_pin->pin_nid;
707 int channels = substream->runtime->channels; 722 int channels = substream->runtime->channels;
708 struct hdmi_eld *eld; 723 struct hdmi_eld *eld;
709 int ca; 724 int ca;
725 int cvt_idx;
710 union audio_infoframe ai; 726 union audio_infoframe ai;
727 bool non_pcm = false;
728
729 cvt_idx = cvt_nid_to_cvt_index(spec, cvt_nid);
730 per_cvt = &spec->cvts[cvt_idx];
731
732 mutex_lock(&codec->spdif_mutex);
733 spdif = snd_hda_spdif_out_of_nid(codec, cvt_nid);
734 non_pcm = !!(spdif->status & IEC958_AES0_NONAUDIO);
735 mutex_unlock(&codec->spdif_mutex);
711 736
712 eld = &spec->pins[pin_idx].sink_eld; 737 eld = &spec->pins[pin_idx].sink_eld;
713 if (!eld->monitor_present) 738 if (!eld->monitor_present)
@@ -750,12 +775,14 @@ static void hdmi_setup_audio_infoframe(struct hda_codec *codec, int pin_idx,
750 "pin=%d channels=%d\n", 775 "pin=%d channels=%d\n",
751 pin_nid, 776 pin_nid,
752 channels); 777 channels);
753 hdmi_setup_channel_mapping(codec, pin_nid, ca); 778 hdmi_setup_channel_mapping(codec, pin_nid, cvt_nid, non_pcm, ca);
754 hdmi_stop_infoframe_trans(codec, pin_nid); 779 hdmi_stop_infoframe_trans(codec, pin_nid);
755 hdmi_fill_audio_infoframe(codec, pin_nid, 780 hdmi_fill_audio_infoframe(codec, pin_nid,
756 ai.bytes, sizeof(ai)); 781 ai.bytes, sizeof(ai));
757 hdmi_start_infoframe_trans(codec, pin_nid); 782 hdmi_start_infoframe_trans(codec, pin_nid);
758 } 783 }
784
785 per_cvt->non_pcm = non_pcm;
759} 786}
760 787
761 788
@@ -1077,6 +1104,7 @@ static int hdmi_add_cvt(struct hda_codec *codec, hda_nid_t cvt_nid)
1077 1104
1078 per_cvt->cvt_nid = cvt_nid; 1105 per_cvt->cvt_nid = cvt_nid;
1079 per_cvt->channels_min = 2; 1106 per_cvt->channels_min = 2;
1107 per_cvt->non_pcm = false;
1080 if (chans <= 16) 1108 if (chans <= 16)
1081 per_cvt->channels_max = chans; 1109 per_cvt->channels_max = chans;
1082 1110
@@ -1164,7 +1192,7 @@ static int generic_hdmi_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
1164 1192
1165 hdmi_set_channel_count(codec, cvt_nid, substream->runtime->channels); 1193 hdmi_set_channel_count(codec, cvt_nid, substream->runtime->channels);
1166 1194
1167 hdmi_setup_audio_infoframe(codec, pin_idx, substream); 1195 hdmi_setup_audio_infoframe(codec, pin_idx, cvt_nid, substream);
1168 1196
1169 pinctl = snd_hda_codec_read(codec, pin_nid, 0, 1197 pinctl = snd_hda_codec_read(codec, pin_nid, 0,
1170 AC_VERB_GET_PIN_WIDGET_CONTROL, 0); 1198 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);