diff options
author | Wu Fengguang <fengguang.wu@intel.com> | 2009-02-11 02:22:29 -0500 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2009-02-11 03:08:59 -0500 |
commit | 606c0cee695bbd0c2bf32132999e35cff5a6dd9e (patch) | |
tree | 0e180183852098d0349eec5419f747d5ea2c8ca9 /sound/pci | |
parent | a1667e4eea0a7085815d1532d7630bb4611271d0 (diff) |
ALSA: hda - enable HDMI audio pin out at module loading time
We found that enabling/disabling HDMI audio pin out at stream start/stop
time will kill the leading 500ms or so sound samples. Avoid this by enabling
pin out once and for ever at module loading time.
The leading ~500ms audio samples will still be lost when switching from
X-channel playback to Y-channel playback where X != Y. However there's no
much we can do about it: the audio infoframe has to change and it looks like
either G45 or YAMAHA requires some time to switch the configuration.
Signed-off-by: Wu Fengguang <fengguang.wu@intel.com>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound/pci')
-rw-r--r-- | sound/pci/hda/patch_intelhdmi.c | 42 |
1 files changed, 19 insertions, 23 deletions
diff --git a/sound/pci/hda/patch_intelhdmi.c b/sound/pci/hda/patch_intelhdmi.c index a8643509e2af..f2610d67e187 100644 --- a/sound/pci/hda/patch_intelhdmi.c +++ b/sound/pci/hda/patch_intelhdmi.c | |||
@@ -49,11 +49,6 @@ static struct hda_verb pinout_enable_verb[] = { | |||
49 | {} /* terminator */ | 49 | {} /* terminator */ |
50 | }; | 50 | }; |
51 | 51 | ||
52 | static struct hda_verb pinout_disable_verb[] = { | ||
53 | {PIN_NID, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00}, | ||
54 | {} | ||
55 | }; | ||
56 | |||
57 | static struct hda_verb unsolicited_response_verb[] = { | 52 | static struct hda_verb unsolicited_response_verb[] = { |
58 | {PIN_NID, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | | 53 | {PIN_NID, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | |
59 | INTEL_HDMI_EVENT_TAG}, | 54 | INTEL_HDMI_EVENT_TAG}, |
@@ -248,10 +243,6 @@ static void hdmi_write_dip_byte(struct hda_codec *codec, hda_nid_t nid, | |||
248 | 243 | ||
249 | static void hdmi_enable_output(struct hda_codec *codec) | 244 | static void hdmi_enable_output(struct hda_codec *codec) |
250 | { | 245 | { |
251 | /* Enable Audio InfoFrame Transmission */ | ||
252 | hdmi_set_dip_index(codec, PIN_NID, 0x0, 0x0); | ||
253 | snd_hda_codec_write(codec, PIN_NID, 0, AC_VERB_SET_HDMI_DIP_XMIT, | ||
254 | AC_DIPXMIT_BEST); | ||
255 | /* Unmute */ | 246 | /* Unmute */ |
256 | if (get_wcaps(codec, PIN_NID) & AC_WCAP_OUT_AMP) | 247 | if (get_wcaps(codec, PIN_NID) & AC_WCAP_OUT_AMP) |
257 | snd_hda_codec_write(codec, PIN_NID, 0, | 248 | snd_hda_codec_write(codec, PIN_NID, 0, |
@@ -260,17 +251,24 @@ static void hdmi_enable_output(struct hda_codec *codec) | |||
260 | snd_hda_sequence_write(codec, pinout_enable_verb); | 251 | snd_hda_sequence_write(codec, pinout_enable_verb); |
261 | } | 252 | } |
262 | 253 | ||
263 | static void hdmi_disable_output(struct hda_codec *codec) | 254 | /* |
255 | * Enable Audio InfoFrame Transmission | ||
256 | */ | ||
257 | static void hdmi_start_infoframe_trans(struct hda_codec *codec) | ||
264 | { | 258 | { |
265 | snd_hda_sequence_write(codec, pinout_disable_verb); | 259 | hdmi_set_dip_index(codec, PIN_NID, 0x0, 0x0); |
266 | if (get_wcaps(codec, PIN_NID) & AC_WCAP_OUT_AMP) | 260 | snd_hda_codec_write(codec, PIN_NID, 0, AC_VERB_SET_HDMI_DIP_XMIT, |
267 | snd_hda_codec_write(codec, PIN_NID, 0, | 261 | AC_DIPXMIT_BEST); |
268 | AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE); | 262 | } |
269 | 263 | ||
270 | /* | 264 | /* |
271 | * FIXME: noises may arise when playing music after reloading the | 265 | * Disable Audio InfoFrame Transmission |
272 | * kernel module, until the next X restart or monitor repower. | 266 | */ |
273 | */ | 267 | static void hdmi_stop_infoframe_trans(struct hda_codec *codec) |
268 | { | ||
269 | hdmi_set_dip_index(codec, PIN_NID, 0x0, 0x0); | ||
270 | snd_hda_codec_write(codec, PIN_NID, 0, AC_VERB_SET_HDMI_DIP_XMIT, | ||
271 | AC_DIPXMIT_DISABLE); | ||
274 | } | 272 | } |
275 | 273 | ||
276 | static int hdmi_get_channel_count(struct hda_codec *codec) | 274 | static int hdmi_get_channel_count(struct hda_codec *codec) |
@@ -489,6 +487,7 @@ static void hdmi_setup_audio_infoframe(struct hda_codec *codec, | |||
489 | hdmi_setup_channel_mapping(codec, &ai); | 487 | hdmi_setup_channel_mapping(codec, &ai); |
490 | 488 | ||
491 | hdmi_fill_audio_infoframe(codec, &ai); | 489 | hdmi_fill_audio_infoframe(codec, &ai); |
490 | hdmi_start_infoframe_trans(codec); | ||
492 | } | 491 | } |
493 | 492 | ||
494 | 493 | ||
@@ -566,7 +565,7 @@ static int intel_hdmi_playback_pcm_close(struct hda_pcm_stream *hinfo, | |||
566 | { | 565 | { |
567 | struct intel_hdmi_spec *spec = codec->spec; | 566 | struct intel_hdmi_spec *spec = codec->spec; |
568 | 567 | ||
569 | hdmi_disable_output(codec); | 568 | hdmi_stop_infoframe_trans(codec); |
570 | 569 | ||
571 | return snd_hda_multi_out_dig_close(codec, &spec->multiout); | 570 | return snd_hda_multi_out_dig_close(codec, &spec->multiout); |
572 | } | 571 | } |
@@ -586,8 +585,6 @@ static int intel_hdmi_playback_pcm_prepare(struct hda_pcm_stream *hinfo, | |||
586 | 585 | ||
587 | hdmi_setup_audio_infoframe(codec, substream); | 586 | hdmi_setup_audio_infoframe(codec, substream); |
588 | 587 | ||
589 | hdmi_enable_output(codec); | ||
590 | |||
591 | return 0; | 588 | return 0; |
592 | } | 589 | } |
593 | 590 | ||
@@ -632,8 +629,7 @@ static int intel_hdmi_build_controls(struct hda_codec *codec) | |||
632 | 629 | ||
633 | static int intel_hdmi_init(struct hda_codec *codec) | 630 | static int intel_hdmi_init(struct hda_codec *codec) |
634 | { | 631 | { |
635 | /* disable audio output as early as possible */ | 632 | hdmi_enable_output(codec); |
636 | hdmi_disable_output(codec); | ||
637 | 633 | ||
638 | snd_hda_sequence_write(codec, unsolicited_response_verb); | 634 | snd_hda_sequence_write(codec, unsolicited_response_verb); |
639 | 635 | ||