summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRafal Redzimski <rafal.f.redzimski@intel.com>2014-12-19 01:44:30 +0100
committerTakashi Iwai <tiwai@suse.de>2014-12-26 12:21:21 +0100
commit93e3423e6ba4b0ddaf056ecbdf5bc46f18f41deb (patch)
treef1c490d8bdcc06665c914ebe77f5b7f10c6caf19
parentLinux 3.19-rc1 (diff)
downloadlinux-93e3423e6ba4b0ddaf056ecbdf5bc46f18f41deb.tar.xz
linux-93e3423e6ba4b0ddaf056ecbdf5bc46f18f41deb.zip
ALSA: hda_controller: Separate stream_tag for input and output streams.
Implemented separate stream_tag assignment for input and output streams. 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. This change is necessary to support HW which provides a total of more than 15 stream DMA engines which with legacy implementation causes an overflow on SDxCTL.STRM field (and the whole SDxCTL register) and as a result usage of Reserved value 0 in the SDxCTL.STRM field which confuses HDA controller. Signed-off-by: Rafal Redzimski <rafal.f.redzimski@intel.com> Signed-off-by: Jayachandran B <jayachandran.b@intel.com> Signed-off-by: Libin Yang <libin.yang@intel.com> Reviewed-by: Vinod Koul <vinod.koul@intel.com> Signed-off-by: Takashi Iwai <tiwai@suse.de>
-rw-r--r--sound/pci/hda/hda_controller.c24
-rw-r--r--sound/pci/hda/hda_priv.h1
2 files changed, 23 insertions, 2 deletions
diff --git a/sound/pci/hda/hda_controller.c b/sound/pci/hda/hda_controller.c
index 8276a743e22e..0cfc9c8c4b4e 100644
--- a/sound/pci/hda/hda_controller.c
+++ b/sound/pci/hda/hda_controller.c
@@ -1922,10 +1922,18 @@ 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->capture_index_offset &&
+ index < chip->capture_index_offset + chip->capture_streams);
+}
+
/* 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 +1946,21 @@ 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
+ * use separate stream tag if the flag
+ * AZX_DCAPS_SEPARATE_STREAM_TAG is used
+ */
+ if (chip->driver_caps & AZX_DCAPS_SEPARATE_STREAM_TAG)
+ azx_dev->stream_tag =
+ is_input_stream(chip, i) ?
+ ++in_stream_tag :
+ ++out_stream_tag;
+ else
+ azx_dev->stream_tag = i + 1;
}
return 0;
diff --git a/sound/pci/hda/hda_priv.h b/sound/pci/hda/hda_priv.h
index aa484fdf4338..166e3e84b963 100644
--- a/sound/pci/hda/hda_priv.h
+++ b/sound/pci/hda/hda_priv.h
@@ -171,6 +171,7 @@ enum { SDI0, SDI1, SDI2, SDI3, SDO0, SDO1, SDO2, SDO3 };
#define AZX_DCAPS_I915_POWERWELL (1 << 27) /* HSW i915 powerwell support */
#define AZX_DCAPS_CORBRP_SELF_CLEAR (1 << 28) /* CORBRP clears itself after reset */
#define AZX_DCAPS_NO_MSI64 (1 << 29) /* Stick to 32-bit MSIs */
+#define AZX_DCAPS_SEPARATE_STREAM_TAG (1 << 30) /* capture and playback use separate stream tag */
enum {
AZX_SNOOP_TYPE_NONE ,