mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-13 23:34:05 +08:00
ALSA: hda/hdmi: Move ELD parse and jack reporting into update_eld()
This is a final step of the cleanup series: move the HDMI ELD parser call into update_eld() function so that we can unify the calls. The ELD validity check is unified in update_eld(), too. Along with it, the repoll scheduling is moved to update_eld() as well, where sync_eld_via_acomp() just passes 0 for skipping it. Reviewed-by: Kai Vehmanen <kai.vehmanen@linux.intel.com> Reviewed-by: Nikhil Mahale <nmahale@nvidia.com> Link: https://lore.kernel.org/r/20200206162804.4734-5-tiwai@suse.de Signed-off-by: Takashi Iwai <tiwai@suse.de>
This commit is contained in:
parent
ae47e2ec5b
commit
adf615a605
@ -1466,21 +1466,60 @@ static void hdmi_pcm_reset_pin(struct hdmi_spec *spec,
|
||||
per_pin->channels = 0;
|
||||
}
|
||||
|
||||
static struct snd_jack *pin_idx_to_pcm_jack(struct hda_codec *codec,
|
||||
struct hdmi_spec_per_pin *per_pin)
|
||||
{
|
||||
struct hdmi_spec *spec = codec->spec;
|
||||
|
||||
if (per_pin->pcm_idx >= 0)
|
||||
return spec->pcm_rec[per_pin->pcm_idx].jack;
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* update per_pin ELD from the given new ELD;
|
||||
* setup info frame and notification accordingly
|
||||
* also notify ELD kctl and report jack status changes
|
||||
*/
|
||||
static bool update_eld(struct hda_codec *codec,
|
||||
static void update_eld(struct hda_codec *codec,
|
||||
struct hdmi_spec_per_pin *per_pin,
|
||||
struct hdmi_eld *eld)
|
||||
struct hdmi_eld *eld,
|
||||
int repoll)
|
||||
{
|
||||
struct hdmi_eld *pin_eld = &per_pin->sink_eld;
|
||||
struct hdmi_spec *spec = codec->spec;
|
||||
struct snd_jack *pcm_jack;
|
||||
bool old_eld_valid = pin_eld->eld_valid;
|
||||
bool eld_changed;
|
||||
int pcm_idx;
|
||||
|
||||
if (eld->eld_valid) {
|
||||
if (eld->eld_size <= 0 ||
|
||||
snd_hdmi_parse_eld(codec, &eld->info, eld->eld_buffer,
|
||||
eld->eld_size) < 0) {
|
||||
eld->eld_valid = false;
|
||||
if (repoll) {
|
||||
schedule_delayed_work(&per_pin->work,
|
||||
msecs_to_jiffies(300));
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!eld->eld_valid || eld->eld_size <= 0) {
|
||||
eld->eld_valid = false;
|
||||
eld->eld_size = 0;
|
||||
}
|
||||
|
||||
/* for monitor disconnection, save pcm_idx firstly */
|
||||
pcm_idx = per_pin->pcm_idx;
|
||||
|
||||
/*
|
||||
* pcm_idx >=0 before update_eld() means it is in monitor
|
||||
* disconnected event. Jack must be fetched before update_eld().
|
||||
*/
|
||||
pcm_jack = pin_idx_to_pcm_jack(codec, per_pin);
|
||||
|
||||
if (spec->dyn_pcm_assign) {
|
||||
if (eld->eld_valid) {
|
||||
hdmi_attach_hda_pcm(spec, per_pin);
|
||||
@ -1495,6 +1534,8 @@ static bool update_eld(struct hda_codec *codec,
|
||||
*/
|
||||
if (pcm_idx == -1)
|
||||
pcm_idx = per_pin->pcm_idx;
|
||||
if (!pcm_jack)
|
||||
pcm_jack = pin_idx_to_pcm_jack(codec, per_pin);
|
||||
|
||||
if (eld->eld_valid)
|
||||
snd_hdmi_show_eld(codec, &eld->info);
|
||||
@ -1533,36 +1574,8 @@ static bool update_eld(struct hda_codec *codec,
|
||||
SNDRV_CTL_EVENT_MASK_VALUE |
|
||||
SNDRV_CTL_EVENT_MASK_INFO,
|
||||
&get_hdmi_pcm(spec, pcm_idx)->eld_ctl->id);
|
||||
return eld_changed;
|
||||
}
|
||||
|
||||
static struct snd_jack *pin_idx_to_pcm_jack(struct hda_codec *codec,
|
||||
struct hdmi_spec_per_pin *per_pin)
|
||||
{
|
||||
struct hdmi_spec *spec = codec->spec;
|
||||
|
||||
if (per_pin->pcm_idx >= 0)
|
||||
return spec->pcm_rec[per_pin->pcm_idx].jack;
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void do_update_eld(struct hda_codec *codec,
|
||||
struct hdmi_spec_per_pin *per_pin,
|
||||
struct hdmi_eld *eld)
|
||||
{
|
||||
struct snd_jack *pcm_jack;
|
||||
bool changed;
|
||||
|
||||
/*
|
||||
* pcm_idx >=0 before update_eld() means it is in monitor
|
||||
* disconnected event. Jack must be fetched before update_eld().
|
||||
*/
|
||||
pcm_jack = pin_idx_to_pcm_jack(codec, per_pin);
|
||||
changed = update_eld(codec, per_pin, eld);
|
||||
if (!pcm_jack)
|
||||
pcm_jack = pin_idx_to_pcm_jack(codec, per_pin);
|
||||
if (changed && pcm_jack)
|
||||
if (eld_changed && pcm_jack)
|
||||
snd_jack_report(pcm_jack,
|
||||
(eld->monitor_present && eld->eld_valid) ?
|
||||
SND_JACK_AVOUT : 0);
|
||||
@ -1586,7 +1599,6 @@ static void hdmi_present_sense_via_verbs(struct hdmi_spec_per_pin *per_pin,
|
||||
* the unsolicited response to avoid custom WARs.
|
||||
*/
|
||||
int present;
|
||||
bool do_repoll = false;
|
||||
int ret;
|
||||
|
||||
ret = snd_hda_power_up_pm(codec);
|
||||
@ -1610,20 +1622,9 @@ static void hdmi_present_sense_via_verbs(struct hdmi_spec_per_pin *per_pin,
|
||||
if (spec->ops.pin_get_eld(codec, pin_nid, dev_id,
|
||||
eld->eld_buffer, &eld->eld_size) < 0)
|
||||
eld->eld_valid = false;
|
||||
else {
|
||||
if (snd_hdmi_parse_eld(codec, &eld->info, eld->eld_buffer,
|
||||
eld->eld_size) < 0)
|
||||
eld->eld_valid = false;
|
||||
}
|
||||
if (!eld->eld_valid && repoll)
|
||||
do_repoll = true;
|
||||
}
|
||||
|
||||
if (do_repoll)
|
||||
schedule_delayed_work(&per_pin->work, msecs_to_jiffies(300));
|
||||
else
|
||||
do_update_eld(codec, per_pin, eld);
|
||||
|
||||
update_eld(codec, per_pin, eld, repoll);
|
||||
mutex_unlock(&per_pin->lock);
|
||||
out:
|
||||
snd_hda_power_down_pm(codec);
|
||||
@ -1635,29 +1636,14 @@ static void sync_eld_via_acomp(struct hda_codec *codec,
|
||||
{
|
||||
struct hdmi_spec *spec = codec->spec;
|
||||
struct hdmi_eld *eld = &spec->temp_eld;
|
||||
int size;
|
||||
|
||||
mutex_lock(&per_pin->lock);
|
||||
eld->monitor_present = false;
|
||||
size = snd_hdac_acomp_get_eld(&codec->core, per_pin->pin_nid,
|
||||
eld->eld_size = snd_hdac_acomp_get_eld(&codec->core, per_pin->pin_nid,
|
||||
per_pin->dev_id, &eld->monitor_present,
|
||||
eld->eld_buffer, ELD_MAX_SIZE);
|
||||
if (size > 0) {
|
||||
size = min(size, ELD_MAX_SIZE);
|
||||
if (snd_hdmi_parse_eld(codec, &eld->info,
|
||||
eld->eld_buffer, size) < 0)
|
||||
size = -EINVAL;
|
||||
}
|
||||
|
||||
if (size > 0) {
|
||||
eld->eld_valid = true;
|
||||
eld->eld_size = size;
|
||||
} else {
|
||||
eld->eld_valid = false;
|
||||
eld->eld_size = 0;
|
||||
}
|
||||
|
||||
do_update_eld(codec, per_pin, eld);
|
||||
eld->eld_valid = (eld->eld_size > 0);
|
||||
update_eld(codec, per_pin, eld, 0);
|
||||
mutex_unlock(&per_pin->lock);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user