diff options
Diffstat (limited to 'sound')
-rw-r--r-- | sound/pci/hda/hda_codec.c | 80 | ||||
-rw-r--r-- | sound/pci/hda/hda_codec.h | 12 | ||||
-rw-r--r-- | sound/pci/hda/hda_intel.c | 5 | ||||
-rw-r--r-- | sound/pci/hda/patch_hdmi.c | 19 | ||||
-rw-r--r-- | sound/pci/hda/patch_via.c | 12 |
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 | } |
2775 | EXPORT_SYMBOL_HDA(snd_hda_create_spdif_out_ctls); | 2787 | EXPORT_SYMBOL_HDA(snd_hda_create_spdif_out_ctls); |
2776 | 2788 | ||
2789 | struct 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 | } | ||
2801 | EXPORT_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); | |||
4177 | static void setup_dig_out_stream(struct hda_codec *codec, hda_nid_t nid, | 4203 | static 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 | ||
4198 | static void cleanup_dig_out_stream(struct hda_codec *codec, hda_nid_t nid) | 4226 | static 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 */ |
948 | void snd_hda_shutup_pins(struct hda_codec *codec); | 947 | void snd_hda_shutup_pins(struct hda_codec *codec); |
949 | 948 | ||
949 | /* SPDIF controls */ | ||
950 | struct 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 | }; | ||
955 | struct 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, |