summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMark Farrugia <mark.farrugia@fiberdyne.com.au>2018-10-08 12:06:46 +1100
committerMark Farrugia <mark.farrugia@fiberdyne.com.au>2018-10-26 17:27:39 +1100
commit1b8e8c7a0b998e9e458094e5f1b7b60bc1c4b297 (patch)
treeed61c88ecb60a872103d9d9bf153ba6532d0631f
parent85510ff4540c13609b3ec749a80638ae502fd098 (diff)
Refactor avirt_card_register, move PCM creation to it.
When creating the PCMs we need information regarding the stream's mapping. For the loopback, we need to add both playback and capture substreams. Signed-off-by: Mark Farrugia <mark.farrugia@fiberdyne.com.au>
-rw-r--r--configfs.c7
-rw-r--r--core.c72
-rw-r--r--core.h3
-rw-r--r--core_internal.h5
4 files changed, 56 insertions, 31 deletions
diff --git a/configfs.c b/configfs.c
index 6a82b0b..924866c 100644
--- a/configfs.c
+++ b/configfs.c
@@ -153,11 +153,6 @@ static ssize_t cfg_avirt_stream_group_sealed_store(struct config_item *item,
unsigned long tmp;
char *p = (char *)page;
- if (__avirt_streams_sealed()) {
- pr_err("AVIRT streams are already sealed!\n");
- return -EPERM;
- }
-
CHK_ERR(kstrtoul(p, 10, &tmp));
if (tmp != 1) {
@@ -165,7 +160,7 @@ static ssize_t cfg_avirt_stream_group_sealed_store(struct config_item *item,
return -ERANGE;
}
- CHK_ERR(__avirt_card_register());
+ __avirt_streams_seal();
return count;
}
diff --git a/core.c b/core.c
index cdc7556..f4f8310 100644
--- a/core.c
+++ b/core.c
@@ -189,6 +189,41 @@ static struct avirt_audiopath_obj *create_avirt_audiopath_obj(const char *uid)
return avirt_audiopath;
}
+static struct snd_pcm *pcm_create(struct avirt_stream *stream)
+{
+ bool playback = false, capture = false;
+ struct snd_pcm *pcm;
+ int err;
+
+ if (!strcmp(stream->map, "ap_loopback")) {
+ playback = true;
+ capture = true;
+ } else if (!stream->direction) {
+ playback = true;
+ } else {
+ capture = true;
+ }
+
+ err = snd_pcm_new(core.card, stream->name, stream->device, playback,
+ capture, &pcm);
+
+ if (err < 0)
+ return ERR_PTR(err);
+
+ // TD MF: IMPORTANT: NEED TO TEST >8 PCM DEVICES ON A
+ // CARD!
+ /** Register driver callbacks */
+ if (playback)
+ snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &pcm_ops);
+ if (capture)
+ snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &pcm_ops);
+
+ pcm->info_flags = 0;
+ strcpy(pcm->name, stream->name);
+
+ return pcm;
+}
+
/**
* destroy_avirt_audiopath_obj - destroys an Audio Path object
* @name: the Audio Path object
@@ -323,51 +358,46 @@ EXPORT_SYMBOL_GPL(avirt_stream_count);
*/
struct avirt_stream *__avirt_stream_create(const char *name, int direction)
{
- struct snd_pcm *pcm;
struct avirt_stream *stream;
- int err;
stream = kzalloc(sizeof(*stream), GFP_KERNEL);
if (!stream)
return ERR_PTR(-ENOMEM);
strcpy(stream->name, name);
- strcpy(stream->map, "ap_fddsp");
+ strcpy(stream->map, "none");
stream->channels = 0;
stream->direction = direction;
stream->device = core.stream_count++;
- err = snd_pcm_new(core.card, name, stream->device, !direction,
- direction, &pcm);
- if (err < 0)
- return ERR_PTR(err);
-
- // TD MF: IMPORTANT: NEED TO TEST >8 PCM DEVICES ON A
- // CARD!
- /** Register driver callbacks */
- snd_pcm_set_ops(pcm, direction, &pcm_ops);
-
- pcm->info_flags = 0;
- strcpy(pcm->name, name);
-
- pr_info("%s [ARGS] name: %s device:%d\n", __func__, name,
- stream->device);
-
- // coreinfo.streams[stream_idx] = stream;
+ D_INFOK("name: %s device:%d", name, stream->device);
return stream;
}
-int __avirt_card_register(void)
+int __avirt_streams_seal(void)
{
int err = 0;
struct avirt_audiopath_obj *ap_obj;
+ struct avirt_stream *stream;
+ struct config_item *item;
+ struct list_head *entry;
if (core.streams_sealed) {
D_ERRORK("streams are already sealed!");
return -1;
}
+ list_for_each (entry, &core.stream_group->cg_children) {
+ item = container_of(entry, struct config_item, ci_entry);
+ stream = avirt_stream_from_config_item(item);
+ if (!stream)
+ return -EFAULT;
+ stream->pcm = pcm_create(stream);
+ if (IS_ERR_OR_NULL(stream->pcm))
+ return (PTR_ERR(stream->pcm));
+ }
+
list_for_each_entry (ap_obj, &audiopath_list, list) {
D_INFOK("configure() AP uid: %s", ap_obj->path->uid);
ap_obj->path->configure(core.card, core.stream_group,
diff --git a/core.h b/core.h
index b7c250a..bac4fc0 100644
--- a/core.h
+++ b/core.h
@@ -59,6 +59,7 @@ struct avirt_stream {
unsigned int channels; /* Stream channel count */
unsigned int device; /* Stream PCM device no. */
unsigned int direction; /* Stream direction */
+ struct snd_pcm *pcm; /* ALSA PCM */
struct config_item item; /* configfs item reference */
};
@@ -105,7 +106,7 @@ int avirt_stream_count(unsigned int direction);
* @return: The item's avirt_stream if successful, NULL otherwise
*/
static inline struct avirt_stream *
- avirt_stream_from_config_item(struct config_item *item)
+avirt_stream_from_config_item(struct config_item *item)
{
return item ? container_of(item, struct avirt_stream, item) : NULL;
}
diff --git a/core_internal.h b/core_internal.h
index 5979a50..1ab8d3c 100644
--- a/core_internal.h
+++ b/core_internal.h
@@ -37,10 +37,10 @@ int __init __avirt_configfs_init(struct avirt_core *core);
void __exit __avirt_configfs_exit(struct avirt_core *core);
/**
- * __avirt_card_register - Register the sound card to user space
+ * __avirt_streams_seal - Register the sound card to user space
* @return: 0 on success, negative ERRNO on failure
*/
-int __avirt_card_register(void);
+int __avirt_streams_seal(void);
/**
* __avirt_streams_sealed - Check whether the streams have been sealed or not
@@ -49,7 +49,6 @@ int __avirt_card_register(void);
bool __avirt_streams_sealed(void);
/**
-/**
* __avirt_stream_find_by_device - Get audio stream from device number
* @device: The PCM device number corresponding to the desired stream
* @return: The audio stream if found, or an error pointer otherwise