[alsa-devel] [PATCH 0/4] Intel HDMI audio fixes
Hi Takashi,
Here are four assorted fixes for Intel HDMI audio. They have been tested in G35 SDVO HDMI and G45 integrated HDMI systems, and shall be OK for 2.6.29.
[PATCH 1/4] hda - allow multi-channel HDMI audio playback when ELD is not present [PATCH 2/4] hda - enable HDMI audio pin out at module loading time [PATCH 3/4] hda - compute checksum in HDMI audio infoframe [PATCH 4/4] hda - add id for Intel IbexPeak integrated HDMI codec
Shane: the first two patches should address the two bugs you reported, i.e. - multi-channel HDMI audio playback problem - first half-second audio samples missing These two bugs was reproduced and fixed in the combination of G35 SDVO HDMI + Yamaha RX-V1800 AV receiver. The first problem cannot be verified in G45 system because we still cannot make G45 work with Yamaha. The second problem is interesting in that it can be fixed by the second patch in G35, but still remains in G45.
Thanks, Fengguang --
The YAMAHA AV-X1800 requires audio infoframe to include speaker-channel mapping to play >2 channel HDMI audio. In theory that mapping should be derived from its speaker configurations contained in its ELD. However we currently cannot get ELD in console before the KMS functionalities are ready. This is a more or less general issue at least in the near future. As a workaround, we propose to allow playback of mult-channel audio when ELD is not available.
Signed-off-by: Wu Fengguang fengguang.wu@intel.com --- sound/pci/hda/patch_intelhdmi.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-)
--- mm.orig/sound/pci/hda/patch_intelhdmi.c +++ mm/sound/pci/hda/patch_intelhdmi.c @@ -419,14 +419,18 @@ static int hdmi_setup_channel_allocation /* * CA defaults to 0 for basic stereo audio */ - if (!eld->eld_ver) - return 0; - if (!eld->spk_alloc) - return 0; if (channels <= 2) return 0;
/* + * HDMI sink's ELD info cannot always be retrieved for now, e.g. + * in console or for audio devices. Assume the highest speakers + * configuration, to _not_ prohibit multi-channel audio playback. + */ + if (!eld->spk_alloc) + eld->spk_alloc = 0xffff; + + /* * expand ELD's speaker allocation mask * * ELD tells the speaker mask in a compact(paired) form,
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 --- sound/pci/hda/patch_intelhdmi.c | 42 +++++++++++++----------------- 1 file changed, 19 insertions(+), 23 deletions(-)
--- mm.orig/sound/pci/hda/patch_intelhdmi.c +++ mm/sound/pci/hda/patch_intelhdmi.c @@ -49,11 +49,6 @@ static struct hda_verb pinout_enable_ver {} /* terminator */ };
-static struct hda_verb pinout_disable_verb[] = { - {PIN_NID, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00}, - {} -}; - static struct hda_verb unsolicited_response_verb[] = { {PIN_NID, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | INTEL_HDMI_EVENT_TAG}, @@ -248,10 +243,6 @@ static void hdmi_write_dip_byte(struct h
static void hdmi_enable_output(struct hda_codec *codec) { - /* Enable Audio InfoFrame Transmission */ - hdmi_set_dip_index(codec, PIN_NID, 0x0, 0x0); - snd_hda_codec_write(codec, PIN_NID, 0, AC_VERB_SET_HDMI_DIP_XMIT, - AC_DIPXMIT_BEST); /* Unmute */ if (get_wcaps(codec, PIN_NID) & AC_WCAP_OUT_AMP) snd_hda_codec_write(codec, PIN_NID, 0, @@ -260,17 +251,24 @@ static void hdmi_enable_output(struct hd snd_hda_sequence_write(codec, pinout_enable_verb); }
-static void hdmi_disable_output(struct hda_codec *codec) +/* + * Enable Audio InfoFrame Transmission + */ +static void hdmi_start_infoframe_trans(struct hda_codec *codec) { - snd_hda_sequence_write(codec, pinout_disable_verb); - if (get_wcaps(codec, PIN_NID) & AC_WCAP_OUT_AMP) - snd_hda_codec_write(codec, PIN_NID, 0, - AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE); + hdmi_set_dip_index(codec, PIN_NID, 0x0, 0x0); + snd_hda_codec_write(codec, PIN_NID, 0, AC_VERB_SET_HDMI_DIP_XMIT, + AC_DIPXMIT_BEST); +}
- /* - * FIXME: noises may arise when playing music after reloading the - * kernel module, until the next X restart or monitor repower. - */ +/* + * Disable Audio InfoFrame Transmission + */ +static void hdmi_stop_infoframe_trans(struct hda_codec *codec) +{ + hdmi_set_dip_index(codec, PIN_NID, 0x0, 0x0); + snd_hda_codec_write(codec, PIN_NID, 0, AC_VERB_SET_HDMI_DIP_XMIT, + AC_DIPXMIT_DISABLE); }
static int hdmi_get_channel_count(struct hda_codec *codec) @@ -489,6 +487,7 @@ static void hdmi_setup_audio_infoframe(s hdmi_setup_channel_mapping(codec, &ai);
hdmi_fill_audio_infoframe(codec, &ai); + hdmi_start_infoframe_trans(codec); }
@@ -566,7 +565,7 @@ static int intel_hdmi_playback_pcm_close { struct intel_hdmi_spec *spec = codec->spec;
- hdmi_disable_output(codec); + hdmi_stop_infoframe_trans(codec);
return snd_hda_multi_out_dig_close(codec, &spec->multiout); } @@ -586,8 +585,6 @@ static int intel_hdmi_playback_pcm_prepa
hdmi_setup_audio_infoframe(codec, substream);
- hdmi_enable_output(codec); - return 0; }
@@ -632,8 +629,7 @@ static int intel_hdmi_build_controls(str
static int intel_hdmi_init(struct hda_codec *codec) { - /* disable audio output as early as possible */ - hdmi_disable_output(codec); + hdmi_enable_output(codec);
snd_hda_sequence_write(codec, unsolicited_response_verb);
Signed-off-by: Wu Fengguang fengguang.wu@intel.com --- sound/pci/hda/patch_intelhdmi.c | 5 +++++ 1 file changed, 5 insertions(+)
--- mm.orig/sound/pci/hda/patch_intelhdmi.c +++ mm/sound/pci/hda/patch_intelhdmi.c @@ -366,11 +366,16 @@ static void hdmi_fill_audio_infoframe(st struct hdmi_audio_infoframe *ai) { u8 *params = (u8 *)ai; + u8 sum = 0; int i;
hdmi_debug_dip_size(codec); hdmi_clear_dip_buffers(codec); /* be paranoid */
+ for (i = 0; i < sizeof(ai); i++) + sum += params[i]; + ai->checksum = - sum; + hdmi_set_dip_index(codec, PIN_NID, 0x0, 0x0); for (i = 0; i < sizeof(ai); i++) hdmi_write_dip_byte(codec, PIN_NID, params[i]);
Signed-off-by: Wu Fengguang fengguang.wu@intel.com --- sound/pci/hda/patch_intelhdmi.c | 2 ++ 1 file changed, 2 insertions(+)
--- mm.orig/sound/pci/hda/patch_intelhdmi.c +++ mm/sound/pci/hda/patch_intelhdmi.c @@ -684,6 +684,7 @@ static struct hda_codec_preset snd_hda_p { .id = 0x80862801, .name = "G45 DEVBLC", .patch = patch_intel_hdmi }, { .id = 0x80862802, .name = "G45 DEVCTG", .patch = patch_intel_hdmi }, { .id = 0x80862803, .name = "G45 DEVELK", .patch = patch_intel_hdmi }, + { .id = 0x80862804, .name = "G45 DEVIBX", .patch = patch_intel_hdmi }, { .id = 0x10951392, .name = "SiI1392 HDMI", .patch = patch_intel_hdmi }, {} /* terminator */ }; @@ -692,6 +693,7 @@ MODULE_ALIAS("snd-hda-codec-id:808629fb" MODULE_ALIAS("snd-hda-codec-id:80862801"); MODULE_ALIAS("snd-hda-codec-id:80862802"); MODULE_ALIAS("snd-hda-codec-id:80862803"); +MODULE_ALIAS("snd-hda-codec-id:80862804"); MODULE_ALIAS("snd-hda-codec-id:10951392");
MODULE_LICENSE("GPL");
At Wed, 11 Feb 2009 15:22:27 +0800, Wu Fengguang wrote:
Hi Takashi,
Here are four assorted fixes for Intel HDMI audio. They have been tested in G35 SDVO HDMI and G45 integrated HDMI systems, and shall be OK for 2.6.29.
[PATCH 1/4] hda - allow multi-channel HDMI audio playback when ELD is not present [PATCH 2/4] hda - enable HDMI audio pin out at module loading time [PATCH 3/4] hda - compute checksum in HDMI audio infoframe [PATCH 4/4] hda - add id for Intel IbexPeak integrated HDMI codec
Thanks, all look good, so applied now. I'll queue them for the next pull request.
Takashi
Shane: the first two patches should address the two bugs you reported, i.e.
- multi-channel HDMI audio playback problem
- first half-second audio samples missing
These two bugs was reproduced and fixed in the combination of G35 SDVO HDMI + Yamaha RX-V1800 AV receiver. The first problem cannot be verified in G45 system because we still cannot make G45 work with Yamaha. The second problem is interesting in that it can be fixed by the second patch in G35, but still remains in G45.
Thanks, Fengguang --
On Wed, Feb 11, 2009 at 10:10:55AM +0200, Takashi Iwai wrote:
At Wed, 11 Feb 2009 15:22:27 +0800, Wu Fengguang wrote:
Hi Takashi,
Here are four assorted fixes for Intel HDMI audio. They have been tested in G35 SDVO HDMI and G45 integrated HDMI systems, and shall be OK for 2.6.29.
[PATCH 1/4] hda - allow multi-channel HDMI audio playback when ELD is not present [PATCH 2/4] hda - enable HDMI audio pin out at module loading time [PATCH 3/4] hda - compute checksum in HDMI audio infoframe [PATCH 4/4] hda - add id for Intel IbexPeak integrated HDMI codec
Thanks, all look good, so applied now. I'll queue them for the next pull request.
Thank you!
Fengguang
participants (2)
-
Takashi Iwai
-
Wu Fengguang