aboutsummaryrefslogtreecommitdiffstats
path: root/core.c
diff options
context:
space:
mode:
Diffstat (limited to 'core.c')
-rw-r--r--core.c51
1 files changed, 51 insertions, 0 deletions
diff --git a/core.c b/core.c
index d9e264c..c2e32c5 100644
--- a/core.c
+++ b/core.c
@@ -112,6 +112,30 @@ static struct snd_pcm *snd_avirt_pcm_create(struct snd_avirt_stream *stream)
return pcm;
}
+void snd_avirt_stream_try_destroy(struct snd_avirt_stream *stream)
+{
+ unsigned long _flags;
+ struct snd_pcm_substream *substream =
+ stream->pcm->streams[stream->direction].substream;
+
+ snd_pcm_stream_lock_irqsave(substream, _flags);
+ if (substream->runtime) {
+ if (snd_pcm_running(substream)) {
+ if (0 !=
+ snd_pcm_stop(substream, SNDRV_PCM_STATE_SUSPENDED))
+ D_ERRORK("Could not stop PCM '%s'",
+ stream->name);
+ }
+ }
+ snd_pcm_stream_unlock_irqrestore(substream, _flags);
+
+ snd_device_free(core.card, stream->pcm);
+ kfree(stream->pcm_ops);
+ kfree(stream);
+
+ core.stream_count--;
+}
+
static struct snd_avirt_route *snd_avirt_route_get(const char *uid)
{
struct list_head *entry;
@@ -620,6 +644,33 @@ int snd_avirt_streams_configure(void)
return err;
}
+int snd_avirt_streams_unconfigure(void)
+{
+ int i = 0, err = 0;
+ struct snd_avirt_audiopath_obj *ap_obj;
+ struct snd_avirt_stream_array stream_array;
+
+ if (!core.streams_configured) {
+ D_ERRORK("streams are already unconfigured!");
+ return -1;
+ }
+
+ list_for_each_entry (ap_obj, &audiopath_list, list) {
+ if (!ap_obj->path->unconfigure) {
+ D_ERRORK("Cannot do 'unconfigure' for AP: %s",
+ ap_obj->path->uid);
+ return -EFAULT;
+ }
+
+ D_INFOK("Do 'unconfigure' for AP: %s", ap_obj->path->uid);
+ ap_obj->path->unconfigure();
+ }
+
+ core.streams_configured = false;
+
+ return 0;
+}
+
bool snd_avirt_streams_configured(void)
{
return core.streams_configured;