aboutsummaryrefslogtreecommitdiffstats
path: root/sound
diff options
context:
space:
mode:
Diffstat (limited to 'sound')
-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,