All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] hda - HDMI sticky stream tag support
@ 2009-12-25  5:14 Wu Fengguang
  2009-12-25 13:24 ` Takashi Iwai
  0 siblings, 1 reply; 2+ messages in thread
From: Wu Fengguang @ 2009-12-25  5:14 UTC (permalink / raw)
  To: Takashi Iwai; +Cc: alsa-devel

When we run the following commands in turn (with
CONFIG_SND_HDA_POWER_SAVE_DEFAULT=0),

	speaker-test -Dhw:0,3 -c2 -twav  # HDMI
	speaker-test -Dhw:0,0 -c2 -twav  # Analog

The second command will produce sound in the analog lineout _as well as_
HDMI sink. The root cause is, device 0 "reuses" the same stream tag that
was used by device 3, and the "intelhdmi - sticky stream id" patch leaves
the HDMI codec in a functional state. So the HDMI codec happily accepts
the audio samples which reuse its stream tag.

The proposed solution is to remember the last device each azx_dev was
assigned to, and prefer to
1) reuse the azx_dev (and hence the stream tag) the HDMI codec last used
2) or assign a never-used azx_dev for HDMI

With this patch and the above two speaker-test commands, 
HDMI codec will use stream tag 8 and Analog codec will use 5.

The stream tag used by HDMI codec won't be reused by others, as long
as we don't run out of the 4 playback azx_dev's. The legacy Analog
codec will continue to use stream tag 5 because its device id is 0
(this is a bit tricky).

Signed-off-by: Wu Fengguang <fengguang.wu@intel.com>
---
 sound/pci/hda/hda_intel.c |   21 +++++++++++++++------
 1 file changed, 15 insertions(+), 6 deletions(-)

--- sound-2.6.orig/sound/pci/hda/hda_intel.c	2009-12-25 12:17:28.000000000 +0800
+++ sound-2.6/sound/pci/hda/hda_intel.c	2009-12-25 12:41:02.000000000 +0800
@@ -356,6 +356,7 @@ struct azx_dev {
 					 */
 	unsigned char stream_tag;	/* assigned stream */
 	unsigned char index;		/* stream index */
+	int device;			/* last device number assigned to */
 
 	unsigned int opened :1;
 	unsigned int running :1;
@@ -1441,10 +1442,13 @@ static int __devinit azx_codec_configure
  */
 
 /* assign a stream for the PCM */
-static inline struct azx_dev *azx_assign_device(struct azx *chip, int stream)
+static inline struct azx_dev *
+azx_assign_device(struct azx *chip, struct snd_pcm_substream *substream)
 {
 	int dev, i, nums;
-	if (stream == SNDRV_PCM_STREAM_PLAYBACK) {
+	struct azx_dev *res = NULL;
+
+	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
 		dev = chip->playback_index_offset;
 		nums = chip->playback_streams;
 	} else {
@@ -1453,10 +1457,15 @@ static inline struct azx_dev *azx_assign
 	}
 	for (i = 0; i < nums; i++, dev++)
 		if (!chip->azx_dev[dev].opened) {
-			chip->azx_dev[dev].opened = 1;
-			return &chip->azx_dev[dev];
+			res = &chip->azx_dev[dev];
+			if (res->device == substream->pcm->device)
+				break;
 		}
-	return NULL;
+	if (res) {
+		res->opened = 1;
+		res->device = substream->pcm->device;
+	}
+	return res;
 }
 
 /* release the assigned stream */
@@ -1505,7 +1514,7 @@ static int azx_pcm_open(struct snd_pcm_s
 	int err;
 
 	mutex_lock(&chip->open_mutex);
-	azx_dev = azx_assign_device(chip, substream->stream);
+	azx_dev = azx_assign_device(chip, substream);
 	if (azx_dev == NULL) {
 		mutex_unlock(&chip->open_mutex);
 		return -EBUSY;

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

* Re: [PATCH] hda - HDMI sticky stream tag support
  2009-12-25  5:14 [PATCH] hda - HDMI sticky stream tag support Wu Fengguang
@ 2009-12-25 13:24 ` Takashi Iwai
  0 siblings, 0 replies; 2+ messages in thread
From: Takashi Iwai @ 2009-12-25 13:24 UTC (permalink / raw)
  To: Wu Fengguang; +Cc: alsa-devel

At Fri, 25 Dec 2009 13:14:27 +0800,
Wu Fengguang wrote:
> 
> When we run the following commands in turn (with
> CONFIG_SND_HDA_POWER_SAVE_DEFAULT=0),
> 
> 	speaker-test -Dhw:0,3 -c2 -twav  # HDMI
> 	speaker-test -Dhw:0,0 -c2 -twav  # Analog
> 
> The second command will produce sound in the analog lineout _as well as_
> HDMI sink. The root cause is, device 0 "reuses" the same stream tag that
> was used by device 3, and the "intelhdmi - sticky stream id" patch leaves
> the HDMI codec in a functional state. So the HDMI codec happily accepts
> the audio samples which reuse its stream tag.
> 
> The proposed solution is to remember the last device each azx_dev was
> assigned to, and prefer to
> 1) reuse the azx_dev (and hence the stream tag) the HDMI codec last used
> 2) or assign a never-used azx_dev for HDMI
> 
> With this patch and the above two speaker-test commands, 
> HDMI codec will use stream tag 8 and Analog codec will use 5.
> 
> The stream tag used by HDMI codec won't be reused by others, as long
> as we don't run out of the 4 playback azx_dev's. The legacy Analog
> codec will continue to use stream tag 5 because its device id is 0
> (this is a bit tricky).
> 
> Signed-off-by: Wu Fengguang <fengguang.wu@intel.com>

Applied now.  I thought of a similar patch, but you were fast ;)

Thanks,


Takashi

> ---
>  sound/pci/hda/hda_intel.c |   21 +++++++++++++++------
>  1 file changed, 15 insertions(+), 6 deletions(-)
> 
> --- sound-2.6.orig/sound/pci/hda/hda_intel.c	2009-12-25 12:17:28.000000000 +0800
> +++ sound-2.6/sound/pci/hda/hda_intel.c	2009-12-25 12:41:02.000000000 +0800
> @@ -356,6 +356,7 @@ struct azx_dev {
>  					 */
>  	unsigned char stream_tag;	/* assigned stream */
>  	unsigned char index;		/* stream index */
> +	int device;			/* last device number assigned to */
>  
>  	unsigned int opened :1;
>  	unsigned int running :1;
> @@ -1441,10 +1442,13 @@ static int __devinit azx_codec_configure
>   */
>  
>  /* assign a stream for the PCM */
> -static inline struct azx_dev *azx_assign_device(struct azx *chip, int stream)
> +static inline struct azx_dev *
> +azx_assign_device(struct azx *chip, struct snd_pcm_substream *substream)
>  {
>  	int dev, i, nums;
> -	if (stream == SNDRV_PCM_STREAM_PLAYBACK) {
> +	struct azx_dev *res = NULL;
> +
> +	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
>  		dev = chip->playback_index_offset;
>  		nums = chip->playback_streams;
>  	} else {
> @@ -1453,10 +1457,15 @@ static inline struct azx_dev *azx_assign
>  	}
>  	for (i = 0; i < nums; i++, dev++)
>  		if (!chip->azx_dev[dev].opened) {
> -			chip->azx_dev[dev].opened = 1;
> -			return &chip->azx_dev[dev];
> +			res = &chip->azx_dev[dev];
> +			if (res->device == substream->pcm->device)
> +				break;
>  		}
> -	return NULL;
> +	if (res) {
> +		res->opened = 1;
> +		res->device = substream->pcm->device;
> +	}
> +	return res;
>  }
>  
>  /* release the assigned stream */
> @@ -1505,7 +1514,7 @@ static int azx_pcm_open(struct snd_pcm_s
>  	int err;
>  
>  	mutex_lock(&chip->open_mutex);
> -	azx_dev = azx_assign_device(chip, substream->stream);
> +	azx_dev = azx_assign_device(chip, substream);
>  	if (azx_dev == NULL) {
>  		mutex_unlock(&chip->open_mutex);
>  		return -EBUSY;
> 

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

end of thread, other threads:[~2009-12-25 13:24 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2009-12-25  5:14 [PATCH] hda - HDMI sticky stream tag support Wu Fengguang
2009-12-25 13:24 ` 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.