aboutsummaryrefslogtreecommitdiffstats
path: root/sound/pci/hda
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2013-11-07 07:38:23 -0500
committerTakashi Iwai <tiwai@suse.de>2013-11-07 08:02:49 -0500
commitefe4710860fa6ed10dd041f13902f0e06c86e8cc (patch)
tree5cfecea529d1e8650d51cc841d1959b417253ba8 /sound/pci/hda
parent3b098eb486868d57d7f2666d05b86c19a07df71b (diff)
ALSA: hda - Delay HDMI presence reports while waiting for ELD information
There is a small gap between the jack detection unsolicited event and the time the ELD is updated. When user-space queries the HDMI ELD immediately after receiving the notification, it might fail because of this gap. For avoiding such a problem, this patch tries to delay the HDMI jack detect notification until ELD information is fully updated. The workaround is imperfect, but good enough as a starting point. Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound/pci/hda')
-rw-r--r--sound/pci/hda/patch_hdmi.c17
1 files changed, 12 insertions, 5 deletions
diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c
index e22323f50424..ce412d1a15d0 100644
--- a/sound/pci/hda/patch_hdmi.c
+++ b/sound/pci/hda/patch_hdmi.c
@@ -1140,7 +1140,7 @@ static void hdmi_setup_audio_infoframe(struct hda_codec *codec,
1140 * Unsolicited events 1140 * Unsolicited events
1141 */ 1141 */
1142 1142
1143static void hdmi_present_sense(struct hdmi_spec_per_pin *per_pin, int repoll); 1143static bool hdmi_present_sense(struct hdmi_spec_per_pin *per_pin, int repoll);
1144 1144
1145static void hdmi_intrinsic_event(struct hda_codec *codec, unsigned int res) 1145static void hdmi_intrinsic_event(struct hda_codec *codec, unsigned int res)
1146{ 1146{
@@ -1166,8 +1166,8 @@ static void hdmi_intrinsic_event(struct hda_codec *codec, unsigned int res)
1166 if (pin_idx < 0) 1166 if (pin_idx < 0)
1167 return; 1167 return;
1168 1168
1169 hdmi_present_sense(get_pin(spec, pin_idx), 1); 1169 if (hdmi_present_sense(get_pin(spec, pin_idx), 1))
1170 snd_hda_jack_report_sync(codec); 1170 snd_hda_jack_report_sync(codec);
1171} 1171}
1172 1172
1173static void hdmi_non_intrinsic_event(struct hda_codec *codec, unsigned int res) 1173static void hdmi_non_intrinsic_event(struct hda_codec *codec, unsigned int res)
@@ -1475,7 +1475,7 @@ static int hdmi_read_pin_conn(struct hda_codec *codec, int pin_idx)
1475 return 0; 1475 return 0;
1476} 1476}
1477 1477
1478static void hdmi_present_sense(struct hdmi_spec_per_pin *per_pin, int repoll) 1478static bool hdmi_present_sense(struct hdmi_spec_per_pin *per_pin, int repoll)
1479{ 1479{
1480 struct hda_codec *codec = per_pin->codec; 1480 struct hda_codec *codec = per_pin->codec;
1481 struct hdmi_spec *spec = codec->spec; 1481 struct hdmi_spec *spec = codec->spec;
@@ -1493,6 +1493,7 @@ static void hdmi_present_sense(struct hdmi_spec_per_pin *per_pin, int repoll)
1493 int present = snd_hda_pin_sense(codec, pin_nid); 1493 int present = snd_hda_pin_sense(codec, pin_nid);
1494 bool update_eld = false; 1494 bool update_eld = false;
1495 bool eld_changed = false; 1495 bool eld_changed = false;
1496 bool ret;
1496 1497
1497 mutex_lock(&per_pin->lock); 1498 mutex_lock(&per_pin->lock);
1498 pin_eld->monitor_present = !!(present & AC_PINSENSE_PRESENCE); 1499 pin_eld->monitor_present = !!(present & AC_PINSENSE_PRESENCE);
@@ -1559,7 +1560,12 @@ static void hdmi_present_sense(struct hdmi_spec_per_pin *per_pin, int repoll)
1559 SNDRV_CTL_EVENT_MASK_VALUE | SNDRV_CTL_EVENT_MASK_INFO, 1560 SNDRV_CTL_EVENT_MASK_VALUE | SNDRV_CTL_EVENT_MASK_INFO,
1560 &per_pin->eld_ctl->id); 1561 &per_pin->eld_ctl->id);
1561 unlock: 1562 unlock:
1563 if ((codec->vendor_id & 0xffff0000) == 0x10020000)
1564 ret = true; /* AMD codecs create ELD by itself */
1565 else
1566 ret = !repoll || !pin_eld->monitor_present || pin_eld->eld_valid;
1562 mutex_unlock(&per_pin->lock); 1567 mutex_unlock(&per_pin->lock);
1568 return ret;
1563} 1569}
1564 1570
1565static void hdmi_repoll_eld(struct work_struct *work) 1571static void hdmi_repoll_eld(struct work_struct *work)
@@ -1570,7 +1576,8 @@ static void hdmi_repoll_eld(struct work_struct *work)
1570 if (per_pin->repoll_count++ > 6) 1576 if (per_pin->repoll_count++ > 6)
1571 per_pin->repoll_count = 0; 1577 per_pin->repoll_count = 0;
1572 1578
1573 hdmi_present_sense(per_pin, per_pin->repoll_count); 1579 if (hdmi_present_sense(per_pin, per_pin->repoll_count))
1580 snd_hda_jack_report_sync(per_pin->codec);
1574} 1581}
1575 1582
1576static void intel_haswell_fixup_connect_list(struct hda_codec *codec, 1583static void intel_haswell_fixup_connect_list(struct hda_codec *codec,