Merge branch 'for-linus' into for-next
[cascardo/linux.git] / sound / pci / hda / patch_hdmi.c
index 7e09f5e..d2e57c7 100644 (file)
@@ -1397,7 +1397,6 @@ static bool hdmi_present_sense_via_verbs(struct hdmi_spec_per_pin *per_pin,
        struct hda_codec *codec = per_pin->codec;
        struct hdmi_spec *spec = codec->spec;
        struct hdmi_eld *eld = &spec->temp_eld;
-       struct hdmi_eld *pin_eld = &per_pin->sink_eld;
        hda_nid_t pin_nid = per_pin->pin_nid;
        /*
         * Always execute a GetPinSense verb here, even when called from
@@ -1414,15 +1413,15 @@ static bool hdmi_present_sense_via_verbs(struct hdmi_spec_per_pin *per_pin,
        present = snd_hda_pin_sense(codec, pin_nid);
 
        mutex_lock(&per_pin->lock);
-       pin_eld->monitor_present = !!(present & AC_PINSENSE_PRESENCE);
-       if (pin_eld->monitor_present)
+       eld->monitor_present = !!(present & AC_PINSENSE_PRESENCE);
+       if (eld->monitor_present)
                eld->eld_valid  = !!(present & AC_PINSENSE_ELDV);
        else
                eld->eld_valid = false;
 
        codec_dbg(codec,
                "HDMI status: Codec=%d Pin=%d Presence_Detect=%d ELD_Valid=%d\n",
-               codec->addr, pin_nid, pin_eld->monitor_present, eld->eld_valid);
+               codec->addr, pin_nid, eld->monitor_present, eld->eld_valid);
 
        if (eld->eld_valid) {
                if (spec->ops.pin_get_eld(codec, pin_nid, eld->eld_buffer,
@@ -1442,7 +1441,7 @@ static bool hdmi_present_sense_via_verbs(struct hdmi_spec_per_pin *per_pin,
        else
                update_eld(codec, per_pin, eld);
 
-       ret = !repoll || !pin_eld->monitor_present || pin_eld->eld_valid;
+       ret = !repoll || !eld->monitor_present || eld->eld_valid;
 
        jack = snd_hda_jack_tbl_get(codec, pin_nid);
        if (jack)
@@ -1837,6 +1836,18 @@ static const struct hda_pcm_ops generic_ops = {
        .cleanup = generic_hdmi_playback_pcm_cleanup,
 };
 
+static int hdmi_get_spk_alloc(struct hdac_device *hdac, int pcm_idx)
+{
+       struct hda_codec *codec = container_of(hdac, struct hda_codec, core);
+       struct hdmi_spec *spec = codec->spec;
+       struct hdmi_spec_per_pin *per_pin = pcm_idx_to_pin(spec, pcm_idx);
+
+       if (!per_pin)
+               return 0;
+
+       return per_pin->sink_eld.info.spk_alloc;
+}
+
 static void hdmi_get_chmap(struct hdac_device *hdac, int pcm_idx,
                                        unsigned char *chmap)
 {
@@ -1858,6 +1869,8 @@ static void hdmi_set_chmap(struct hdac_device *hdac, int pcm_idx,
        struct hdmi_spec *spec = codec->spec;
        struct hdmi_spec_per_pin *per_pin = pcm_idx_to_pin(spec, pcm_idx);
 
+       if (!per_pin)
+               return;
        mutex_lock(&per_pin->lock);
        per_pin->chmap_set = true;
        memcpy(per_pin->chmap, chmap, ARRAY_SIZE(per_pin->chmap));
@@ -2165,6 +2178,7 @@ static int alloc_generic_hdmi(struct hda_codec *codec)
        spec->chmap.ops.get_chmap = hdmi_get_chmap;
        spec->chmap.ops.set_chmap = hdmi_set_chmap;
        spec->chmap.ops.is_pcm_attached = is_hdmi_pcm_attached;
+       spec->chmap.ops.get_spk_alloc = hdmi_get_spk_alloc,
 
        codec->spec = spec;
        hdmi_array_init(spec, 4);
@@ -2274,12 +2288,23 @@ static void haswell_set_power_state(struct hda_codec *codec, hda_nid_t fg,
 static void intel_pin_eld_notify(void *audio_ptr, int port)
 {
        struct hda_codec *codec = audio_ptr;
-       int pin_nid = port + 0x04;
+       int pin_nid;
 
        /* we assume only from port-B to port-D */
        if (port < 1 || port > 3)
                return;
 
+       switch (codec->core.vendor_id) {
+       case 0x80860054: /* ILK */
+       case 0x80862804: /* ILK */
+       case 0x80862882: /* VLV */
+               pin_nid = port + 0x03;
+               break;
+       default:
+               pin_nid = port + 0x04;
+               break;
+       }
+
        /* skip notification during system suspend (but not in runtime PM);
         * the state will be updated at resume
         */
@@ -2289,6 +2314,7 @@ static void intel_pin_eld_notify(void *audio_ptr, int port)
        if (atomic_read(&(codec)->core.in_pm))
                return;
 
+       snd_hdac_i915_set_bclk(&codec->bus->core);
        check_presence_and_report(codec, pin_nid);
 }
 
@@ -2375,7 +2401,7 @@ static int patch_i915_hsw_hdmi(struct hda_codec *codec)
        return 0;
 }
 
-/* Intel Baytrail and Braswell; without get_eld notifier */
+/* Intel Baytrail and Braswell; with eld notifier */
 static int patch_i915_byt_hdmi(struct hda_codec *codec)
 {
        struct hdmi_spec *spec;
@@ -2409,10 +2435,11 @@ static int patch_i915_byt_hdmi(struct hda_codec *codec)
        }
 
        generic_hdmi_init_per_pins(codec);
+       register_i915_notifier(codec);
        return 0;
 }
 
-/* Intel SandyBridge and IvyBridge; with i915 eld notifier */
+/* Intel IronLake, SandyBridge and IvyBridge; with eld notifier */
 static int patch_i915_cpt_hdmi(struct hda_codec *codec)
 {
        struct hdmi_spec *spec;
@@ -3614,11 +3641,11 @@ HDA_CODEC_ENTRY(0x11069f80, "VX900 HDMI/DP",    patch_via_hdmi),
 HDA_CODEC_ENTRY(0x11069f81, "VX900 HDMI/DP",   patch_via_hdmi),
 HDA_CODEC_ENTRY(0x11069f84, "VX11 HDMI/DP",    patch_generic_hdmi),
 HDA_CODEC_ENTRY(0x11069f85, "VX11 HDMI/DP",    patch_generic_hdmi),
-HDA_CODEC_ENTRY(0x80860054, "IbexPeak HDMI",   patch_generic_hdmi),
+HDA_CODEC_ENTRY(0x80860054, "IbexPeak HDMI",   patch_i915_cpt_hdmi),
 HDA_CODEC_ENTRY(0x80862801, "Bearlake HDMI",   patch_generic_hdmi),
 HDA_CODEC_ENTRY(0x80862802, "Cantiga HDMI",    patch_generic_hdmi),
 HDA_CODEC_ENTRY(0x80862803, "Eaglelake HDMI",  patch_generic_hdmi),
-HDA_CODEC_ENTRY(0x80862804, "IbexPeak HDMI",   patch_generic_hdmi),
+HDA_CODEC_ENTRY(0x80862804, "IbexPeak HDMI",   patch_i915_cpt_hdmi),
 HDA_CODEC_ENTRY(0x80862805, "CougarPoint HDMI",        patch_i915_cpt_hdmi),
 HDA_CODEC_ENTRY(0x80862806, "PantherPoint HDMI", patch_i915_cpt_hdmi),
 HDA_CODEC_ENTRY(0x80862807, "Haswell HDMI",    patch_i915_hsw_hdmi),