Commit 551626ec authored by Takashi Iwai's avatar Takashi Iwai

ALSA: hda/hdmi - Don't report spurious jack state changes

The HDMI jack handling reports the state change always via
snd_jack_report() whenever hdmi_present_sense() is called, even if the
state itself doesn't change from the previous time.  This is mostly
harmless but still a bit confusing to user-space.

This patch reduces such spurious jack state changes and reports only
when the state really changed.  Also, as a minor optimization, avoid
overwriting the pin ELD data when the state is identical.
Reviewed-by: default avatarKai Vehmanen <kai.vehmanen@linux.intel.com>
Signed-off-by: default avatarTakashi Iwai <tiwai@suse.de>
parent 5f9e832c
...@@ -1421,7 +1421,7 @@ static void hdmi_pcm_reset_pin(struct hdmi_spec *spec, ...@@ -1421,7 +1421,7 @@ static void hdmi_pcm_reset_pin(struct hdmi_spec *spec,
/* update per_pin ELD from the given new ELD; /* update per_pin ELD from the given new ELD;
* setup info frame and notification accordingly * setup info frame and notification accordingly
*/ */
static void update_eld(struct hda_codec *codec, static bool update_eld(struct hda_codec *codec,
struct hdmi_spec_per_pin *per_pin, struct hdmi_spec_per_pin *per_pin,
struct hdmi_eld *eld) struct hdmi_eld *eld)
{ {
...@@ -1452,18 +1452,22 @@ static void update_eld(struct hda_codec *codec, ...@@ -1452,18 +1452,22 @@ static void update_eld(struct hda_codec *codec,
snd_hdmi_show_eld(codec, &eld->info); snd_hdmi_show_eld(codec, &eld->info);
eld_changed = (pin_eld->eld_valid != eld->eld_valid); eld_changed = (pin_eld->eld_valid != eld->eld_valid);
if (eld->eld_valid && pin_eld->eld_valid) eld_changed |= (pin_eld->monitor_present != eld->monitor_present);
if (!eld_changed && eld->eld_valid && pin_eld->eld_valid)
if (pin_eld->eld_size != eld->eld_size || if (pin_eld->eld_size != eld->eld_size ||
memcmp(pin_eld->eld_buffer, eld->eld_buffer, memcmp(pin_eld->eld_buffer, eld->eld_buffer,
eld->eld_size) != 0) eld->eld_size) != 0)
eld_changed = true; eld_changed = true;
pin_eld->monitor_present = eld->monitor_present; if (eld_changed) {
pin_eld->eld_valid = eld->eld_valid; pin_eld->monitor_present = eld->monitor_present;
pin_eld->eld_size = eld->eld_size; pin_eld->eld_valid = eld->eld_valid;
if (eld->eld_valid) pin_eld->eld_size = eld->eld_size;
memcpy(pin_eld->eld_buffer, eld->eld_buffer, eld->eld_size); if (eld->eld_valid)
pin_eld->info = eld->info; memcpy(pin_eld->eld_buffer, eld->eld_buffer,
eld->eld_size);
pin_eld->info = eld->info;
}
/* /*
* Re-setup pin and infoframe. This is needed e.g. when * Re-setup pin and infoframe. This is needed e.g. when
...@@ -1481,6 +1485,7 @@ static void update_eld(struct hda_codec *codec, ...@@ -1481,6 +1485,7 @@ static void update_eld(struct hda_codec *codec,
SNDRV_CTL_EVENT_MASK_VALUE | SNDRV_CTL_EVENT_MASK_VALUE |
SNDRV_CTL_EVENT_MASK_INFO, SNDRV_CTL_EVENT_MASK_INFO,
&get_hdmi_pcm(spec, pcm_idx)->eld_ctl->id); &get_hdmi_pcm(spec, pcm_idx)->eld_ctl->id);
return eld_changed;
} }
/* update ELD and jack state via HD-audio verbs */ /* update ELD and jack state via HD-audio verbs */
...@@ -1582,6 +1587,7 @@ static void sync_eld_via_acomp(struct hda_codec *codec, ...@@ -1582,6 +1587,7 @@ static void sync_eld_via_acomp(struct hda_codec *codec,
struct hdmi_spec *spec = codec->spec; struct hdmi_spec *spec = codec->spec;
struct hdmi_eld *eld = &spec->temp_eld; struct hdmi_eld *eld = &spec->temp_eld;
struct snd_jack *jack = NULL; struct snd_jack *jack = NULL;
bool changed;
int size; int size;
mutex_lock(&per_pin->lock); mutex_lock(&per_pin->lock);
...@@ -1608,15 +1614,13 @@ static void sync_eld_via_acomp(struct hda_codec *codec, ...@@ -1608,15 +1614,13 @@ static void sync_eld_via_acomp(struct hda_codec *codec,
* disconnected event. Jack must be fetched before update_eld() * disconnected event. Jack must be fetched before update_eld()
*/ */
jack = pin_idx_to_jack(codec, per_pin); jack = pin_idx_to_jack(codec, per_pin);
update_eld(codec, per_pin, eld); changed = update_eld(codec, per_pin, eld);
if (jack == NULL) if (jack == NULL)
jack = pin_idx_to_jack(codec, per_pin); jack = pin_idx_to_jack(codec, per_pin);
if (jack == NULL) if (changed && jack)
goto unlock; snd_jack_report(jack,
snd_jack_report(jack, (eld->monitor_present && eld->eld_valid) ?
(eld->monitor_present && eld->eld_valid) ?
SND_JACK_AVOUT : 0); SND_JACK_AVOUT : 0);
unlock:
mutex_unlock(&per_pin->lock); mutex_unlock(&per_pin->lock);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment