summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/sound/hdaudio_ext.h2
-rw-r--r--sound/hda/ext/hdac_ext_stream.c41
2 files changed, 43 insertions, 0 deletions
diff --git a/include/sound/hdaudio_ext.h b/include/sound/hdaudio_ext.h
index 68ab89211de2..511211f4a2b6 100644
--- a/include/sound/hdaudio_ext.h
+++ b/include/sound/hdaudio_ext.h
@@ -75,6 +75,8 @@ struct hdac_ext_stream *snd_hdac_ext_stream_assign(struct hdac_bus *bus,
struct snd_pcm_substream *substream,
int type);
void snd_hdac_ext_stream_release(struct hdac_ext_stream *hext_stream, int type);
+struct hdac_ext_stream *snd_hdac_ext_cstream_assign(struct hdac_bus *bus,
+ struct snd_compr_stream *cstream);
void snd_hdac_ext_stream_decouple_locked(struct hdac_bus *bus,
struct hdac_ext_stream *hext_stream, bool decouple);
void snd_hdac_ext_stream_decouple(struct hdac_bus *bus,
diff --git a/sound/hda/ext/hdac_ext_stream.c b/sound/hda/ext/hdac_ext_stream.c
index 2a071a09224d..11b7119cc47e 100644
--- a/sound/hda/ext/hdac_ext_stream.c
+++ b/sound/hda/ext/hdac_ext_stream.c
@@ -14,6 +14,7 @@
#include <sound/pcm.h>
#include <sound/hda_register.h>
#include <sound/hdaudio_ext.h>
+#include <sound/compress_driver.h>
/**
* snd_hdac_ext_stream_init - initialize each stream (aka device)
@@ -367,3 +368,43 @@ void snd_hdac_ext_stream_release(struct hdac_ext_stream *hext_stream, int type)
}
EXPORT_SYMBOL_GPL(snd_hdac_ext_stream_release);
+
+/**
+ * snd_hdac_ext_cstream_assign - assign a host stream for compress
+ * @bus: HD-audio core bus
+ * @cstream: Compress stream to assign
+ *
+ * Assign an unused host stream for the given compress stream.
+ * If no stream is free, NULL is returned. Stream is decoupled
+ * before assignment.
+ */
+struct hdac_ext_stream *snd_hdac_ext_cstream_assign(struct hdac_bus *bus,
+ struct snd_compr_stream *cstream)
+{
+ struct hdac_ext_stream *res = NULL;
+ struct hdac_stream *hstream;
+
+ spin_lock_irq(&bus->reg_lock);
+ list_for_each_entry(hstream, &bus->stream_list, list) {
+ struct hdac_ext_stream *hext_stream = stream_to_hdac_ext_stream(hstream);
+
+ if (hstream->direction != cstream->direction)
+ continue;
+
+ if (!hstream->opened) {
+ res = hext_stream;
+ break;
+ }
+ }
+
+ if (res) {
+ snd_hdac_ext_stream_decouple_locked(bus, res, true);
+ res->hstream.opened = 1;
+ res->hstream.running = 0;
+ res->hstream.cstream = cstream;
+ }
+ spin_unlock_irq(&bus->reg_lock);
+
+ return res;
+}
+EXPORT_SYMBOL_GPL(snd_hdac_ext_cstream_assign);