diff options
author | Nikesh Oswal <noswal@nvidia.com> | 2012-09-13 14:28:02 +0530 |
---|---|---|
committer | Dan Willemsen <dwillemsen@nvidia.com> | 2013-09-14 12:34:29 -0700 |
commit | ef016d03e928e6be747f8fc9a5425b3c037c932f (patch) | |
tree | 6e3dbf29a53bdb331f6965ac2fea3901c9617f0c /sound/pci | |
parent | ea25ecb53a9045c4a43ba1de643c9c21a04026ed (diff) |
ALSA: hda: check validity of speaker allocation field
Kernel 3.1 hda driver read the eld data once and if
the speaker allocation field was 0 (not set yet by
hdmi driver) then it considers it as 0xFFFF which
allows multichannel and doesn't block it. In Kernel
3.4 hda driver there is a repolling mechanism added
for ELD data, if the ELD data sanity check fails
then HDA driver re-schedules the work unit to poll
ELD data again hence the check on speaker allocation
field was removed. But the NVIDIA hda/hdmi controller
for some reason fails to update the speaker allocation
field and the read data is not valid even after
repeated attempts, hence the ASP channel mapping
happens for default 2 channel case. Adding the check
for speaker allocation field again solves the issue
and multichannel content plays fine over hda/hdmi.
Bug 1045435
Bug 1043021
Change-Id: I79fe33c0e354142f5af16c3ebbb3611a733dd88d
Signed-off-by: Nikesh Oswal <noswal@nvidia.com>
Reviewed-on: http://git-master/r/132128
Reviewed-by: Sumit Bhattacharya <sumitb@nvidia.com>
Reviewed-by: Scott Peterson <speterson@nvidia.com>
Reviewed-by: Ravindra Lokhande <rlokhande@nvidia.com>
Rebase-Id: Racb3856e878119e64f393a578e9c6cae0e3ab4f4
Diffstat (limited to 'sound/pci')
-rw-r--r-- | sound/pci/hda/patch_hdmi.c | 32 |
1 files changed, 32 insertions, 0 deletions
diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c index e975fe5661f6..d048fa1f9418 100644 --- a/sound/pci/hda/patch_hdmi.c +++ b/sound/pci/hda/patch_hdmi.c @@ -964,6 +964,9 @@ static void hdmi_intrinsic_event(struct hda_codec *codec, unsigned int res) int pin_nid; int pin_idx; struct hda_jack_tbl *jack; +#ifdef CONFIG_SND_HDA_PLATFORM_NVIDIA_TEGRA + struct hdmi_eld *eld = &spec->pins[pin_idx].sink_eld; +#endif jack = snd_hda_jack_tbl_get_from_tag(codec, tag); if (!jack) @@ -981,6 +984,19 @@ static void hdmi_intrinsic_event(struct hda_codec *codec, unsigned int res) return; hdmi_present_sense(get_pin(spec, pin_idx), 1); + +#ifdef CONFIG_SND_HDA_PLATFORM_NVIDIA_TEGRA + if (codec->preset->id == 0x10de0020) { + /* + * 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; + } +#endif + snd_hda_jack_report_sync(codec); } @@ -1305,11 +1321,27 @@ static void hdmi_repoll_eld(struct work_struct *work) { struct hdmi_spec_per_pin *per_pin = container_of(to_delayed_work(work), struct hdmi_spec_per_pin, work); +#ifdef CONFIG_SND_HDA_PLATFORM_NVIDIA_TEGRA + struct hda_codec *codec = per_pin->codec; + struct hdmi_eld *eld = &per_pin->sink_eld; +#endif if (per_pin->repoll_count++ > 6) per_pin->repoll_count = 0; hdmi_present_sense(per_pin, per_pin->repoll_count); + +#ifdef CONFIG_SND_HDA_PLATFORM_NVIDIA_TEGRA + if (codec->preset->id == 0x10de0020) { + /* + * 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; + } +#endif } static void intel_haswell_fixup_connect_list(struct hda_codec *codec, |