diff options
Diffstat (limited to 'sound/pci/hda/patch_hdmi.c')
-rw-r--r-- | sound/pci/hda/patch_hdmi.c | 62 |
1 files changed, 60 insertions, 2 deletions
diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c index e287015cbbb3..b03efbc17132 100644 --- a/sound/pci/hda/patch_hdmi.c +++ b/sound/pci/hda/patch_hdmi.c @@ -34,6 +34,11 @@ #include <linux/moduleparam.h> #include <sound/core.h> #include <sound/jack.h> + +#ifdef CONFIG_SND_HDA_PLATFORM_NVIDIA_TEGRA +#include <mach/hdmi-audio.h> +#endif + #include "hda_codec.h" #include "hda_local.h" @@ -865,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); @@ -1057,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 @@ -1089,6 +1122,21 @@ static int generic_hdmi_playback_pcm_prepare(struct hda_pcm_stream *hinfo, int pin_idx = hinfo_to_pin_index(spec, hinfo); hda_nid_t pin_nid = spec->pins[pin_idx].pin_nid; +#if defined(CONFIG_SND_HDA_PLATFORM_NVIDIA_TEGRA) && defined(CONFIG_TEGRA_DC) + if (codec->preset->id == 0x10de0020) { + int err = 0; + /* Set hdmi:audio freq and source selection*/ + err = tegra_hdmi_setup_audio_freq_source( + substream->runtime->rate, HDA); + if ( err < 0 ) { + snd_printk(KERN_ERR + "Unable to set hdmi audio freq to %d \n", + substream->runtime->rate); + return err; + } + } +#endif + hdmi_set_channel_count(codec, cvt_nid, substream->runtime->channels); hdmi_setup_audio_infoframe(codec, pin_idx, substream); @@ -1189,6 +1237,14 @@ static int generic_hdmi_init(struct hda_codec *codec) struct hdmi_spec *spec = codec->spec; int pin_idx; + switch (codec->preset->id) { + case 0x10de0020: + snd_hda_codec_write(codec, 4, 0, + AC_VERB_SET_DIGI_CONVERT_1, 0x11); + default: + break; + } + for (pin_idx = 0; pin_idx < spec->num_pins; pin_idx++) { struct hdmi_spec_per_pin *per_pin = &spec->pins[pin_idx]; hda_nid_t pin_nid = per_pin->pin_nid; @@ -1803,6 +1859,7 @@ static const struct hda_codec_preset snd_hda_preset_hdmi[] = { { .id = 0x10de001a, .name = "GPU 1a HDMI/DP", .patch = patch_generic_hdmi }, { .id = 0x10de001b, .name = "GPU 1b HDMI/DP", .patch = patch_generic_hdmi }, { .id = 0x10de001c, .name = "GPU 1c HDMI/DP", .patch = patch_generic_hdmi }, +{ .id = 0x10de0020, .name = "Tegra30 HDMI", .patch = patch_generic_hdmi }, { .id = 0x10de0040, .name = "GPU 40 HDMI/DP", .patch = patch_generic_hdmi }, { .id = 0x10de0041, .name = "GPU 41 HDMI/DP", .patch = patch_generic_hdmi }, { .id = 0x10de0042, .name = "GPU 42 HDMI/DP", .patch = patch_generic_hdmi }, @@ -1848,6 +1905,7 @@ MODULE_ALIAS("snd-hda-codec-id:10de0019"); MODULE_ALIAS("snd-hda-codec-id:10de001a"); MODULE_ALIAS("snd-hda-codec-id:10de001b"); MODULE_ALIAS("snd-hda-codec-id:10de001c"); +MODULE_ALIAS("snd-hda-codec-id:10de0020"); MODULE_ALIAS("snd-hda-codec-id:10de0040"); MODULE_ALIAS("snd-hda-codec-id:10de0041"); MODULE_ALIAS("snd-hda-codec-id:10de0042"); |