summaryrefslogtreecommitdiff
path: root/sound
diff options
context:
space:
mode:
authorAnssi Hannula <anssi.hannula@iki.fi>2013-10-05 02:25:41 +0300
committerJiri Slaby <jslaby@suse.cz>2014-03-12 13:25:25 +0100
commit83d514f8571a8f709daff8ed488ce04f8ada94cf (patch)
tree5196b68687f9f2b6a937ed71ee86d22fdd48d01d /sound
parentb88945f412cf9f7aee57f5537b8758938a2f316a (diff)
ALSA: hda - hdmi: Fix unused slots being enabled in manual and non-PCM mappings
commit 11f7c52d90b21a51b0bc6a8b642c6ed150bdc219 upstream. 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> Signed-off-by: Jiri Slaby <jslaby@suse.cz>
Diffstat (limited to 'sound')
-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 22f6376f724b..eef388f4d1cd 100644
--- a/sound/pci/hda/patch_hdmi.c
+++ b/sound/pci/hda/patch_hdmi.c
@@ -635,9 +635,9 @@ static void hdmi_std_setup_channel_mapping(struct hda_codec *codec,
if (non_pcm) {
for (i = 0; i < ch_alloc->channels; i++)
- non_pcm_mapping[i] = i | (i << 4);
+ non_pcm_mapping[i] = (i << 4) | i;
for (; i < 8; i++)
- non_pcm_mapping[i] = 0xf | (i << 4);
+ non_pcm_mapping[i] = (0xf << 4) | i;
}
for (i = 0; i < 8; i++) {
@@ -691,7 +691,7 @@ static int to_cea_slot(unsigned char c)
if (t->map == c)
return t->cea_slot;
}
- return 0x0f;
+ return -1;
}
/* from CEA slot to ALSA API channel position */
@@ -744,14 +744,23 @@ static int hdmi_manual_setup_channel_mapping(struct hda_codec *codec,
hda_nid_t pin_nid,
int chs, unsigned char *map)
{
- int i;
- for (i = 0; i < 8; i++) {
+ int alsa_pos, hdmi_slot;
+ int assignments[8] = {[0 ... 7] = 0xf};
+
+ for (alsa_pos = 0; alsa_pos < chs; alsa_pos++) {
+
+ hdmi_slot = to_cea_slot(map[alsa_pos]);
+
+ if (hdmi_slot < 0)
+ continue; /* unassigned channel */
+
+ assignments[hdmi_slot] = alsa_pos;
+ }
+
+ for (hdmi_slot = 0; hdmi_slot < 8; hdmi_slot++) {
int val, err;
- if (i < chs)
- val = to_cea_slot(map[i]);
- else
- val = 0xf;
- val |= (i << 4);
+
+ val = (assignments[hdmi_slot] << 4) | hdmi_slot;
err = snd_hda_codec_write(codec, pin_nid, 0,
AC_VERB_SET_HDMI_CHAN_SLOT, val);
if (err)