diff --git a/packages/linux/patches/3.7.6/linux-990.04-hda-Fix_the_workaround_for_conflicting_IEC958_controls.patch b/packages/linux/patches/3.7.6/linux-990.04-hda-Fix_the_workaround_for_conflicting_IEC958_controls.patch new file mode 100644 index 0000000000..b042469a87 --- /dev/null +++ b/packages/linux/patches/3.7.6/linux-990.04-hda-Fix_the_workaround_for_conflicting_IEC958_controls.patch @@ -0,0 +1,94 @@ +From 1aec20670bfd1c0680d2ea4b29c4e5d8f1bdb43f Mon Sep 17 00:00:00 2001 +From: Anssi Hannula +Date: Sat, 9 Feb 2013 00:19:09 +0200 +Subject: [PATCH] ALSA: hda - Fix the workaround for conflicting IEC958 + controls + +Commit dcda5806165c155d90b9aa466a1602cf4726012b ("ALSA: hda - Add +workaround for conflicting IEC958 controls") added a workaround for +cards that have both an S/PDIF and an HDMI device, so that S/PDIF IEC958 +controls will be moved to device=1 on such cards. + +However, the workaround did not take it into account that the S/PDIF and +HDMI devices may be on different codecs of the same card. Currently this +is always the case, and the workaround therefore fails to work. + +Fix the workaround to handle card-wide IEC958 conflicts. + +Reported-by: Stephan Raue +Signed-off-by: Anssi Hannula +--- + sound/pci/hda/hda_codec.c | 27 +++++++++++++++------------ + sound/pci/hda/hda_codec.h | 4 +++- + 2 files changed, 18 insertions(+), 13 deletions(-) + +diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c +index 822df97..fe5d6fc 100644 +--- a/sound/pci/hda/hda_codec.c ++++ b/sound/pci/hda/hda_codec.c +@@ -3135,25 +3135,28 @@ int snd_hda_create_dig_out_ctls(struct hda_codec *codec, + int idx, dev = 0; + const int spdif_pcm_dev = 1; + struct hda_spdif_out *spdif; ++ struct hda_codec *c; + +- if (codec->primary_dig_out_type == HDA_PCM_TYPE_HDMI && ++ if (codec->bus->primary_dig_out_type == HDA_PCM_TYPE_HDMI && + type == HDA_PCM_TYPE_SPDIF) { + dev = spdif_pcm_dev; +- } else if (codec->primary_dig_out_type == HDA_PCM_TYPE_SPDIF && ++ } else if (codec->bus->primary_dig_out_type == HDA_PCM_TYPE_SPDIF && + type == HDA_PCM_TYPE_HDMI) { +- for (idx = 0; idx < codec->spdif_out.used; idx++) { +- spdif = snd_array_elem(&codec->spdif_out, idx); +- for (dig_mix = dig_mixes; dig_mix->name; dig_mix++) { +- kctl = find_mixer_ctl(codec, dig_mix->name, 0, idx); +- if (!kctl) +- break; +- kctl->id.device = spdif_pcm_dev; ++ list_for_each_entry(c, &codec->bus->codec_list, list) { ++ for (idx = 0; idx < c->spdif_out.used; idx++) { ++ spdif = snd_array_elem(&c->spdif_out, idx); ++ for (dig_mix = dig_mixes; dig_mix->name; dig_mix++) { ++ kctl = find_mixer_ctl(c, dig_mix->name, 0, idx); ++ if (!kctl) ++ break; ++ kctl->id.device = spdif_pcm_dev; ++ } + } + } +- codec->primary_dig_out_type = HDA_PCM_TYPE_HDMI; ++ codec->bus->primary_dig_out_type = HDA_PCM_TYPE_HDMI; + } +- if (!codec->primary_dig_out_type) +- codec->primary_dig_out_type = type; ++ if (!codec->bus->primary_dig_out_type) ++ codec->bus->primary_dig_out_type = type; + + idx = find_empty_mixer_ctl_idx(codec, "IEC958 Playback Switch", dev); + if (idx < 0) { +diff --git a/sound/pci/hda/hda_codec.h b/sound/pci/hda/hda_codec.h +index 8665540..ab807f7 100644 +--- a/sound/pci/hda/hda_codec.h ++++ b/sound/pci/hda/hda_codec.h +@@ -671,6 +671,9 @@ struct hda_bus { + unsigned int response_reset:1; /* controller was reset */ + unsigned int in_reset:1; /* during reset operation */ + unsigned int power_keep_link_on:1; /* don't power off HDA link */ ++ ++ /* primary digital out PCM type */ ++ int primary_dig_out_type; + }; + + /* +@@ -837,7 +840,6 @@ struct hda_codec { + struct mutex hash_mutex; + struct snd_array spdif_out; + unsigned int spdif_in_enable; /* SPDIF input enable? */ +- int primary_dig_out_type; /* primary digital out PCM type */ + const hda_nid_t *slave_dig_outs; /* optional digital out slave widgets */ + struct snd_array init_pins; /* initial (BIOS) pin configurations */ + struct snd_array driver_pins; /* pin configs set by codec parser */ +-- +1.7.10 +