From: Rafal Redzimski rafal.f.redzimski@intel.com
According to hda specification stream tag must be unique throughout the input streams group, however an output stream might use a stream tag which is already in use by an input stream.
Newer Intel HW has the capability to provides a total of more than 15 stream DMA engines which with the current implementation causes an overflow on STRM field (and the whole register) which results in usage of reserved value 0 in the STRM field which confuses HDA controller. So make stream_tag assignment separate for input and output streams
Signed-off-by: Rafal Redzimski rafal.f.redzimski@intel.com Signed-off-by: Vinod Koul vinod.koul@intel.com --- sound/pci/hda/hda_controller.c | 14 ++++++++++++-- 1 files changed, 12 insertions(+), 2 deletions(-)
diff --git a/sound/pci/hda/hda_controller.c b/sound/pci/hda/hda_controller.c index 8337645..703ac6e 100644 --- a/sound/pci/hda/hda_controller.c +++ b/sound/pci/hda/hda_controller.c @@ -1921,11 +1921,17 @@ int azx_mixer_create(struct azx *chip) } EXPORT_SYMBOL_GPL(azx_mixer_create);
+static bool is_input_stream(struct azx *chip, unsigned char index) +{ + return index < chip->playback_index_offset; +}
/* initialize SD streams */ int azx_init_stream(struct azx *chip) { int i; + int in_stream_tag = 0; + int out_stream_tag = 0;
/* initialize each stream (aka device) * assign the starting bdl address to each stream (device) @@ -1938,9 +1944,13 @@ int azx_init_stream(struct azx *chip) azx_dev->sd_addr = chip->remap_addr + (0x20 * i + 0x80); /* int mask: SDI0=0x01, SDI1=0x02, ... SDO3=0x80 */ azx_dev->sd_int_sta_mask = 1 << i; - /* stream tag: must be non-zero and unique */ azx_dev->index = i; - azx_dev->stream_tag = i + 1; + + /* stream tag must be unique throughout the stream direction + * group, valid values 1...15 + */ + azx_dev->stream_tag = is_input_stream(chip, i) ? + ++in_stream_tag : ++out_stream_tag; }
return 0;