aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWu Fengguang <fengguang.wu@intel.com>2009-12-25 00:14:27 -0500
committerTakashi Iwai <tiwai@suse.de>2009-12-25 08:17:36 -0500
commitef18beded8ddbaafdf4914bab209f77e60ae3a18 (patch)
treea0dc41a87c0d6d68f328ae983ae7a6ffd1444271
parent6b7b284958d47b77d06745b36bc7f36dab769d9b (diff)
ALSA: hda - HDMI sticky stream tag support
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> Signed-off-by: Takashi Iwai <tiwai@suse.de>
-rw-r--r--sound/pci/hda/hda_intel.c21
1 files changed, 15 insertions, 6 deletions
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c
index ff8ad46cc50e..ec9c348336cc 100644
--- a/sound/pci/hda/hda_intel.c
+++ b/sound/pci/hda/hda_intel.c
@@ -356,6 +356,7 @@ struct azx_dev {
356 */ 356 */
357 unsigned char stream_tag; /* assigned stream */ 357 unsigned char stream_tag; /* assigned stream */
358 unsigned char index; /* stream index */ 358 unsigned char index; /* stream index */
359 int device; /* last device number assigned to */
359 360
360 unsigned int opened :1; 361 unsigned int opened :1;
361 unsigned int running :1; 362 unsigned int running :1;
@@ -1441,10 +1442,13 @@ static int __devinit azx_codec_configure(struct azx *chip)
1441 */ 1442 */
1442 1443
1443/* assign a stream for the PCM */ 1444/* assign a stream for the PCM */
1444static inline struct azx_dev *azx_assign_device(struct azx *chip, int stream) 1445static inline struct azx_dev *
1446azx_assign_device(struct azx *chip, struct snd_pcm_substream *substream)
1445{ 1447{
1446 int dev, i, nums; 1448 int dev, i, nums;
1447 if (stream == SNDRV_PCM_STREAM_PLAYBACK) { 1449 struct azx_dev *res = NULL;
1450
1451 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
1448 dev = chip->playback_index_offset; 1452 dev = chip->playback_index_offset;
1449 nums = chip->playback_streams; 1453 nums = chip->playback_streams;
1450 } else { 1454 } else {
@@ -1453,10 +1457,15 @@ static inline struct azx_dev *azx_assign_device(struct azx *chip, int stream)
1453 } 1457 }
1454 for (i = 0; i < nums; i++, dev++) 1458 for (i = 0; i < nums; i++, dev++)
1455 if (!chip->azx_dev[dev].opened) { 1459 if (!chip->azx_dev[dev].opened) {
1456 chip->azx_dev[dev].opened = 1; 1460 res = &chip->azx_dev[dev];
1457 return &chip->azx_dev[dev]; 1461 if (res->device == substream->pcm->device)
1462 break;
1458 } 1463 }
1459 return NULL; 1464 if (res) {
1465 res->opened = 1;
1466 res->device = substream->pcm->device;
1467 }
1468 return res;
1460} 1469}
1461 1470
1462/* release the assigned stream */ 1471/* release the assigned stream */
@@ -1505,7 +1514,7 @@ static int azx_pcm_open(struct snd_pcm_substream *substream)
1505 int err; 1514 int err;
1506 1515
1507 mutex_lock(&chip->open_mutex); 1516 mutex_lock(&chip->open_mutex);
1508 azx_dev = azx_assign_device(chip, substream->stream); 1517 azx_dev = azx_assign_device(chip, substream);
1509 if (azx_dev == NULL) { 1518 if (azx_dev == NULL) {
1510 mutex_unlock(&chip->open_mutex); 1519 mutex_unlock(&chip->open_mutex);
1511 return -EBUSY; 1520 return -EBUSY;