summaryrefslogtreecommitdiff
path: root/sound/pci/hda/patch_hdmi.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/pci/hda/patch_hdmi.c')
-rw-r--r--sound/pci/hda/patch_hdmi.c43
1 files changed, 33 insertions, 10 deletions
diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c
index bcbc4ee10..e68fa449e 100644
--- a/sound/pci/hda/patch_hdmi.c
+++ b/sound/pci/hda/patch_hdmi.c
@@ -152,13 +152,17 @@ struct hdmi_spec {
struct hda_pcm_stream pcm_playback;
/* i915/powerwell (Haswell+/Valleyview+) specific */
+ bool use_acomp_notifier; /* use i915 eld_notify callback for hotplug */
struct i915_audio_component_audio_ops i915_audio_ops;
bool i915_bound; /* was i915 bound in this driver? */
};
#ifdef CONFIG_SND_HDA_I915
-#define codec_has_acomp(codec) \
- ((codec)->bus->core.audio_component != NULL)
+static inline bool codec_has_acomp(struct hda_codec *codec)
+{
+ struct hdmi_spec *spec = codec->spec;
+ return spec->use_acomp_notifier;
+}
#else
#define codec_has_acomp(codec) false
#endif
@@ -1562,6 +1566,7 @@ static void update_eld(struct hda_codec *codec,
eld->eld_size) != 0)
eld_changed = true;
+ pin_eld->monitor_present = eld->monitor_present;
pin_eld->eld_valid = eld->eld_valid;
pin_eld->eld_size = eld->eld_size;
if (eld->eld_valid)
@@ -1665,11 +1670,10 @@ static void sync_eld_via_acomp(struct hda_codec *codec,
int size;
mutex_lock(&per_pin->lock);
+ eld->monitor_present = false;
size = snd_hdac_acomp_get_eld(&codec->bus->core, per_pin->pin_nid,
&eld->monitor_present, eld->eld_buffer,
ELD_MAX_SIZE);
- if (size < 0)
- goto unlock;
if (size > 0) {
size = min(size, ELD_MAX_SIZE);
if (snd_hdmi_parse_eld(codec, &eld->info,
@@ -1873,7 +1877,8 @@ static int generic_hdmi_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
/* Call sync_audio_rate to set the N/CTS/M manually if necessary */
/* Todo: add DP1.2 MST audio support later */
- snd_hdac_sync_audio_rate(&codec->bus->core, pin_nid, runtime->rate);
+ if (codec_has_acomp(codec))
+ snd_hdac_sync_audio_rate(&codec->bus->core, pin_nid, runtime->rate);
non_pcm = check_non_pcm_per_cvt(codec, cvt_nid);
mutex_lock(&per_pin->lock);
@@ -2432,6 +2437,10 @@ static void intel_pin_eld_notify(void *audio_ptr, int port)
struct hda_codec *codec = audio_ptr;
int pin_nid = port + 0x04;
+ /* we assume only from port-B to port-D */
+ if (port < 1 || port > 3)
+ return;
+
/* skip notification during system suspend (but not in runtime PM);
* the state will be updated at resume
*/
@@ -2456,11 +2465,24 @@ static int patch_generic_hdmi(struct hda_codec *codec)
codec->spec = spec;
hdmi_array_init(spec, 4);
- /* Try to bind with i915 for any Intel codecs (if not done yet) */
- if (!codec_has_acomp(codec) &&
- (codec->core.vendor_id >> 16) == 0x8086)
- if (!snd_hdac_i915_init(&codec->bus->core))
- spec->i915_bound = true;
+#ifdef CONFIG_SND_HDA_I915
+ /* Try to bind with i915 for Intel HSW+ codecs (if not done yet) */
+ if ((codec->core.vendor_id >> 16) == 0x8086 &&
+ is_haswell_plus(codec)) {
+#if 0
+ /* on-demand binding leads to an unbalanced refcount when
+ * both i915 and hda drivers are probed concurrently;
+ * disabled temporarily for now
+ */
+ if (!codec->bus->core.audio_component)
+ if (!snd_hdac_i915_init(&codec->bus->core))
+ spec->i915_bound = true;
+#endif
+ /* use i915 audio component notifier for hotplug */
+ if (codec->bus->core.audio_component)
+ spec->use_acomp_notifier = true;
+ }
+#endif
if (is_haswell_plus(codec)) {
intel_haswell_enable_all_pins(codec, true);
@@ -3659,6 +3681,7 @@ HDA_CODEC_ENTRY(0x10de0070, "GPU 70 HDMI/DP", patch_nvhdmi),
HDA_CODEC_ENTRY(0x10de0071, "GPU 71 HDMI/DP", patch_nvhdmi),
HDA_CODEC_ENTRY(0x10de0072, "GPU 72 HDMI/DP", patch_nvhdmi),
HDA_CODEC_ENTRY(0x10de007d, "GPU 7d HDMI/DP", patch_nvhdmi),
+HDA_CODEC_ENTRY(0x10de0082, "GPU 82 HDMI/DP", patch_nvhdmi),
HDA_CODEC_ENTRY(0x10de0083, "GPU 83 HDMI/DP", patch_nvhdmi),
HDA_CODEC_ENTRY(0x10de8001, "MCP73 HDMI", patch_nvhdmi_2ch),
HDA_CODEC_ENTRY(0x11069f80, "VX900 HDMI/DP", patch_via_hdmi),