aboutsummaryrefslogtreecommitdiffstats
path: root/sound/pci
diff options
context:
space:
mode:
authorAnssi Hannula <anssi.hannula@iki.fi>2013-10-04 19:25:41 -0400
committerTakashi Iwai <tiwai@suse.de>2013-10-07 06:47:30 -0400
commit11f7c52d90b21a51b0bc6a8b642c6ed150bdc219 (patch)
treeaf5f20f66a34c349dcac2691059f3e9b5861cccc /sound/pci
parent1df5a06abbaa876ecc01ea84064cdffb4f52a1a1 (diff)
ALSA: hda - hdmi: Fix unused slots being enabled in manual and non-PCM mappings
hdmi_manual_setup_channel_mapping() and hdmi_std_setup_channel_mapping try to assign ALSA channels to HDMI channel slots and disable (i.e. silence) other slots. However, they try to disable a slot by using AC_VERB_SET_CHAN_SLOT with parameter ((alsa_ch << 8) | 0xf), while the correct parameter is ((0xf << 8) | hdmi_slot), i.e. the slot should be unassigned, not the ALSA channel. Fix that by actually disabling the unused slots. Note that this bug did not cause any (reported) issues because slots incorrectly having audio are normally ignored by a receiver if the CEA channel allocation used does not map that slot to any speaker. Additionally, the converter channel count configuration limits the number of actually active channels in any case. Signed-off-by: Anssi Hannula <anssi.hannula@iki.fi> Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound/pci')
-rw-r--r--sound/pci/hda/patch_hdmi.c29
1 files changed, 19 insertions, 10 deletions
diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c
index 4efaca89d805..8bf526ea8cf2 100644
--- a/sound/pci/hda/patch_hdmi.c
+++ b/sound/pci/hda/patch_hdmi.c
@@ -622,9 +622,9 @@ static void hdmi_std_setup_channel_mapping(struct hda_codec *codec,
622 622
623 if (non_pcm) { 623 if (non_pcm) {
624 for (i = 0; i < ch_alloc->channels; i++) 624 for (i = 0; i < ch_alloc->channels; i++)
625 non_pcm_mapping[i] = i | (i << 4); 625 non_pcm_mapping[i] = (i << 4) | i;
626 for (; i < 8; i++) 626 for (; i < 8; i++)
627 non_pcm_mapping[i] = 0xf | (i << 4); 627 non_pcm_mapping[i] = (0xf << 4) | i;
628 } 628 }
629 629
630 for (i = 0; i < 8; i++) { 630 for (i = 0; i < 8; i++) {
@@ -678,7 +678,7 @@ static int to_cea_slot(unsigned char c)
678 if (t->map == c) 678 if (t->map == c)
679 return t->cea_slot; 679 return t->cea_slot;
680 } 680 }
681 return 0x0f; 681 return -1;
682} 682}
683 683
684/* from CEA slot to ALSA API channel position */ 684/* from CEA slot to ALSA API channel position */
@@ -731,14 +731,23 @@ static int hdmi_manual_setup_channel_mapping(struct hda_codec *codec,
731 hda_nid_t pin_nid, 731 hda_nid_t pin_nid,
732 int chs, unsigned char *map) 732 int chs, unsigned char *map)
733{ 733{
734 int i; 734 int alsa_pos, hdmi_slot;
735 for (i = 0; i < 8; i++) { 735 int assignments[8] = {[0 ... 7] = 0xf};
736
737 for (alsa_pos = 0; alsa_pos < chs; alsa_pos++) {
738
739 hdmi_slot = to_cea_slot(map[alsa_pos]);
740
741 if (hdmi_slot < 0)
742 continue; /* unassigned channel */
743
744 assignments[hdmi_slot] = alsa_pos;
745 }
746
747 for (hdmi_slot = 0; hdmi_slot < 8; hdmi_slot++) {
736 int val, err; 748 int val, err;
737 if (i < chs) 749
738 val = to_cea_slot(map[i]); 750 val = (assignments[hdmi_slot] << 4) | hdmi_slot;
739 else
740 val = 0xf;
741 val |= (i << 4);
742 err = snd_hda_codec_write(codec, pin_nid, 0, 751 err = snd_hda_codec_write(codec, pin_nid, 0,
743 AC_VERB_SET_HDMI_CHAN_SLOT, val); 752 AC_VERB_SET_HDMI_CHAN_SLOT, val);
744 if (err) 753 if (err)