codec->spdif_ctls = val;
if (change) {
+ hda_nid_t *d;
snd_hda_codec_write_cache(codec, nid, 0,
AC_VERB_SET_DIGI_CONVERT_1,
val & 0xff);
snd_hda_codec_write_cache(codec, nid, 0,
AC_VERB_SET_DIGI_CONVERT_2,
val >> 8);
+
+ for (d = codec->slave_dig_outs; *d; d++) {
+ snd_hda_codec_write_cache(codec, *d, 0,
+ AC_VERB_SET_DIGI_CONVERT_1,
+ val & 0xff);
+ snd_hda_codec_write_cache(codec, *d, 0,
+ AC_VERB_SET_DIGI_CONVERT_2,
+ val >> 8);
+ }
}
mutex_unlock(&codec->spdif_mutex);
val |= AC_DIG1_ENABLE;
change = codec->spdif_ctls != val;
if (change) {
+ hda_nid_t *d;
codec->spdif_ctls = val;
snd_hda_codec_write_cache(codec, nid, 0,
AC_VERB_SET_DIGI_CONVERT_1,
val & 0xff);
+
+ for (d = codec->slave_dig_outs; *d; d++)
+ snd_hda_codec_write_cache(codec, *d, 0,
+ AC_VERB_SET_DIGI_CONVERT_1,
+ val & 0xff);
/* unmute amp switch (if any) */
if ((get_wcaps(codec, nid) & AC_WCAP_OUT_AMP) &&
(val & AC_DIG1_ENABLE))
mutex_lock(&codec->spdif_mutex);
change = codec->spdif_in_enable != val;
if (change) {
+ hda_nid_t *d;
codec->spdif_in_enable = val;
snd_hda_codec_write_cache(codec, nid, 0,
AC_VERB_SET_DIGI_CONVERT_1, val);
+
+ for (d = codec->slave_dig_outs; *d; d++)
+ snd_hda_codec_write_cache(codec, *d, 0,
+ AC_VERB_SET_DIGI_CONVERT_1, val);
}
mutex_unlock(&codec->spdif_mutex);
return change;
static void setup_dig_out_stream(struct hda_codec *codec, hda_nid_t nid,
unsigned int stream_tag, unsigned int format)
{
+ hda_nid_t *d;
+
/* turn off SPDIF once; otherwise the IEC958 bits won't be updated */
- if (codec->spdif_status_reset && (codec->spdif_ctls & AC_DIG1_ENABLE))
+ if (codec->spdif_status_reset && (codec->spdif_ctls & AC_DIG1_ENABLE)) {
snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1,
+ codec->spdif_ctls & ~AC_DIG1_ENABLE & 0xff);
+
+ for (d = codec->slave_dig_outs; *d; d++)
+ snd_hda_codec_write(codec, *d, 0,
+ AC_VERB_SET_DIGI_CONVERT_1,
codec->spdif_ctls & ~AC_DIG1_ENABLE & 0xff);
+ }
snd_hda_codec_setup_stream(codec, nid, stream_tag, 0, format);
/* turn on again (if needed) */
- if (codec->spdif_status_reset && (codec->spdif_ctls & AC_DIG1_ENABLE))
+ if (codec->spdif_status_reset && (codec->spdif_ctls & AC_DIG1_ENABLE)) {
snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1,
codec->spdif_ctls & 0xff);
+
+ for (d = codec->slave_dig_outs; *d; d++)
+ snd_hda_codec_write(codec, *d, 0,
+ AC_VERB_SET_DIGI_CONVERT_1,
+ codec->spdif_ctls & 0xff);
+ }
+
}
/*
unsigned int format,
struct snd_pcm_substream *substream)
{
+ hda_nid_t *nid;
mutex_lock(&codec->spdif_mutex);
setup_dig_out_stream(codec, mout->dig_out_nid, stream_tag, format);
+ if (codec->slave_dig_outs)
+ for (nid = codec->slave_dig_outs; *nid; nid++)
+ setup_dig_out_stream(codec, *nid, stream_tag, format);
mutex_unlock(&codec->spdif_mutex);
return 0;
}
struct snd_pcm_substream *substream)
{
hda_nid_t *nids = mout->dac_nids;
+ hda_nid_t *d;
int chs = substream->runtime->channels;
int i;
mout->dig_out_used = HDA_DIG_ANALOG_DUP;
setup_dig_out_stream(codec, mout->dig_out_nid,
stream_tag, format);
+ if (codec->slave_dig_outs)
+ for (d = codec->slave_dig_outs; *d; d++)
+ setup_dig_out_stream(codec, *d,
+ stream_tag, format);
} else {
mout->dig_out_used = 0;
snd_hda_codec_cleanup_stream(codec, mout->dig_out_nid);
+ if (codec->slave_dig_outs)
+ for (d = codec->slave_dig_outs; *d; d++)
+ snd_hda_codec_cleanup_stream(codec, *d);
}
}
mutex_unlock(&codec->spdif_mutex);