diff options
author | Sumit Bhattacharya <sumitb@nvidia.com> | 2011-11-29 02:17:05 +0530 |
---|---|---|
committer | Varun Wadekar <vwadekar@nvidia.com> | 2011-12-08 17:13:10 +0530 |
commit | 855e04ad25df842addc76d9f82ed4faf1c2efae1 (patch) | |
tree | 9a0da9376b6c6ba0e2f28622c1cb3ce64b04517c /sound/pci | |
parent | 3dbacbbe26b577f88294e33af10caa8e5f526dec (diff) |
ALSA: hda: Support disabling of clocks for Tegra
This change is basically a WAR. Tegra T30 HDA controller does not
support presence detect event generateion when all HDA clocks are
off. This change forcefully enables power disabling of HDA chip and
clocks while not in use. As a side effect Tegra HDA driver misses
the unsolicited HDMI plug in event when in power off mode. To overcome
this limitation whenever user space tries to open an HDMI pcm stream
Tegra HDA controller requests HDMI driver to setup presence detect
registers after enabling the chip and waits until it gets valid ELD
data.
Bug 904530
Change-Id: I8c8cb6fe7935ba8b16c421beca68cb1d7f576212
Signed-off-by: Sumit Bhattacharya <sumitb@nvidia.com>
Reviewed-on: http://git-master/r/66972
Reviewed-by: Scott Peterson <speterson@nvidia.com>
Diffstat (limited to 'sound/pci')
-rw-r--r-- | sound/pci/hda/hda_intel.c | 12 | ||||
-rw-r--r-- | sound/pci/hda/patch_hdmi.c | 32 |
2 files changed, 42 insertions, 2 deletions
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index cc32d89e8b03..973e46706cdb 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c @@ -2491,6 +2491,18 @@ static int azx_resume(struct azx *chip) if (snd_hda_codecs_inuse(chip->bus)) azx_init_chip(chip, 1); +#if defined(CONFIG_SND_HDA_PLATFORM_DRIVER) && \ + defined(CONFIG_SND_HDA_POWER_SAVE) + else if (chip->driver_type == AZX_DRIVER_NVIDIA_TEGRA) { + struct hda_bus *bus = chip->bus; + struct hda_codec *c; + + list_for_each_entry(c, &bus->codec_list, list) { + snd_hda_power_up(c); + snd_hda_power_down(c); + } + } +#endif snd_hda_resume(chip->bus); snd_power_change_state(card, SNDRV_CTL_POWER_D0); diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c index e968cc9cbf31..b03efbc17132 100644 --- a/sound/pci/hda/patch_hdmi.c +++ b/sound/pci/hda/patch_hdmi.c @@ -870,6 +870,34 @@ static int hdmi_pcm_open(struct hda_pcm_stream *hinfo, hinfo->formats = per_cvt->formats; hinfo->maxbps = per_cvt->maxbps; +#ifdef CONFIG_SND_HDA_PLATFORM_NVIDIA_TEGRA + if ((codec->preset->id == 0x10de0020) && + (!eld->eld_valid || !eld->sad_count)) { + int err = 0; + unsigned long timeout; + + if (!eld->eld_valid) { + err = tegra_hdmi_setup_hda_presence(); + if (err < 0) { + snd_printk(KERN_WARNING + "HDMI: No HDMI device connected\n"); + return -ENODEV; + } + } + + timeout = jiffies + msecs_to_jiffies(5000); + for (;;) { + if (eld->eld_valid && eld->sad_count) + break; + + if (time_after(jiffies, timeout)) + break; + + mdelay(10); + } + } +#endif + /* Restrict capabilities by ELD if this isn't disabled */ if (!static_hdmi_pcm && eld->eld_valid) { snd_hdmi_eld_update_pcm_info(eld, hinfo); @@ -1062,8 +1090,8 @@ static int hdmi_parse_codec(struct hda_codec *codec) * HDA link is powered off at hot plug or hw initialization time. */ #ifdef CONFIG_SND_HDA_POWER_SAVE - if (!(snd_hda_param_read(codec, codec->afg, AC_PAR_POWER_STATE) & - AC_PWRST_EPSS)) + if ((!(snd_hda_param_read(codec, codec->afg, AC_PAR_POWER_STATE) & + AC_PWRST_EPSS)) && (codec->preset->id != 0x10de0020)) codec->bus->power_keep_link_on = 1; #endif |