diff options
Diffstat (limited to 'sound/pci/hda/patch_hdmi.c')
-rw-r--r-- | sound/pci/hda/patch_hdmi.c | 37 |
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 | ||
40 | static bool static_hdmi_pcm; | 41 | static bool static_hdmi_pcm; |
41 | module_param(static_hdmi_pcm, bool, 0644); | 42 | 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); | |||
754 | static void hdmi_intrinsic_event(struct hda_codec *codec, unsigned int res) | 755 | static 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 | ||
773 | static void hdmi_non_intrinsic_event(struct hda_codec *codec, unsigned int res) | 783 | 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) | |||
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 | ||
1003 | static void hdmi_repoll_eld(struct work_struct *work) | 1011 | static void hdmi_repoll_eld(struct work_struct *work) |
@@ -1226,21 +1234,16 @@ static int generic_hdmi_build_pcms(struct hda_codec *codec) | |||
1226 | 1234 | ||
1227 | static int generic_hdmi_build_jack(struct hda_codec *codec, int pin_idx) | 1235 | static 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 | ||
1246 | static int generic_hdmi_build_controls(struct hda_codec *codec) | 1249 | static 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); |