All of lore.kernel.org
 help / color / mirror / Atom feed
* [RFC PATCH] ALSA: hda - hdmi eld control created based on pcm
@ 2016-02-23  8:33 libin.yang
  2016-02-23 13:58 ` Takashi Iwai
  0 siblings, 1 reply; 4+ messages in thread
From: libin.yang @ 2016-02-23  8:33 UTC (permalink / raw)
  To: alsa-devel, tiwai; +Cc: libin.yang, mengdong.lin, Libin Yang

From: Libin Yang <libin.yang@linux.intel.com>

eld control is created based on pcm now.
When monitor is connected, eld control will be bound to
pin automatically.

Signed-off-by: Libin Yang <libin.yang@linux.intel.com>
---
 sound/pci/hda/patch_hdmi.c | 74 ++++++++++++++++++++++++++++++----------------
 1 file changed, 48 insertions(+), 26 deletions(-)

diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c
index 541986f..d77509a 100644
--- a/sound/pci/hda/patch_hdmi.c
+++ b/sound/pci/hda/patch_hdmi.c
@@ -86,7 +86,6 @@ struct hdmi_spec_per_pin {
 	struct hdmi_eld sink_eld;
 	struct mutex lock;
 	struct delayed_work work;
-	struct snd_kcontrol *eld_ctl;
 	struct hdmi_pcm *pcm; /* pointer to spec->pcm_rec[n] dynamically*/
 	int pcm_idx; /* which pcm is attached. -1 means no pcm is attached */
 	int repoll_count;
@@ -136,6 +135,7 @@ struct hdmi_ops {
 struct hdmi_pcm {
 	struct hda_pcm *pcm;
 	struct snd_jack *jack;
+	struct snd_kcontrol *eld_ctl;
 };
 
 struct hdmi_spec {
@@ -471,17 +471,22 @@ static int hdmi_eld_ctl_info(struct snd_kcontrol *kcontrol,
 	struct hdmi_spec *spec = codec->spec;
 	struct hdmi_spec_per_pin *per_pin;
 	struct hdmi_eld *eld;
-	int pin_idx;
+	int pcm_idx;
 
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_BYTES;
 
-	pin_idx = kcontrol->private_value;
-	per_pin = get_pin(spec, pin_idx);
+	pcm_idx = kcontrol->private_value;
+	mutex_lock(&spec->pcm_lock);
+	per_pin = pcm_idx_to_pin(spec, pcm_idx);
+	if (!per_pin) {
+		/* no pin is bound to the pcm */
+		uinfo->count = 0;
+		mutex_unlock(&spec->pcm_lock);
+		return 0;
+	}
 	eld = &per_pin->sink_eld;
-
-	mutex_lock(&per_pin->lock);
 	uinfo->count = eld->eld_valid ? eld->eld_size : 0;
-	mutex_unlock(&per_pin->lock);
+	mutex_unlock(&spec->pcm_lock);
 
 	return 0;
 }
@@ -493,16 +498,23 @@ static int hdmi_eld_ctl_get(struct snd_kcontrol *kcontrol,
 	struct hdmi_spec *spec = codec->spec;
 	struct hdmi_spec_per_pin *per_pin;
 	struct hdmi_eld *eld;
-	int pin_idx;
+	int pcm_idx;
 
-	pin_idx = kcontrol->private_value;
-	per_pin = get_pin(spec, pin_idx);
+	pcm_idx = kcontrol->private_value;
+	mutex_lock(&spec->pcm_lock);
+	per_pin = pcm_idx_to_pin(spec, pcm_idx);
+	if (!per_pin) {
+		/* no pin is bound to the pcm */
+		memset(ucontrol->value.bytes.data, 0,
+	       ARRAY_SIZE(ucontrol->value.bytes.data));
+		mutex_unlock(&spec->pcm_lock);
+		return 0;
+	}
 	eld = &per_pin->sink_eld;
 
-	mutex_lock(&per_pin->lock);
 	if (eld->eld_size > ARRAY_SIZE(ucontrol->value.bytes.data) ||
 	    eld->eld_size > ELD_MAX_SIZE) {
-		mutex_unlock(&per_pin->lock);
+		mutex_unlock(&spec->pcm_lock);
 		snd_BUG();
 		return -EINVAL;
 	}
@@ -512,7 +524,7 @@ static int hdmi_eld_ctl_get(struct snd_kcontrol *kcontrol,
 	if (eld->eld_valid)
 		memcpy(ucontrol->value.bytes.data, eld->eld_buffer,
 		       eld->eld_size);
-	mutex_unlock(&per_pin->lock);
+	mutex_unlock(&spec->pcm_lock);
 
 	return 0;
 }
@@ -525,7 +537,7 @@ static struct snd_kcontrol_new eld_bytes_ctl = {
 	.get = hdmi_eld_ctl_get,
 };
 
-static int hdmi_create_eld_ctl(struct hda_codec *codec, int pin_idx,
+static int hdmi_create_eld_ctl(struct hda_codec *codec, int pcm_idx,
 			int device)
 {
 	struct snd_kcontrol *kctl;
@@ -535,14 +547,17 @@ static int hdmi_create_eld_ctl(struct hda_codec *codec, int pin_idx,
 	kctl = snd_ctl_new1(&eld_bytes_ctl, codec);
 	if (!kctl)
 		return -ENOMEM;
-	kctl->private_value = pin_idx;
+	kctl->private_value = pcm_idx;
 	kctl->id.device = device;
 
-	err = snd_hda_ctl_add(codec, get_pin(spec, pin_idx)->pin_nid, kctl);
+	/* no pin nid is associated with the kctl now
+	 * tbd: associate pin nid to eld ctl later
+	 */
+	err = snd_hda_ctl_add(codec, 0, kctl);
 	if (err < 0)
 		return err;
 
-	get_pin(spec, pin_idx)->eld_ctl = kctl;
+	get_hdmi_pcm(spec, pcm_idx)->eld_ctl = kctl;
 	return 0;
 }
 
@@ -1841,7 +1856,10 @@ static void update_eld(struct hda_codec *codec,
 	struct hdmi_spec *spec = codec->spec;
 	bool old_eld_valid = pin_eld->eld_valid;
 	bool eld_changed;
+	int pcm_idx = -1;
 
+	/* for monitor disconnection, save pcm_idx firstly */
+	pcm_idx = per_pin->pcm_idx;
 	if (spec->dyn_pcm_assign) {
 		if (eld->eld_valid) {
 			hdmi_attach_hda_pcm(spec, per_pin);
@@ -1851,6 +1869,11 @@ static void update_eld(struct hda_codec *codec,
 			hdmi_detach_hda_pcm(spec, per_pin);
 		}
 	}
+	/* if pcm_idx == -1, it means this is in monitor connection event
+	 * we can get the correct pcm_idx now.
+	 */
+	if (pcm_idx == -1)
+		pcm_idx = per_pin->pcm_idx;
 
 	if (eld->eld_valid)
 		snd_hdmi_show_eld(codec, &eld->info);
@@ -1884,11 +1907,11 @@ static void update_eld(struct hda_codec *codec,
 		hdmi_setup_audio_infoframe(codec, per_pin, per_pin->non_pcm);
 	}
 
-	if (eld_changed)
+	if (eld_changed && pcm_idx >= 0)
 		snd_ctl_notify(codec->card,
 			       SNDRV_CTL_EVENT_MASK_VALUE |
 			       SNDRV_CTL_EVENT_MASK_INFO,
-			       &per_pin->eld_ctl->id);
+			       &get_hdmi_pcm(spec, pcm_idx)->eld_ctl->id);
 }
 
 /* update ELD and jack state via HD-audio verbs */
@@ -2629,17 +2652,16 @@ static int generic_hdmi_build_controls(struct hda_codec *codec)
 		if (err < 0)
 			return err;
 		snd_hda_spdif_ctls_unassign(codec, pcm_idx);
-	}
-
-	for (pin_idx = 0; pin_idx < spec->num_pins; pin_idx++) {
-		struct hdmi_spec_per_pin *per_pin = get_pin(spec, pin_idx);
 
 		/* add control for ELD Bytes */
-		err = hdmi_create_eld_ctl(codec, pin_idx,
-				get_pcm_rec(spec, pin_idx)->device);
-
+		err = hdmi_create_eld_ctl(codec, pcm_idx,
+					get_pcm_rec(spec, pcm_idx)->device);
 		if (err < 0)
 			return err;
+	}
+
+	for (pin_idx = 0; pin_idx < spec->num_pins; pin_idx++) {
+		struct hdmi_spec_per_pin *per_pin = get_pin(spec, pin_idx);
 
 		hdmi_present_sense(per_pin, 0);
 	}
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 4+ messages in thread

* Re: [RFC PATCH] ALSA: hda - hdmi eld control created based on pcm
  2016-02-23  8:33 [RFC PATCH] ALSA: hda - hdmi eld control created based on pcm libin.yang
@ 2016-02-23 13:58 ` Takashi Iwai
  2016-02-23 14:25   ` Yang, Libin
  0 siblings, 1 reply; 4+ messages in thread
From: Takashi Iwai @ 2016-02-23 13:58 UTC (permalink / raw)
  To: libin.yang; +Cc: libin.yang, mengdong.lin, alsa-devel

On Tue, 23 Feb 2016 09:33:37 +0100,
libin.yang@linux.intel.com wrote:
> 
> From: Libin Yang <libin.yang@linux.intel.com>
> 
> eld control is created based on pcm now.
> When monitor is connected, eld control will be bound to
> pin automatically.
> 
> Signed-off-by: Libin Yang <libin.yang@linux.intel.com>

Looks good to me -- as long as you tested :)
Let me know if you'd like to merge it as is.


thanks,

Takashi


> ---
>  sound/pci/hda/patch_hdmi.c | 74 ++++++++++++++++++++++++++++++----------------
>  1 file changed, 48 insertions(+), 26 deletions(-)
> 
> diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c
> index 541986f..d77509a 100644
> --- a/sound/pci/hda/patch_hdmi.c
> +++ b/sound/pci/hda/patch_hdmi.c
> @@ -86,7 +86,6 @@ struct hdmi_spec_per_pin {
>  	struct hdmi_eld sink_eld;
>  	struct mutex lock;
>  	struct delayed_work work;
> -	struct snd_kcontrol *eld_ctl;
>  	struct hdmi_pcm *pcm; /* pointer to spec->pcm_rec[n] dynamically*/
>  	int pcm_idx; /* which pcm is attached. -1 means no pcm is attached */
>  	int repoll_count;
> @@ -136,6 +135,7 @@ struct hdmi_ops {
>  struct hdmi_pcm {
>  	struct hda_pcm *pcm;
>  	struct snd_jack *jack;
> +	struct snd_kcontrol *eld_ctl;
>  };
>  
>  struct hdmi_spec {
> @@ -471,17 +471,22 @@ static int hdmi_eld_ctl_info(struct snd_kcontrol *kcontrol,
>  	struct hdmi_spec *spec = codec->spec;
>  	struct hdmi_spec_per_pin *per_pin;
>  	struct hdmi_eld *eld;
> -	int pin_idx;
> +	int pcm_idx;
>  
>  	uinfo->type = SNDRV_CTL_ELEM_TYPE_BYTES;
>  
> -	pin_idx = kcontrol->private_value;
> -	per_pin = get_pin(spec, pin_idx);
> +	pcm_idx = kcontrol->private_value;
> +	mutex_lock(&spec->pcm_lock);
> +	per_pin = pcm_idx_to_pin(spec, pcm_idx);
> +	if (!per_pin) {
> +		/* no pin is bound to the pcm */
> +		uinfo->count = 0;
> +		mutex_unlock(&spec->pcm_lock);
> +		return 0;
> +	}
>  	eld = &per_pin->sink_eld;
> -
> -	mutex_lock(&per_pin->lock);
>  	uinfo->count = eld->eld_valid ? eld->eld_size : 0;
> -	mutex_unlock(&per_pin->lock);
> +	mutex_unlock(&spec->pcm_lock);
>  
>  	return 0;
>  }
> @@ -493,16 +498,23 @@ static int hdmi_eld_ctl_get(struct snd_kcontrol *kcontrol,
>  	struct hdmi_spec *spec = codec->spec;
>  	struct hdmi_spec_per_pin *per_pin;
>  	struct hdmi_eld *eld;
> -	int pin_idx;
> +	int pcm_idx;
>  
> -	pin_idx = kcontrol->private_value;
> -	per_pin = get_pin(spec, pin_idx);
> +	pcm_idx = kcontrol->private_value;
> +	mutex_lock(&spec->pcm_lock);
> +	per_pin = pcm_idx_to_pin(spec, pcm_idx);
> +	if (!per_pin) {
> +		/* no pin is bound to the pcm */
> +		memset(ucontrol->value.bytes.data, 0,
> +	       ARRAY_SIZE(ucontrol->value.bytes.data));
> +		mutex_unlock(&spec->pcm_lock);
> +		return 0;
> +	}
>  	eld = &per_pin->sink_eld;
>  
> -	mutex_lock(&per_pin->lock);
>  	if (eld->eld_size > ARRAY_SIZE(ucontrol->value.bytes.data) ||
>  	    eld->eld_size > ELD_MAX_SIZE) {
> -		mutex_unlock(&per_pin->lock);
> +		mutex_unlock(&spec->pcm_lock);
>  		snd_BUG();
>  		return -EINVAL;
>  	}
> @@ -512,7 +524,7 @@ static int hdmi_eld_ctl_get(struct snd_kcontrol *kcontrol,
>  	if (eld->eld_valid)
>  		memcpy(ucontrol->value.bytes.data, eld->eld_buffer,
>  		       eld->eld_size);
> -	mutex_unlock(&per_pin->lock);
> +	mutex_unlock(&spec->pcm_lock);
>  
>  	return 0;
>  }
> @@ -525,7 +537,7 @@ static struct snd_kcontrol_new eld_bytes_ctl = {
>  	.get = hdmi_eld_ctl_get,
>  };
>  
> -static int hdmi_create_eld_ctl(struct hda_codec *codec, int pin_idx,
> +static int hdmi_create_eld_ctl(struct hda_codec *codec, int pcm_idx,
>  			int device)
>  {
>  	struct snd_kcontrol *kctl;
> @@ -535,14 +547,17 @@ static int hdmi_create_eld_ctl(struct hda_codec *codec, int pin_idx,
>  	kctl = snd_ctl_new1(&eld_bytes_ctl, codec);
>  	if (!kctl)
>  		return -ENOMEM;
> -	kctl->private_value = pin_idx;
> +	kctl->private_value = pcm_idx;
>  	kctl->id.device = device;
>  
> -	err = snd_hda_ctl_add(codec, get_pin(spec, pin_idx)->pin_nid, kctl);
> +	/* no pin nid is associated with the kctl now
> +	 * tbd: associate pin nid to eld ctl later
> +	 */
> +	err = snd_hda_ctl_add(codec, 0, kctl);
>  	if (err < 0)
>  		return err;
>  
> -	get_pin(spec, pin_idx)->eld_ctl = kctl;
> +	get_hdmi_pcm(spec, pcm_idx)->eld_ctl = kctl;
>  	return 0;
>  }
>  
> @@ -1841,7 +1856,10 @@ static void update_eld(struct hda_codec *codec,
>  	struct hdmi_spec *spec = codec->spec;
>  	bool old_eld_valid = pin_eld->eld_valid;
>  	bool eld_changed;
> +	int pcm_idx = -1;
>  
> +	/* for monitor disconnection, save pcm_idx firstly */
> +	pcm_idx = per_pin->pcm_idx;
>  	if (spec->dyn_pcm_assign) {
>  		if (eld->eld_valid) {
>  			hdmi_attach_hda_pcm(spec, per_pin);
> @@ -1851,6 +1869,11 @@ static void update_eld(struct hda_codec *codec,
>  			hdmi_detach_hda_pcm(spec, per_pin);
>  		}
>  	}
> +	/* if pcm_idx == -1, it means this is in monitor connection event
> +	 * we can get the correct pcm_idx now.
> +	 */
> +	if (pcm_idx == -1)
> +		pcm_idx = per_pin->pcm_idx;
>  
>  	if (eld->eld_valid)
>  		snd_hdmi_show_eld(codec, &eld->info);
> @@ -1884,11 +1907,11 @@ static void update_eld(struct hda_codec *codec,
>  		hdmi_setup_audio_infoframe(codec, per_pin, per_pin->non_pcm);
>  	}
>  
> -	if (eld_changed)
> +	if (eld_changed && pcm_idx >= 0)
>  		snd_ctl_notify(codec->card,
>  			       SNDRV_CTL_EVENT_MASK_VALUE |
>  			       SNDRV_CTL_EVENT_MASK_INFO,
> -			       &per_pin->eld_ctl->id);
> +			       &get_hdmi_pcm(spec, pcm_idx)->eld_ctl->id);
>  }
>  
>  /* update ELD and jack state via HD-audio verbs */
> @@ -2629,17 +2652,16 @@ static int generic_hdmi_build_controls(struct hda_codec *codec)
>  		if (err < 0)
>  			return err;
>  		snd_hda_spdif_ctls_unassign(codec, pcm_idx);
> -	}
> -
> -	for (pin_idx = 0; pin_idx < spec->num_pins; pin_idx++) {
> -		struct hdmi_spec_per_pin *per_pin = get_pin(spec, pin_idx);
>  
>  		/* add control for ELD Bytes */
> -		err = hdmi_create_eld_ctl(codec, pin_idx,
> -				get_pcm_rec(spec, pin_idx)->device);
> -
> +		err = hdmi_create_eld_ctl(codec, pcm_idx,
> +					get_pcm_rec(spec, pcm_idx)->device);
>  		if (err < 0)
>  			return err;
> +	}
> +
> +	for (pin_idx = 0; pin_idx < spec->num_pins; pin_idx++) {
> +		struct hdmi_spec_per_pin *per_pin = get_pin(spec, pin_idx);
>  
>  		hdmi_present_sense(per_pin, 0);
>  	}
> -- 
> 1.9.1
> 

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [RFC PATCH] ALSA: hda - hdmi eld control created based on pcm
  2016-02-23 13:58 ` Takashi Iwai
@ 2016-02-23 14:25   ` Yang, Libin
  2016-02-23 14:43     ` Takashi Iwai
  0 siblings, 1 reply; 4+ messages in thread
From: Yang, Libin @ 2016-02-23 14:25 UTC (permalink / raw)
  To: Takashi Iwai, libin.yang; +Cc: Lin, Mengdong, alsa-devel

Hi Takashi,


> -----Original Message-----
> From: Takashi Iwai [mailto:tiwai@suse.de]
> Sent: Tuesday, February 23, 2016 9:59 PM
> To: libin.yang@linux.intel.com
> Cc: alsa-devel@alsa-project.org; Lin, Mengdong; Yang, Libin
> Subject: Re: [alsa-devel] [RFC PATCH] ALSA: hda - hdmi eld control
> created based on pcm
> 
> On Tue, 23 Feb 2016 09:33:37 +0100,
> libin.yang@linux.intel.com wrote:
> >
> > From: Libin Yang <libin.yang@linux.intel.com>
> >
> > eld control is created based on pcm now.
> > When monitor is connected, eld control will be bound to
> > pin automatically.
> >
> > Signed-off-by: Libin Yang <libin.yang@linux.intel.com>
> 
> Looks good to me -- as long as you tested :)
> Let me know if you'd like to merge it as is.

The patch is tested with my basic test case.
It's great if the patch can be merged :)

Regards,
Libin

> 
> 
> thanks,
> 
> Takashi
> 
> 
> > ---
> >  sound/pci/hda/patch_hdmi.c | 74
> ++++++++++++++++++++++++++++++----------------
> >  1 file changed, 48 insertions(+), 26 deletions(-)
> >
> > diff --git a/sound/pci/hda/patch_hdmi.c
> b/sound/pci/hda/patch_hdmi.c
> > index 541986f..d77509a 100644
> > --- a/sound/pci/hda/patch_hdmi.c
> > +++ b/sound/pci/hda/patch_hdmi.c
> > @@ -86,7 +86,6 @@ struct hdmi_spec_per_pin {
> >  	struct hdmi_eld sink_eld;
> >  	struct mutex lock;
> >  	struct delayed_work work;
> > -	struct snd_kcontrol *eld_ctl;
> >  	struct hdmi_pcm *pcm; /* pointer to spec->pcm_rec[n]
> dynamically*/
> >  	int pcm_idx; /* which pcm is attached. -1 means no pcm is
> attached */
> >  	int repoll_count;
> > @@ -136,6 +135,7 @@ struct hdmi_ops {
> >  struct hdmi_pcm {
> >  	struct hda_pcm *pcm;
> >  	struct snd_jack *jack;
> > +	struct snd_kcontrol *eld_ctl;
> >  };
> >
> >  struct hdmi_spec {
> > @@ -471,17 +471,22 @@ static int hdmi_eld_ctl_info(struct
> snd_kcontrol *kcontrol,
> >  	struct hdmi_spec *spec = codec->spec;
> >  	struct hdmi_spec_per_pin *per_pin;
> >  	struct hdmi_eld *eld;
> > -	int pin_idx;
> > +	int pcm_idx;
> >
> >  	uinfo->type = SNDRV_CTL_ELEM_TYPE_BYTES;
> >
> > -	pin_idx = kcontrol->private_value;
> > -	per_pin = get_pin(spec, pin_idx);
> > +	pcm_idx = kcontrol->private_value;
> > +	mutex_lock(&spec->pcm_lock);
> > +	per_pin = pcm_idx_to_pin(spec, pcm_idx);
> > +	if (!per_pin) {
> > +		/* no pin is bound to the pcm */
> > +		uinfo->count = 0;
> > +		mutex_unlock(&spec->pcm_lock);
> > +		return 0;
> > +	}
> >  	eld = &per_pin->sink_eld;
> > -
> > -	mutex_lock(&per_pin->lock);
> >  	uinfo->count = eld->eld_valid ? eld->eld_size : 0;
> > -	mutex_unlock(&per_pin->lock);
> > +	mutex_unlock(&spec->pcm_lock);
> >
> >  	return 0;
> >  }
> > @@ -493,16 +498,23 @@ static int hdmi_eld_ctl_get(struct
> snd_kcontrol *kcontrol,
> >  	struct hdmi_spec *spec = codec->spec;
> >  	struct hdmi_spec_per_pin *per_pin;
> >  	struct hdmi_eld *eld;
> > -	int pin_idx;
> > +	int pcm_idx;
> >
> > -	pin_idx = kcontrol->private_value;
> > -	per_pin = get_pin(spec, pin_idx);
> > +	pcm_idx = kcontrol->private_value;
> > +	mutex_lock(&spec->pcm_lock);
> > +	per_pin = pcm_idx_to_pin(spec, pcm_idx);
> > +	if (!per_pin) {
> > +		/* no pin is bound to the pcm */
> > +		memset(ucontrol->value.bytes.data, 0,
> > +	       ARRAY_SIZE(ucontrol->value.bytes.data));
> > +		mutex_unlock(&spec->pcm_lock);
> > +		return 0;
> > +	}
> >  	eld = &per_pin->sink_eld;
> >
> > -	mutex_lock(&per_pin->lock);
> >  	if (eld->eld_size > ARRAY_SIZE(ucontrol->value.bytes.data) ||
> >  	    eld->eld_size > ELD_MAX_SIZE) {
> > -		mutex_unlock(&per_pin->lock);
> > +		mutex_unlock(&spec->pcm_lock);
> >  		snd_BUG();
> >  		return -EINVAL;
> >  	}
> > @@ -512,7 +524,7 @@ static int hdmi_eld_ctl_get(struct snd_kcontrol
> *kcontrol,
> >  	if (eld->eld_valid)
> >  		memcpy(ucontrol->value.bytes.data, eld->eld_buffer,
> >  		       eld->eld_size);
> > -	mutex_unlock(&per_pin->lock);
> > +	mutex_unlock(&spec->pcm_lock);
> >
> >  	return 0;
> >  }
> > @@ -525,7 +537,7 @@ static struct snd_kcontrol_new eld_bytes_ctl =
> {
> >  	.get = hdmi_eld_ctl_get,
> >  };
> >
> > -static int hdmi_create_eld_ctl(struct hda_codec *codec, int pin_idx,
> > +static int hdmi_create_eld_ctl(struct hda_codec *codec, int pcm_idx,
> >  			int device)
> >  {
> >  	struct snd_kcontrol *kctl;
> > @@ -535,14 +547,17 @@ static int hdmi_create_eld_ctl(struct
> hda_codec *codec, int pin_idx,
> >  	kctl = snd_ctl_new1(&eld_bytes_ctl, codec);
> >  	if (!kctl)
> >  		return -ENOMEM;
> > -	kctl->private_value = pin_idx;
> > +	kctl->private_value = pcm_idx;
> >  	kctl->id.device = device;
> >
> > -	err = snd_hda_ctl_add(codec, get_pin(spec, pin_idx)->pin_nid,
> kctl);
> > +	/* no pin nid is associated with the kctl now
> > +	 * tbd: associate pin nid to eld ctl later
> > +	 */
> > +	err = snd_hda_ctl_add(codec, 0, kctl);
> >  	if (err < 0)
> >  		return err;
> >
> > -	get_pin(spec, pin_idx)->eld_ctl = kctl;
> > +	get_hdmi_pcm(spec, pcm_idx)->eld_ctl = kctl;
> >  	return 0;
> >  }
> >
> > @@ -1841,7 +1856,10 @@ static void update_eld(struct hda_codec
> *codec,
> >  	struct hdmi_spec *spec = codec->spec;
> >  	bool old_eld_valid = pin_eld->eld_valid;
> >  	bool eld_changed;
> > +	int pcm_idx = -1;
> >
> > +	/* for monitor disconnection, save pcm_idx firstly */
> > +	pcm_idx = per_pin->pcm_idx;
> >  	if (spec->dyn_pcm_assign) {
> >  		if (eld->eld_valid) {
> >  			hdmi_attach_hda_pcm(spec, per_pin);
> > @@ -1851,6 +1869,11 @@ static void update_eld(struct hda_codec
> *codec,
> >  			hdmi_detach_hda_pcm(spec, per_pin);
> >  		}
> >  	}
> > +	/* if pcm_idx == -1, it means this is in monitor connection event
> > +	 * we can get the correct pcm_idx now.
> > +	 */
> > +	if (pcm_idx == -1)
> > +		pcm_idx = per_pin->pcm_idx;
> >
> >  	if (eld->eld_valid)
> >  		snd_hdmi_show_eld(codec, &eld->info);
> > @@ -1884,11 +1907,11 @@ static void update_eld(struct hda_codec
> *codec,
> >  		hdmi_setup_audio_infoframe(codec, per_pin, per_pin-
> >non_pcm);
> >  	}
> >
> > -	if (eld_changed)
> > +	if (eld_changed && pcm_idx >= 0)
> >  		snd_ctl_notify(codec->card,
> >  			       SNDRV_CTL_EVENT_MASK_VALUE |
> >  			       SNDRV_CTL_EVENT_MASK_INFO,
> > -			       &per_pin->eld_ctl->id);
> > +			       &get_hdmi_pcm(spec, pcm_idx)->eld_ctl-
> >id);
> >  }
> >
> >  /* update ELD and jack state via HD-audio verbs */
> > @@ -2629,17 +2652,16 @@ static int
> generic_hdmi_build_controls(struct hda_codec *codec)
> >  		if (err < 0)
> >  			return err;
> >  		snd_hda_spdif_ctls_unassign(codec, pcm_idx);
> > -	}
> > -
> > -	for (pin_idx = 0; pin_idx < spec->num_pins; pin_idx++) {
> > -		struct hdmi_spec_per_pin *per_pin = get_pin(spec,
> pin_idx);
> >
> >  		/* add control for ELD Bytes */
> > -		err = hdmi_create_eld_ctl(codec, pin_idx,
> > -				get_pcm_rec(spec, pin_idx)->device);
> > -
> > +		err = hdmi_create_eld_ctl(codec, pcm_idx,
> > +					get_pcm_rec(spec, pcm_idx)-
> >device);
> >  		if (err < 0)
> >  			return err;
> > +	}
> > +
> > +	for (pin_idx = 0; pin_idx < spec->num_pins; pin_idx++) {
> > +		struct hdmi_spec_per_pin *per_pin = get_pin(spec,
> pin_idx);
> >
> >  		hdmi_present_sense(per_pin, 0);
> >  	}
> > --
> > 1.9.1
> >

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [RFC PATCH] ALSA: hda - hdmi eld control created based on pcm
  2016-02-23 14:25   ` Yang, Libin
@ 2016-02-23 14:43     ` Takashi Iwai
  0 siblings, 0 replies; 4+ messages in thread
From: Takashi Iwai @ 2016-02-23 14:43 UTC (permalink / raw)
  To: Yang, Libin; +Cc: Lin, Mengdong, libin.yang, alsa-devel

On Tue, 23 Feb 2016 15:25:44 +0100,
Yang, Libin wrote:
> 
> Hi Takashi,
> 
> 
> > -----Original Message-----
> > From: Takashi Iwai [mailto:tiwai@suse.de]
> > Sent: Tuesday, February 23, 2016 9:59 PM
> > To: libin.yang@linux.intel.com
> > Cc: alsa-devel@alsa-project.org; Lin, Mengdong; Yang, Libin
> > Subject: Re: [alsa-devel] [RFC PATCH] ALSA: hda - hdmi eld control
> > created based on pcm
> > 
> > On Tue, 23 Feb 2016 09:33:37 +0100,
> > libin.yang@linux.intel.com wrote:
> > >
> > > From: Libin Yang <libin.yang@linux.intel.com>
> > >
> > > eld control is created based on pcm now.
> > > When monitor is connected, eld control will be bound to
> > > pin automatically.
> > >
> > > Signed-off-by: Libin Yang <libin.yang@linux.intel.com>
> > 
> > Looks good to me -- as long as you tested :)
> > Let me know if you'd like to merge it as is.
> 
> The patch is tested with my basic test case.
> It's great if the patch can be merged :)

OK, applied now.


thanks,

Takashi

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2016-02-23 14:43 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-02-23  8:33 [RFC PATCH] ALSA: hda - hdmi eld control created based on pcm libin.yang
2016-02-23 13:58 ` Takashi Iwai
2016-02-23 14:25   ` Yang, Libin
2016-02-23 14:43     ` Takashi Iwai

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.