diff options
author | Mark Farrugia <mark.farrugia@fiberdyne.com.au> | 2018-10-08 12:06:46 +1100 |
---|---|---|
committer | Mark Farrugia <mark.farrugia@fiberdyne.com.au> | 2018-10-26 17:27:39 +1100 |
commit | 1b8e8c7a0b998e9e458094e5f1b7b60bc1c4b297 (patch) | |
tree | ed61c88ecb60a872103d9d9bf153ba6532d0631f | |
parent | 85510ff4540c13609b3ec749a80638ae502fd098 (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.c | 7 | ||||
-rw-r--r-- | core.c | 72 | ||||
-rw-r--r-- | core.h | 3 | ||||
-rw-r--r-- | core_internal.h | 5 |
4 files changed, 56 insertions, 31 deletions
@@ -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; } @@ -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, @@ -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 |