aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStephen Warren <swarren@nvidia.com>2011-06-01 13:14:17 -0400
committerTakashi Iwai <tiwai@suse.de>2011-06-06 06:48:59 -0400
commit7c9359762797ba7a70bbaa6364aaecc16786ac83 (patch)
tree82830d36c0bc7d934deed1e99b9c4bb80f404b11
parentc3d52105753dafdf2d993e540cc3192f23447dac (diff)
ALSA: hda: Allow multple SPDIF controls per codec
Currently, the data that backs the kcontrols created by snd_hda_create_spdif_out_ctls is stored directly in struct hda_codec. When multiple sets of these controls are stored, they will all manipulate the same data, causing confusion. Instead, store an array of this data, one copy per converter, to isolate the controls. This patch would cause a behavioural change in the case where snd_hda_create_spdif_out_ctls was called multiple times for a single codec. As best I can tell, this is never the case for any codec. This will be relevant at least for some HDMI audio codecs, such as the NVIDIA GeForce 520 and Intel Ibex Peak. A future change will modify the driver's handling of those codecs to create multiple PCMs per codec. Note that this issue isn't affected by whether one creates a PCM-per-converter or PCM-per-pin; there are multiple of both within a single codec in both of those codecs. Note that those codecs don't currently create multiple PCMs for the codec due to the default HW mux state of all pins being to point at the same converter, hence there is only a single converter routed to any pin, and hence only a single PCM. Signed-off-by: Stephen Warren <swarren@nvidia.com> Signed-off-by: Takashi Iwai <tiwai@suse.de>
-rw-r--r--sound/pci/hda/hda_codec.c80
-rw-r--r--sound/pci/hda/hda_codec.h12
-rw-r--r--sound/pci/hda/hda_intel.c5
-rw-r--r--sound/pci/hda/patch_hdmi.c19
-rw-r--r--sound/pci/hda/patch_via.c12
5 files changed, 87 insertions, 41 deletions
diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c
index 45b4a8d70e08..e17e2998d333 100644
--- a/sound/pci/hda/hda_codec.c
+++ b/sound/pci/hda/hda_codec.c
@@ -1083,6 +1083,7 @@ static void snd_hda_codec_free(struct hda_codec *codec)
1083 snd_array_free(&codec->mixers); 1083 snd_array_free(&codec->mixers);
1084 snd_array_free(&codec->nids); 1084 snd_array_free(&codec->nids);
1085 snd_array_free(&codec->conn_lists); 1085 snd_array_free(&codec->conn_lists);
1086 snd_array_free(&codec->spdif_out);
1086 codec->bus->caddr_tbl[codec->addr] = NULL; 1087 codec->bus->caddr_tbl[codec->addr] = NULL;
1087 if (codec->patch_ops.free) 1088 if (codec->patch_ops.free)
1088 codec->patch_ops.free(codec); 1089 codec->patch_ops.free(codec);
@@ -1144,6 +1145,7 @@ int /*__devinit*/ snd_hda_codec_new(struct hda_bus *bus,
1144 snd_array_init(&codec->driver_pins, sizeof(struct hda_pincfg), 16); 1145 snd_array_init(&codec->driver_pins, sizeof(struct hda_pincfg), 16);
1145 snd_array_init(&codec->cvt_setups, sizeof(struct hda_cvt_setup), 8); 1146 snd_array_init(&codec->cvt_setups, sizeof(struct hda_cvt_setup), 8);
1146 snd_array_init(&codec->conn_lists, sizeof(hda_nid_t), 64); 1147 snd_array_init(&codec->conn_lists, sizeof(hda_nid_t), 64);
1148 snd_array_init(&codec->spdif_out, sizeof(struct hda_spdif_out), 16);
1147 if (codec->bus->modelname) { 1149 if (codec->bus->modelname) {
1148 codec->modelname = kstrdup(codec->bus->modelname, GFP_KERNEL); 1150 codec->modelname = kstrdup(codec->bus->modelname, GFP_KERNEL);
1149 if (!codec->modelname) { 1151 if (!codec->modelname) {
@@ -2555,11 +2557,13 @@ static int snd_hda_spdif_default_get(struct snd_kcontrol *kcontrol,
2555 struct snd_ctl_elem_value *ucontrol) 2557 struct snd_ctl_elem_value *ucontrol)
2556{ 2558{
2557 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 2559 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2560 int idx = kcontrol->private_value;
2561 struct hda_spdif_out *spdif = snd_array_elem(&codec->spdif_out, idx);
2558 2562
2559 ucontrol->value.iec958.status[0] = codec->spdif_status & 0xff; 2563 ucontrol->value.iec958.status[0] = spdif->status & 0xff;
2560 ucontrol->value.iec958.status[1] = (codec->spdif_status >> 8) & 0xff; 2564 ucontrol->value.iec958.status[1] = (spdif->status >> 8) & 0xff;
2561 ucontrol->value.iec958.status[2] = (codec->spdif_status >> 16) & 0xff; 2565 ucontrol->value.iec958.status[2] = (spdif->status >> 16) & 0xff;
2562 ucontrol->value.iec958.status[3] = (codec->spdif_status >> 24) & 0xff; 2566 ucontrol->value.iec958.status[3] = (spdif->status >> 24) & 0xff;
2563 2567
2564 return 0; 2568 return 0;
2565} 2569}
@@ -2644,19 +2648,21 @@ static int snd_hda_spdif_default_put(struct snd_kcontrol *kcontrol,
2644 struct snd_ctl_elem_value *ucontrol) 2648 struct snd_ctl_elem_value *ucontrol)
2645{ 2649{
2646 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 2650 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2647 hda_nid_t nid = kcontrol->private_value; 2651 int idx = kcontrol->private_value;
2652 struct hda_spdif_out *spdif = snd_array_elem(&codec->spdif_out, idx);
2653 hda_nid_t nid = spdif->nid;
2648 unsigned short val; 2654 unsigned short val;
2649 int change; 2655 int change;
2650 2656
2651 mutex_lock(&codec->spdif_mutex); 2657 mutex_lock(&codec->spdif_mutex);
2652 codec->spdif_status = ucontrol->value.iec958.status[0] | 2658 spdif->status = ucontrol->value.iec958.status[0] |
2653 ((unsigned int)ucontrol->value.iec958.status[1] << 8) | 2659 ((unsigned int)ucontrol->value.iec958.status[1] << 8) |
2654 ((unsigned int)ucontrol->value.iec958.status[2] << 16) | 2660 ((unsigned int)ucontrol->value.iec958.status[2] << 16) |
2655 ((unsigned int)ucontrol->value.iec958.status[3] << 24); 2661 ((unsigned int)ucontrol->value.iec958.status[3] << 24);
2656 val = convert_from_spdif_status(codec->spdif_status); 2662 val = convert_from_spdif_status(spdif->status);
2657 val |= codec->spdif_ctls & 1; 2663 val |= spdif->ctls & 1;
2658 change = codec->spdif_ctls != val; 2664 change = spdif->ctls != val;
2659 codec->spdif_ctls = val; 2665 spdif->ctls = val;
2660 2666
2661 if (change) 2667 if (change)
2662 set_dig_out_convert(codec, nid, val & 0xff, (val >> 8) & 0xff); 2668 set_dig_out_convert(codec, nid, val & 0xff, (val >> 8) & 0xff);
@@ -2671,8 +2677,10 @@ static int snd_hda_spdif_out_switch_get(struct snd_kcontrol *kcontrol,
2671 struct snd_ctl_elem_value *ucontrol) 2677 struct snd_ctl_elem_value *ucontrol)
2672{ 2678{
2673 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 2679 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2680 int idx = kcontrol->private_value;
2681 struct hda_spdif_out *spdif = snd_array_elem(&codec->spdif_out, idx);
2674 2682
2675 ucontrol->value.integer.value[0] = codec->spdif_ctls & AC_DIG1_ENABLE; 2683 ucontrol->value.integer.value[0] = spdif->ctls & AC_DIG1_ENABLE;
2676 return 0; 2684 return 0;
2677} 2685}
2678 2686
@@ -2680,17 +2688,19 @@ static int snd_hda_spdif_out_switch_put(struct snd_kcontrol *kcontrol,
2680 struct snd_ctl_elem_value *ucontrol) 2688 struct snd_ctl_elem_value *ucontrol)
2681{ 2689{
2682 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 2690 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2683 hda_nid_t nid = kcontrol->private_value; 2691 int idx = kcontrol->private_value;
2692 struct hda_spdif_out *spdif = snd_array_elem(&codec->spdif_out, idx);
2693 hda_nid_t nid = spdif->nid;
2684 unsigned short val; 2694 unsigned short val;
2685 int change; 2695 int change;
2686 2696
2687 mutex_lock(&codec->spdif_mutex); 2697 mutex_lock(&codec->spdif_mutex);
2688 val = codec->spdif_ctls & ~AC_DIG1_ENABLE; 2698 val = spdif->ctls & ~AC_DIG1_ENABLE;
2689 if (ucontrol->value.integer.value[0]) 2699 if (ucontrol->value.integer.value[0])
2690 val |= AC_DIG1_ENABLE; 2700 val |= AC_DIG1_ENABLE;
2691 change = codec->spdif_ctls != val; 2701 change = spdif->ctls != val;
2692 if (change) { 2702 if (change) {
2693 codec->spdif_ctls = val; 2703 spdif->ctls = val;
2694 set_dig_out_convert(codec, nid, val & 0xff, -1); 2704 set_dig_out_convert(codec, nid, val & 0xff, -1);
2695 /* unmute amp switch (if any) */ 2705 /* unmute amp switch (if any) */
2696 if ((get_wcaps(codec, nid) & AC_WCAP_OUT_AMP) && 2706 if ((get_wcaps(codec, nid) & AC_WCAP_OUT_AMP) &&
@@ -2750,30 +2760,46 @@ int snd_hda_create_spdif_out_ctls(struct hda_codec *codec, hda_nid_t nid)
2750 struct snd_kcontrol *kctl; 2760 struct snd_kcontrol *kctl;
2751 struct snd_kcontrol_new *dig_mix; 2761 struct snd_kcontrol_new *dig_mix;
2752 int idx; 2762 int idx;
2763 struct hda_spdif_out *spdif;
2753 2764
2754 idx = find_empty_mixer_ctl_idx(codec, "IEC958 Playback Switch"); 2765 idx = find_empty_mixer_ctl_idx(codec, "IEC958 Playback Switch");
2755 if (idx < 0) { 2766 if (idx < 0) {
2756 printk(KERN_ERR "hda_codec: too many IEC958 outputs\n"); 2767 printk(KERN_ERR "hda_codec: too many IEC958 outputs\n");
2757 return -EBUSY; 2768 return -EBUSY;
2758 } 2769 }
2770 spdif = snd_array_new(&codec->spdif_out);
2759 for (dig_mix = dig_mixes; dig_mix->name; dig_mix++) { 2771 for (dig_mix = dig_mixes; dig_mix->name; dig_mix++) {
2760 kctl = snd_ctl_new1(dig_mix, codec); 2772 kctl = snd_ctl_new1(dig_mix, codec);
2761 if (!kctl) 2773 if (!kctl)
2762 return -ENOMEM; 2774 return -ENOMEM;
2763 kctl->id.index = idx; 2775 kctl->id.index = idx;
2764 kctl->private_value = nid; 2776 kctl->private_value = codec->spdif_out.used - 1;
2765 err = snd_hda_ctl_add(codec, nid, kctl); 2777 err = snd_hda_ctl_add(codec, nid, kctl);
2766 if (err < 0) 2778 if (err < 0)
2767 return err; 2779 return err;
2768 } 2780 }
2769 codec->spdif_ctls = 2781 spdif->nid = nid;
2770 snd_hda_codec_read(codec, nid, 0, 2782 spdif->ctls = snd_hda_codec_read(codec, nid, 0,
2771 AC_VERB_GET_DIGI_CONVERT_1, 0); 2783 AC_VERB_GET_DIGI_CONVERT_1, 0);
2772 codec->spdif_status = convert_to_spdif_status(codec->spdif_ctls); 2784 spdif->status = convert_to_spdif_status(spdif->ctls);
2773 return 0; 2785 return 0;
2774} 2786}
2775EXPORT_SYMBOL_HDA(snd_hda_create_spdif_out_ctls); 2787EXPORT_SYMBOL_HDA(snd_hda_create_spdif_out_ctls);
2776 2788
2789struct hda_spdif_out *snd_hda_spdif_out_of_nid(struct hda_codec *codec,
2790 hda_nid_t nid)
2791{
2792 int i;
2793 for (i = 0; i < codec->spdif_out.used; i++) {
2794 struct hda_spdif_out *spdif =
2795 snd_array_elem(&codec->spdif_out, i);
2796 if (spdif->nid == nid)
2797 return spdif;
2798 }
2799 return NULL;
2800}
2801EXPORT_SYMBOL_HDA(snd_hda_spdif_out_of_nid);
2802
2777/* 2803/*
2778 * SPDIF sharing with analog output 2804 * SPDIF sharing with analog output
2779 */ 2805 */
@@ -4177,10 +4203,12 @@ EXPORT_SYMBOL_HDA(snd_hda_input_mux_put);
4177static void setup_dig_out_stream(struct hda_codec *codec, hda_nid_t nid, 4203static void setup_dig_out_stream(struct hda_codec *codec, hda_nid_t nid,
4178 unsigned int stream_tag, unsigned int format) 4204 unsigned int stream_tag, unsigned int format)
4179{ 4205{
4206 struct hda_spdif_out *spdif = snd_hda_spdif_out_of_nid(codec, nid);
4207
4180 /* turn off SPDIF once; otherwise the IEC958 bits won't be updated */ 4208 /* turn off SPDIF once; otherwise the IEC958 bits won't be updated */
4181 if (codec->spdif_status_reset && (codec->spdif_ctls & AC_DIG1_ENABLE)) 4209 if (codec->spdif_status_reset && (spdif->ctls & AC_DIG1_ENABLE))
4182 set_dig_out_convert(codec, nid, 4210 set_dig_out_convert(codec, nid,
4183 codec->spdif_ctls & ~AC_DIG1_ENABLE & 0xff, 4211 spdif->ctls & ~AC_DIG1_ENABLE & 0xff,
4184 -1); 4212 -1);
4185 snd_hda_codec_setup_stream(codec, nid, stream_tag, 0, format); 4213 snd_hda_codec_setup_stream(codec, nid, stream_tag, 0, format);
4186 if (codec->slave_dig_outs) { 4214 if (codec->slave_dig_outs) {
@@ -4190,9 +4218,9 @@ static void setup_dig_out_stream(struct hda_codec *codec, hda_nid_t nid,
4190 format); 4218 format);
4191 } 4219 }
4192 /* turn on again (if needed) */ 4220 /* turn on again (if needed) */
4193 if (codec->spdif_status_reset && (codec->spdif_ctls & AC_DIG1_ENABLE)) 4221 if (codec->spdif_status_reset && (spdif->ctls & AC_DIG1_ENABLE))
4194 set_dig_out_convert(codec, nid, 4222 set_dig_out_convert(codec, nid,
4195 codec->spdif_ctls & 0xff, -1); 4223 spdif->ctls & 0xff, -1);
4196} 4224}
4197 4225
4198static void cleanup_dig_out_stream(struct hda_codec *codec, hda_nid_t nid) 4226static void cleanup_dig_out_stream(struct hda_codec *codec, hda_nid_t nid)
@@ -4348,6 +4376,8 @@ int snd_hda_multi_out_analog_prepare(struct hda_codec *codec,
4348{ 4376{
4349 const hda_nid_t *nids = mout->dac_nids; 4377 const hda_nid_t *nids = mout->dac_nids;
4350 int chs = substream->runtime->channels; 4378 int chs = substream->runtime->channels;
4379 struct hda_spdif_out *spdif =
4380 snd_hda_spdif_out_of_nid(codec, mout->dig_out_nid);
4351 int i; 4381 int i;
4352 4382
4353 mutex_lock(&codec->spdif_mutex); 4383 mutex_lock(&codec->spdif_mutex);
@@ -4356,7 +4386,7 @@ int snd_hda_multi_out_analog_prepare(struct hda_codec *codec,
4356 if (chs == 2 && 4386 if (chs == 2 &&
4357 snd_hda_is_supported_format(codec, mout->dig_out_nid, 4387 snd_hda_is_supported_format(codec, mout->dig_out_nid,
4358 format) && 4388 format) &&
4359 !(codec->spdif_status & IEC958_AES0_NONAUDIO)) { 4389 !(spdif->status & IEC958_AES0_NONAUDIO)) {
4360 mout->dig_out_used = HDA_DIG_ANALOG_DUP; 4390 mout->dig_out_used = HDA_DIG_ANALOG_DUP;
4361 setup_dig_out_stream(codec, mout->dig_out_nid, 4391 setup_dig_out_stream(codec, mout->dig_out_nid,
4362 stream_tag, format); 4392 stream_tag, format);
diff --git a/sound/pci/hda/hda_codec.h b/sound/pci/hda/hda_codec.h
index 59c97306c1de..1d21c0624e03 100644
--- a/sound/pci/hda/hda_codec.h
+++ b/sound/pci/hda/hda_codec.h
@@ -829,8 +829,7 @@ struct hda_codec {
829 829
830 struct mutex spdif_mutex; 830 struct mutex spdif_mutex;
831 struct mutex control_mutex; 831 struct mutex control_mutex;
832 unsigned int spdif_status; /* IEC958 status bits */ 832 struct snd_array spdif_out;
833 unsigned short spdif_ctls; /* SPDIF control bits */
834 unsigned int spdif_in_enable; /* SPDIF input enable? */ 833 unsigned int spdif_in_enable; /* SPDIF input enable? */
835 const hda_nid_t *slave_dig_outs; /* optional digital out slave widgets */ 834 const hda_nid_t *slave_dig_outs; /* optional digital out slave widgets */
836 struct snd_array init_pins; /* initial (BIOS) pin configurations */ 835 struct snd_array init_pins; /* initial (BIOS) pin configurations */
@@ -947,6 +946,15 @@ int snd_hda_add_pincfg(struct hda_codec *codec, struct snd_array *list,
947 hda_nid_t nid, unsigned int cfg); /* for hwdep */ 946 hda_nid_t nid, unsigned int cfg); /* for hwdep */
948void snd_hda_shutup_pins(struct hda_codec *codec); 947void snd_hda_shutup_pins(struct hda_codec *codec);
949 948
949/* SPDIF controls */
950struct hda_spdif_out {
951 hda_nid_t nid; /* Converter nid values relate to */
952 unsigned int status; /* IEC958 status bits */
953 unsigned short ctls; /* SPDIF control bits */
954};
955struct hda_spdif_out *snd_hda_spdif_out_of_nid(struct hda_codec *codec,
956 hda_nid_t nid);
957
950/* 958/*
951 * Mixer 959 * Mixer
952 */ 960 */
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c
index 486f6deb3eee..966f40147bc3 100644
--- a/sound/pci/hda/hda_intel.c
+++ b/sound/pci/hda/hda_intel.c
@@ -1706,13 +1706,16 @@ static int azx_pcm_prepare(struct snd_pcm_substream *substream)
1706 struct snd_pcm_runtime *runtime = substream->runtime; 1706 struct snd_pcm_runtime *runtime = substream->runtime;
1707 unsigned int bufsize, period_bytes, format_val, stream_tag; 1707 unsigned int bufsize, period_bytes, format_val, stream_tag;
1708 int err; 1708 int err;
1709 struct hda_spdif_out *spdif =
1710 snd_hda_spdif_out_of_nid(apcm->codec, hinfo->nid);
1711 unsigned short ctls = spdif ? spdif->ctls : 0;
1709 1712
1710 azx_stream_reset(chip, azx_dev); 1713 azx_stream_reset(chip, azx_dev);
1711 format_val = snd_hda_calc_stream_format(runtime->rate, 1714 format_val = snd_hda_calc_stream_format(runtime->rate,
1712 runtime->channels, 1715 runtime->channels,
1713 runtime->format, 1716 runtime->format,
1714 hinfo->maxbps, 1717 hinfo->maxbps,
1715 apcm->codec->spdif_ctls); 1718 ctls);
1716 if (!format_val) { 1719 if (!format_val) {
1717 snd_printk(KERN_ERR SFX 1720 snd_printk(KERN_ERR SFX
1718 "invalid format_val, rate=%d, ch=%d, format=%d\n", 1721 "invalid format_val, rate=%d, ch=%d, format=%d\n",
diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c
index 8ccec72a8f0c..86b35a071a83 100644
--- a/sound/pci/hda/patch_hdmi.c
+++ b/sound/pci/hda/patch_hdmi.c
@@ -1352,6 +1352,9 @@ static int nvhdmi_8ch_7x_pcm_prepare(struct hda_pcm_stream *hinfo,
1352 int chs; 1352 int chs;
1353 unsigned int dataDCC1, dataDCC2, channel_id; 1353 unsigned int dataDCC1, dataDCC2, channel_id;
1354 int i; 1354 int i;
1355 struct hdmi_spec *spec = codec->spec;
1356 struct hda_spdif_out *spdif =
1357 snd_hda_spdif_out_of_nid(codec, spec->cvt[0]);
1355 1358
1356 mutex_lock(&codec->spdif_mutex); 1359 mutex_lock(&codec->spdif_mutex);
1357 1360
@@ -1361,12 +1364,12 @@ static int nvhdmi_8ch_7x_pcm_prepare(struct hda_pcm_stream *hinfo,
1361 dataDCC2 = 0x2; 1364 dataDCC2 = 0x2;
1362 1365
1363 /* turn off SPDIF once; otherwise the IEC958 bits won't be updated */ 1366 /* turn off SPDIF once; otherwise the IEC958 bits won't be updated */
1364 if (codec->spdif_status_reset && (codec->spdif_ctls & AC_DIG1_ENABLE)) 1367 if (codec->spdif_status_reset && (spdif->ctls & AC_DIG1_ENABLE))
1365 snd_hda_codec_write(codec, 1368 snd_hda_codec_write(codec,
1366 nvhdmi_master_con_nid_7x, 1369 nvhdmi_master_con_nid_7x,
1367 0, 1370 0,
1368 AC_VERB_SET_DIGI_CONVERT_1, 1371 AC_VERB_SET_DIGI_CONVERT_1,
1369 codec->spdif_ctls & ~AC_DIG1_ENABLE & 0xff); 1372 spdif->ctls & ~AC_DIG1_ENABLE & 0xff);
1370 1373
1371 /* set the stream id */ 1374 /* set the stream id */
1372 snd_hda_codec_write(codec, nvhdmi_master_con_nid_7x, 0, 1375 snd_hda_codec_write(codec, nvhdmi_master_con_nid_7x, 0,
@@ -1378,12 +1381,12 @@ static int nvhdmi_8ch_7x_pcm_prepare(struct hda_pcm_stream *hinfo,
1378 1381
1379 /* turn on again (if needed) */ 1382 /* turn on again (if needed) */
1380 /* enable and set the channel status audio/data flag */ 1383 /* enable and set the channel status audio/data flag */
1381 if (codec->spdif_status_reset && (codec->spdif_ctls & AC_DIG1_ENABLE)) { 1384 if (codec->spdif_status_reset && (spdif->ctls & AC_DIG1_ENABLE)) {
1382 snd_hda_codec_write(codec, 1385 snd_hda_codec_write(codec,
1383 nvhdmi_master_con_nid_7x, 1386 nvhdmi_master_con_nid_7x,
1384 0, 1387 0,
1385 AC_VERB_SET_DIGI_CONVERT_1, 1388 AC_VERB_SET_DIGI_CONVERT_1,
1386 codec->spdif_ctls & 0xff); 1389 spdif->ctls & 0xff);
1387 snd_hda_codec_write(codec, 1390 snd_hda_codec_write(codec,
1388 nvhdmi_master_con_nid_7x, 1391 nvhdmi_master_con_nid_7x,
1389 0, 1392 0,
@@ -1400,12 +1403,12 @@ static int nvhdmi_8ch_7x_pcm_prepare(struct hda_pcm_stream *hinfo,
1400 *otherwise the IEC958 bits won't be updated 1403 *otherwise the IEC958 bits won't be updated
1401 */ 1404 */
1402 if (codec->spdif_status_reset && 1405 if (codec->spdif_status_reset &&
1403 (codec->spdif_ctls & AC_DIG1_ENABLE)) 1406 (spdif->ctls & AC_DIG1_ENABLE))
1404 snd_hda_codec_write(codec, 1407 snd_hda_codec_write(codec,
1405 nvhdmi_con_nids_7x[i], 1408 nvhdmi_con_nids_7x[i],
1406 0, 1409 0,
1407 AC_VERB_SET_DIGI_CONVERT_1, 1410 AC_VERB_SET_DIGI_CONVERT_1,
1408 codec->spdif_ctls & ~AC_DIG1_ENABLE & 0xff); 1411 spdif->ctls & ~AC_DIG1_ENABLE & 0xff);
1409 /* set the stream id */ 1412 /* set the stream id */
1410 snd_hda_codec_write(codec, 1413 snd_hda_codec_write(codec,
1411 nvhdmi_con_nids_7x[i], 1414 nvhdmi_con_nids_7x[i],
@@ -1421,12 +1424,12 @@ static int nvhdmi_8ch_7x_pcm_prepare(struct hda_pcm_stream *hinfo,
1421 /* turn on again (if needed) */ 1424 /* turn on again (if needed) */
1422 /* enable and set the channel status audio/data flag */ 1425 /* enable and set the channel status audio/data flag */
1423 if (codec->spdif_status_reset && 1426 if (codec->spdif_status_reset &&
1424 (codec->spdif_ctls & AC_DIG1_ENABLE)) { 1427 (spdif->ctls & AC_DIG1_ENABLE)) {
1425 snd_hda_codec_write(codec, 1428 snd_hda_codec_write(codec,
1426 nvhdmi_con_nids_7x[i], 1429 nvhdmi_con_nids_7x[i],
1427 0, 1430 0,
1428 AC_VERB_SET_DIGI_CONVERT_1, 1431 AC_VERB_SET_DIGI_CONVERT_1,
1429 codec->spdif_ctls & 0xff); 1432 spdif->ctls & 0xff);
1430 snd_hda_codec_write(codec, 1433 snd_hda_codec_write(codec,
1431 nvhdmi_con_nids_7x[i], 1434 nvhdmi_con_nids_7x[i],
1432 0, 1435 0,
diff --git a/sound/pci/hda/patch_via.c b/sound/pci/hda/patch_via.c
index 605c99e1e520..8304c748dfb7 100644
--- a/sound/pci/hda/patch_via.c
+++ b/sound/pci/hda/patch_via.c
@@ -1236,28 +1236,30 @@ static void playback_multi_pcm_prep_0(struct hda_codec *codec,
1236 const hda_nid_t *nids = mout->dac_nids; 1236 const hda_nid_t *nids = mout->dac_nids;
1237 int chs = substream->runtime->channels; 1237 int chs = substream->runtime->channels;
1238 int i; 1238 int i;
1239 struct hda_spdif_out *spdif =
1240 snd_hda_spdif_out_of_nid(codec, spec->multiout.dig_out_nid);
1239 1241
1240 mutex_lock(&codec->spdif_mutex); 1242 mutex_lock(&codec->spdif_mutex);
1241 if (mout->dig_out_nid && mout->dig_out_used != HDA_DIG_EXCLUSIVE) { 1243 if (mout->dig_out_nid && mout->dig_out_used != HDA_DIG_EXCLUSIVE) {
1242 if (chs == 2 && 1244 if (chs == 2 &&
1243 snd_hda_is_supported_format(codec, mout->dig_out_nid, 1245 snd_hda_is_supported_format(codec, mout->dig_out_nid,
1244 format) && 1246 format) &&
1245 !(codec->spdif_status & IEC958_AES0_NONAUDIO)) { 1247 !(spdif->status & IEC958_AES0_NONAUDIO)) {
1246 mout->dig_out_used = HDA_DIG_ANALOG_DUP; 1248 mout->dig_out_used = HDA_DIG_ANALOG_DUP;
1247 /* turn off SPDIF once; otherwise the IEC958 bits won't 1249 /* turn off SPDIF once; otherwise the IEC958 bits won't
1248 * be updated */ 1250 * be updated */
1249 if (codec->spdif_ctls & AC_DIG1_ENABLE) 1251 if (spdif->ctls & AC_DIG1_ENABLE)
1250 snd_hda_codec_write(codec, mout->dig_out_nid, 0, 1252 snd_hda_codec_write(codec, mout->dig_out_nid, 0,
1251 AC_VERB_SET_DIGI_CONVERT_1, 1253 AC_VERB_SET_DIGI_CONVERT_1,
1252 codec->spdif_ctls & 1254 spdif->ctls &
1253 ~AC_DIG1_ENABLE & 0xff); 1255 ~AC_DIG1_ENABLE & 0xff);
1254 snd_hda_codec_setup_stream(codec, mout->dig_out_nid, 1256 snd_hda_codec_setup_stream(codec, mout->dig_out_nid,
1255 stream_tag, 0, format); 1257 stream_tag, 0, format);
1256 /* turn on again (if needed) */ 1258 /* turn on again (if needed) */
1257 if (codec->spdif_ctls & AC_DIG1_ENABLE) 1259 if (spdif->ctls & AC_DIG1_ENABLE)
1258 snd_hda_codec_write(codec, mout->dig_out_nid, 0, 1260 snd_hda_codec_write(codec, mout->dig_out_nid, 0,
1259 AC_VERB_SET_DIGI_CONVERT_1, 1261 AC_VERB_SET_DIGI_CONVERT_1,
1260 codec->spdif_ctls & 0xff); 1262 spdif->ctls & 0xff);
1261 } else { 1263 } else {
1262 mout->dig_out_used = 0; 1264 mout->dig_out_used = 0;
1263 snd_hda_codec_setup_stream(codec, mout->dig_out_nid, 1265 snd_hda_codec_setup_stream(codec, mout->dig_out_nid,