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.c55
1 files changed, 33 insertions, 22 deletions
diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c
index 81b7b791b3c3..9850c5b481ea 100644
--- a/sound/pci/hda/patch_hdmi.c
+++ b/sound/pci/hda/patch_hdmi.c
@@ -65,7 +65,10 @@ struct hdmi_spec_per_pin {
65 hda_nid_t pin_nid; 65 hda_nid_t pin_nid;
66 int num_mux_nids; 66 int num_mux_nids;
67 hda_nid_t mux_nids[HDA_MAX_CONNECTIONS]; 67 hda_nid_t mux_nids[HDA_MAX_CONNECTIONS];
68
69 struct hda_codec *codec;
68 struct hdmi_eld sink_eld; 70 struct hdmi_eld sink_eld;
71 struct delayed_work work;
69}; 72};
70 73
71struct hdmi_spec { 74struct hdmi_spec {
@@ -745,8 +748,7 @@ static void hdmi_setup_audio_infoframe(struct hda_codec *codec, int pin_idx,
745 * Unsolicited events 748 * Unsolicited events
746 */ 749 */
747 750
748static void hdmi_present_sense(struct hda_codec *codec, hda_nid_t pin_nid, 751static void hdmi_present_sense(struct hdmi_spec_per_pin *per_pin, bool retry);
749 struct hdmi_eld *eld);
750 752
751static void hdmi_intrinsic_event(struct hda_codec *codec, unsigned int res) 753static void hdmi_intrinsic_event(struct hda_codec *codec, unsigned int res)
752{ 754{
@@ -755,7 +757,6 @@ static void hdmi_intrinsic_event(struct hda_codec *codec, unsigned int res)
755 int pd = !!(res & AC_UNSOL_RES_PD); 757 int pd = !!(res & AC_UNSOL_RES_PD);
756 int eldv = !!(res & AC_UNSOL_RES_ELDV); 758 int eldv = !!(res & AC_UNSOL_RES_ELDV);
757 int pin_idx; 759 int pin_idx;
758 struct hdmi_eld *eld;
759 760
760 printk(KERN_INFO 761 printk(KERN_INFO
761 "HDMI hot plug event: Codec=%d Pin=%d Presence_Detect=%d ELD_Valid=%d\n", 762 "HDMI hot plug event: Codec=%d Pin=%d Presence_Detect=%d ELD_Valid=%d\n",
@@ -764,17 +765,8 @@ static void hdmi_intrinsic_event(struct hda_codec *codec, unsigned int res)
764 pin_idx = pin_nid_to_pin_index(spec, pin_nid); 765 pin_idx = pin_nid_to_pin_index(spec, pin_nid);
765 if (pin_idx < 0) 766 if (pin_idx < 0)
766 return; 767 return;
767 eld = &spec->pins[pin_idx].sink_eld;
768
769 hdmi_present_sense(codec, pin_nid, eld);
770 768
771 /* 769 hdmi_present_sense(&spec->pins[pin_idx], true);
772 * HDMI sink's ELD info cannot always be retrieved for now, e.g.
773 * in console or for audio devices. Assume the highest speakers
774 * configuration, to _not_ prohibit multi-channel audio playback.
775 */
776 if (!eld->spk_alloc)
777 eld->spk_alloc = 0xffff;
778} 770}
779 771
780static void hdmi_non_intrinsic_event(struct hda_codec *codec, unsigned int res) 772static void hdmi_non_intrinsic_event(struct hda_codec *codec, unsigned int res)
@@ -968,9 +960,11 @@ static int hdmi_read_pin_conn(struct hda_codec *codec, int pin_idx)
968 return 0; 960 return 0;
969} 961}
970 962
971static void hdmi_present_sense(struct hda_codec *codec, hda_nid_t pin_nid, 963static void hdmi_present_sense(struct hdmi_spec_per_pin *per_pin, bool retry)
972 struct hdmi_eld *eld)
973{ 964{
965 struct hda_codec *codec = per_pin->codec;
966 struct hdmi_eld *eld = &per_pin->sink_eld;
967 hda_nid_t pin_nid = per_pin->pin_nid;
974 /* 968 /*
975 * Always execute a GetPinSense verb here, even when called from 969 * Always execute a GetPinSense verb here, even when called from
976 * hdmi_intrinsic_event; for some NVIDIA HW, the unsolicited 970 * hdmi_intrinsic_event; for some NVIDIA HW, the unsolicited
@@ -980,26 +974,39 @@ static void hdmi_present_sense(struct hda_codec *codec, hda_nid_t pin_nid,
980 * the unsolicited response to avoid custom WARs. 974 * the unsolicited response to avoid custom WARs.
981 */ 975 */
982 int present = snd_hda_pin_sense(codec, pin_nid); 976 int present = snd_hda_pin_sense(codec, pin_nid);
977 bool eld_valid = false;
983 978
984 memset(eld, 0, sizeof(*eld)); 979 memset(eld, 0, offsetof(struct hdmi_eld, eld_buffer));
985 980
986 eld->monitor_present = !!(present & AC_PINSENSE_PRESENCE); 981 eld->monitor_present = !!(present & AC_PINSENSE_PRESENCE);
987 if (eld->monitor_present) 982 if (eld->monitor_present)
988 eld->eld_valid = !!(present & AC_PINSENSE_ELDV); 983 eld_valid = !!(present & AC_PINSENSE_ELDV);
989 else
990 eld->eld_valid = 0;
991 984
992 printk(KERN_INFO 985 printk(KERN_INFO
993 "HDMI status: Codec=%d Pin=%d Presence_Detect=%d ELD_Valid=%d\n", 986 "HDMI status: Codec=%d Pin=%d Presence_Detect=%d ELD_Valid=%d\n",
994 codec->addr, pin_nid, eld->monitor_present, eld->eld_valid); 987 codec->addr, pin_nid, eld->monitor_present, eld_valid);
995 988
996 if (eld->eld_valid) 989 if (eld_valid) {
997 if (!snd_hdmi_get_eld(eld, codec, pin_nid)) 990 if (!snd_hdmi_get_eld(eld, codec, pin_nid))
998 snd_hdmi_show_eld(eld); 991 snd_hdmi_show_eld(eld);
992 else if (retry) {
993 queue_delayed_work(codec->bus->workq,
994 &per_pin->work,
995 msecs_to_jiffies(300));
996 }
997 }
999 998
1000 snd_hda_input_jack_report(codec, pin_nid); 999 snd_hda_input_jack_report(codec, pin_nid);
1001} 1000}
1002 1001
1002static void hdmi_repoll_eld(struct work_struct *work)
1003{
1004 struct hdmi_spec_per_pin *per_pin =
1005 container_of(to_delayed_work(work), struct hdmi_spec_per_pin, work);
1006
1007 hdmi_present_sense(per_pin, false);
1008}
1009
1003static int hdmi_add_pin(struct hda_codec *codec, hda_nid_t pin_nid) 1010static int hdmi_add_pin(struct hda_codec *codec, hda_nid_t pin_nid)
1004{ 1011{
1005 struct hdmi_spec *spec = codec->spec; 1012 struct hdmi_spec *spec = codec->spec;
@@ -1228,7 +1235,7 @@ static int generic_hdmi_build_jack(struct hda_codec *codec, int pin_idx)
1228 if (err < 0) 1235 if (err < 0)
1229 return err; 1236 return err;
1230 1237
1231 hdmi_present_sense(codec, per_pin->pin_nid, &per_pin->sink_eld); 1238 hdmi_present_sense(per_pin, false);
1232 return 0; 1239 return 0;
1233} 1240}
1234 1241
@@ -1279,6 +1286,8 @@ static int generic_hdmi_init(struct hda_codec *codec)
1279 AC_VERB_SET_UNSOLICITED_ENABLE, 1286 AC_VERB_SET_UNSOLICITED_ENABLE,
1280 AC_USRSP_EN | pin_nid); 1287 AC_USRSP_EN | pin_nid);
1281 1288
1289 per_pin->codec = codec;
1290 INIT_DELAYED_WORK(&per_pin->work, hdmi_repoll_eld);
1282 snd_hda_eld_proc_new(codec, eld, pin_idx); 1291 snd_hda_eld_proc_new(codec, eld, pin_idx);
1283 } 1292 }
1284 return 0; 1293 return 0;
@@ -1293,10 +1302,12 @@ static void generic_hdmi_free(struct hda_codec *codec)
1293 struct hdmi_spec_per_pin *per_pin = &spec->pins[pin_idx]; 1302 struct hdmi_spec_per_pin *per_pin = &spec->pins[pin_idx];
1294 struct hdmi_eld *eld = &per_pin->sink_eld; 1303 struct hdmi_eld *eld = &per_pin->sink_eld;
1295 1304
1305 cancel_delayed_work(&per_pin->work);
1296 snd_hda_eld_proc_free(codec, eld); 1306 snd_hda_eld_proc_free(codec, eld);
1297 } 1307 }
1298 snd_hda_input_jack_free(codec); 1308 snd_hda_input_jack_free(codec);
1299 1309
1310 flush_workqueue(codec->bus->workq);
1300 kfree(spec); 1311 kfree(spec);
1301} 1312}
1302 1313