]> git.karo-electronics.de Git - linux-beck.git/blobdiff - sound/pci/hda/patch_hdmi.c
Merge branch 'test/hda-jack' into topic/hda
[linux-beck.git] / sound / pci / hda / patch_hdmi.c
index 6e0756febb2e4753fd1f6c1bb13b9363c64190f1..3f42cc965b464938c86924b913c77cbcdf5c49a3 100644 (file)
@@ -36,6 +36,7 @@
 #include <sound/jack.h>
 #include "hda_codec.h"
 #include "hda_local.h"
+#include "hda_jack.h"
 
 static bool static_hdmi_pcm;
 module_param(static_hdmi_pcm, bool, 0644);
@@ -754,10 +755,18 @@ static void hdmi_present_sense(struct hdmi_spec_per_pin *per_pin, int repoll);
 static void hdmi_intrinsic_event(struct hda_codec *codec, unsigned int res)
 {
        struct hdmi_spec *spec = codec->spec;
-       int pin_nid = res >> AC_UNSOL_RES_TAG_SHIFT;
+       int tag = res >> AC_UNSOL_RES_TAG_SHIFT;
+       int pin_nid;
        int pd = !!(res & AC_UNSOL_RES_PD);
        int eldv = !!(res & AC_UNSOL_RES_ELDV);
        int pin_idx;
+       struct hda_jack_tbl *jack;
+
+       jack = snd_hda_jack_tbl_get_from_tag(codec, tag);
+       if (!jack)
+               return;
+       pin_nid = jack->nid;
+       jack->jack_dirty = 1;
 
        printk(KERN_INFO
                "HDMI hot plug event: Codec=%d Pin=%d Presence_Detect=%d ELD_Valid=%d\n",
@@ -768,6 +777,7 @@ static void hdmi_intrinsic_event(struct hda_codec *codec, unsigned int res)
                return;
 
        hdmi_present_sense(&spec->pins[pin_idx], 1);
+       snd_hda_jack_report_sync(codec);
 }
 
 static void hdmi_non_intrinsic_event(struct hda_codec *codec, unsigned int res)
@@ -799,7 +809,7 @@ static void hdmi_unsol_event(struct hda_codec *codec, unsigned int res)
        int tag = res >> AC_UNSOL_RES_TAG_SHIFT;
        int subtag = (res & AC_UNSOL_RES_SUBTAG) >> AC_UNSOL_RES_SUBTAG_SHIFT;
 
-       if (pin_nid_to_pin_index(spec, tag) < 0) {
+       if (!snd_hda_jack_tbl_get_from_tag(codec, tag)) {
                snd_printd(KERN_INFO "Unexpected HDMI event tag 0x%x\n", tag);
                return;
        }
@@ -996,8 +1006,6 @@ static void hdmi_present_sense(struct hdmi_spec_per_pin *per_pin, int repoll)
                                           msecs_to_jiffies(300));
                }
        }
-
-       snd_hda_input_jack_report(codec, pin_nid);
 }
 
 static void hdmi_repoll_eld(struct work_struct *work)
@@ -1226,21 +1234,16 @@ static int generic_hdmi_build_pcms(struct hda_codec *codec)
 
 static int generic_hdmi_build_jack(struct hda_codec *codec, int pin_idx)
 {
-       int err;
-       char hdmi_str[32];
+       char hdmi_str[32] = "HDMI/DP";
        struct hdmi_spec *spec = codec->spec;
        struct hdmi_spec_per_pin *per_pin = &spec->pins[pin_idx];
        int pcmdev = spec->pcm_rec[pin_idx].device;
 
-       snprintf(hdmi_str, sizeof(hdmi_str), "HDMI/DP,pcm=%d", pcmdev);
-
-       err = snd_hda_input_jack_add(codec, per_pin->pin_nid,
-                            SND_JACK_VIDEOOUT, pcmdev > 0 ? hdmi_str : NULL);
-       if (err < 0)
-               return err;
+       if (pcmdev > 0)
+               sprintf(hdmi_str + strlen(hdmi_str), ",pcm=%d", pcmdev);
 
        hdmi_present_sense(per_pin, 0);
-       return 0;
+       return snd_hda_jack_add_kctl(codec, per_pin->pin_nid, hdmi_str, 0);
 }
 
 static int generic_hdmi_build_controls(struct hda_codec *codec)
@@ -1270,6 +1273,8 @@ static int generic_hdmi_build_controls(struct hda_codec *codec)
 
                if (err < 0)
                        return err;
+
+               hdmi_present_sense(per_pin, false);
        }
 
        return 0;
@@ -1286,14 +1291,13 @@ static int generic_hdmi_init(struct hda_codec *codec)
                struct hdmi_eld *eld = &per_pin->sink_eld;
 
                hdmi_init_pin(codec, pin_nid);
-               snd_hda_codec_write(codec, pin_nid, 0,
-                                   AC_VERB_SET_UNSOLICITED_ENABLE,
-                                   AC_USRSP_EN | pin_nid);
+               snd_hda_jack_detect_enable(codec, pin_nid, pin_nid);
 
                per_pin->codec = codec;
                INIT_DELAYED_WORK(&per_pin->work, hdmi_repoll_eld);
                snd_hda_eld_proc_new(codec, eld, pin_idx);
        }
+       snd_hda_jack_report_sync(codec);
        return 0;
 }
 
@@ -1309,7 +1313,6 @@ static void generic_hdmi_free(struct hda_codec *codec)
                cancel_delayed_work(&per_pin->work);
                snd_hda_eld_proc_free(codec, eld);
        }
-       snd_hda_input_jack_free(codec);
 
        flush_workqueue(codec->bus->workq);
        kfree(spec);