aboutsummaryrefslogtreecommitdiffstats
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.c37
1 files changed, 20 insertions, 17 deletions
diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c
index 6e0756febb2e..3f42cc965b46 100644
--- a/sound/pci/hda/patch_hdmi.c
+++ b/sound/pci/hda/patch_hdmi.c
@@ -36,6 +36,7 @@
36#include <sound/jack.h> 36#include <sound/jack.h>
37#include "hda_codec.h" 37#include "hda_codec.h"
38#include "hda_local.h" 38#include "hda_local.h"
39#include "hda_jack.h"
39 40
40static bool static_hdmi_pcm; 41static bool static_hdmi_pcm;
41module_param(static_hdmi_pcm, bool, 0644); 42module_param(static_hdmi_pcm, bool, 0644);
@@ -754,10 +755,18 @@ static void hdmi_present_sense(struct hdmi_spec_per_pin *per_pin, int repoll);
754static void hdmi_intrinsic_event(struct hda_codec *codec, unsigned int res) 755static void hdmi_intrinsic_event(struct hda_codec *codec, unsigned int res)
755{ 756{
756 struct hdmi_spec *spec = codec->spec; 757 struct hdmi_spec *spec = codec->spec;
757 int pin_nid = res >> AC_UNSOL_RES_TAG_SHIFT; 758 int tag = res >> AC_UNSOL_RES_TAG_SHIFT;
759 int pin_nid;
758 int pd = !!(res & AC_UNSOL_RES_PD); 760 int pd = !!(res & AC_UNSOL_RES_PD);
759 int eldv = !!(res & AC_UNSOL_RES_ELDV); 761 int eldv = !!(res & AC_UNSOL_RES_ELDV);
760 int pin_idx; 762 int pin_idx;
763 struct hda_jack_tbl *jack;
764
765 jack = snd_hda_jack_tbl_get_from_tag(codec, tag);
766 if (!jack)
767 return;
768 pin_nid = jack->nid;
769 jack->jack_dirty = 1;
761 770
762 printk(KERN_INFO 771 printk(KERN_INFO
763 "HDMI hot plug event: Codec=%d Pin=%d Presence_Detect=%d ELD_Valid=%d\n", 772 "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)
768 return; 777 return;
769 778
770 hdmi_present_sense(&spec->pins[pin_idx], 1); 779 hdmi_present_sense(&spec->pins[pin_idx], 1);
780 snd_hda_jack_report_sync(codec);
771} 781}
772 782
773static void hdmi_non_intrinsic_event(struct hda_codec *codec, unsigned int res) 783static 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)
799 int tag = res >> AC_UNSOL_RES_TAG_SHIFT; 809 int tag = res >> AC_UNSOL_RES_TAG_SHIFT;
800 int subtag = (res & AC_UNSOL_RES_SUBTAG) >> AC_UNSOL_RES_SUBTAG_SHIFT; 810 int subtag = (res & AC_UNSOL_RES_SUBTAG) >> AC_UNSOL_RES_SUBTAG_SHIFT;
801 811
802 if (pin_nid_to_pin_index(spec, tag) < 0) { 812 if (!snd_hda_jack_tbl_get_from_tag(codec, tag)) {
803 snd_printd(KERN_INFO "Unexpected HDMI event tag 0x%x\n", tag); 813 snd_printd(KERN_INFO "Unexpected HDMI event tag 0x%x\n", tag);
804 return; 814 return;
805 } 815 }
@@ -996,8 +1006,6 @@ static void hdmi_present_sense(struct hdmi_spec_per_pin *per_pin, int repoll)
996 msecs_to_jiffies(300)); 1006 msecs_to_jiffies(300));
997 } 1007 }
998 } 1008 }
999
1000 snd_hda_input_jack_report(codec, pin_nid);
1001} 1009}
1002 1010
1003static void hdmi_repoll_eld(struct work_struct *work) 1011static void hdmi_repoll_eld(struct work_struct *work)
@@ -1226,21 +1234,16 @@ static int generic_hdmi_build_pcms(struct hda_codec *codec)
1226 1234
1227static int generic_hdmi_build_jack(struct hda_codec *codec, int pin_idx) 1235static int generic_hdmi_build_jack(struct hda_codec *codec, int pin_idx)
1228{ 1236{
1229 int err; 1237 char hdmi_str[32] = "HDMI/DP";
1230 char hdmi_str[32];
1231 struct hdmi_spec *spec = codec->spec; 1238 struct hdmi_spec *spec = codec->spec;
1232 struct hdmi_spec_per_pin *per_pin = &spec->pins[pin_idx]; 1239 struct hdmi_spec_per_pin *per_pin = &spec->pins[pin_idx];
1233 int pcmdev = spec->pcm_rec[pin_idx].device; 1240 int pcmdev = spec->pcm_rec[pin_idx].device;
1234 1241
1235 snprintf(hdmi_str, sizeof(hdmi_str), "HDMI/DP,pcm=%d", pcmdev); 1242 if (pcmdev > 0)
1236 1243 sprintf(hdmi_str + strlen(hdmi_str), ",pcm=%d", pcmdev);
1237 err = snd_hda_input_jack_add(codec, per_pin->pin_nid,
1238 SND_JACK_VIDEOOUT, pcmdev > 0 ? hdmi_str : NULL);
1239 if (err < 0)
1240 return err;
1241 1244
1242 hdmi_present_sense(per_pin, 0); 1245 hdmi_present_sense(per_pin, 0);
1243 return 0; 1246 return snd_hda_jack_add_kctl(codec, per_pin->pin_nid, hdmi_str, 0);
1244} 1247}
1245 1248
1246static int generic_hdmi_build_controls(struct hda_codec *codec) 1249static int generic_hdmi_build_controls(struct hda_codec *codec)
@@ -1270,6 +1273,8 @@ static int generic_hdmi_build_controls(struct hda_codec *codec)
1270 1273
1271 if (err < 0) 1274 if (err < 0)
1272 return err; 1275 return err;
1276
1277 hdmi_present_sense(per_pin, false);
1273 } 1278 }
1274 1279
1275 return 0; 1280 return 0;
@@ -1286,14 +1291,13 @@ static int generic_hdmi_init(struct hda_codec *codec)
1286 struct hdmi_eld *eld = &per_pin->sink_eld; 1291 struct hdmi_eld *eld = &per_pin->sink_eld;
1287 1292
1288 hdmi_init_pin(codec, pin_nid); 1293 hdmi_init_pin(codec, pin_nid);
1289 snd_hda_codec_write(codec, pin_nid, 0, 1294 snd_hda_jack_detect_enable(codec, pin_nid, pin_nid);
1290 AC_VERB_SET_UNSOLICITED_ENABLE,
1291 AC_USRSP_EN | pin_nid);
1292 1295
1293 per_pin->codec = codec; 1296 per_pin->codec = codec;
1294 INIT_DELAYED_WORK(&per_pin->work, hdmi_repoll_eld); 1297 INIT_DELAYED_WORK(&per_pin->work, hdmi_repoll_eld);
1295 snd_hda_eld_proc_new(codec, eld, pin_idx); 1298 snd_hda_eld_proc_new(codec, eld, pin_idx);
1296 } 1299 }
1300 snd_hda_jack_report_sync(codec);
1297 return 0; 1301 return 0;
1298} 1302}
1299 1303
@@ -1309,7 +1313,6 @@ static void generic_hdmi_free(struct hda_codec *codec)
1309 cancel_delayed_work(&per_pin->work); 1313 cancel_delayed_work(&per_pin->work);
1310 snd_hda_eld_proc_free(codec, eld); 1314 snd_hda_eld_proc_free(codec, eld);
1311 } 1315 }
1312 snd_hda_input_jack_free(codec);
1313 1316
1314 flush_workqueue(codec->bus->workq); 1317 flush_workqueue(codec->bus->workq);
1315 kfree(spec); 1318 kfree(spec);