aboutsummaryrefslogtreecommitdiffstats
path: root/alsa-pcm.c
diff options
context:
space:
mode:
authorMark Farrugia <mark.farrugia@fiberdyne.com.au>2018-10-01 17:43:39 +1000
committerMark Farrugia <mark.farrugia@fiberdyne.com.au>2018-10-26 17:27:35 +1100
commit3247d61d378afd8fc76f1e9182e5691bd538ab3f (patch)
tree02485f2a47d8df1c5dbaa11007d6439bac0951e0 /alsa-pcm.c
parent6c5c0d66a792ecbbf92538a7822b62a36710a341 (diff)
Add configfs interface, revamp stream grouping
Add additional callbacks for audio path configuring, after card has been sealed. Signed-off-by: Mark Farrugia <mark.farrugia@fiberdyne.com.au>
Diffstat (limited to 'alsa-pcm.c')
-rw-r--r--alsa-pcm.c82
1 files changed, 29 insertions, 53 deletions
diff --git a/alsa-pcm.c b/alsa-pcm.c
index 21287ee..5a30aff 100644
--- a/alsa-pcm.c
+++ b/alsa-pcm.c
@@ -7,46 +7,30 @@
* Copyright (C) 2010-2018 Fiberdyne Systems Pty Ltd
*/
-#include "alsa-pcm.h"
-#include "utils.h"
-
-#define DO_AUDIOPATH_CB(ap, callback, substream, ...) \
- do { \
- if (ap->pcm_ops->callback) { \
- return ap->pcm_ops->callback((substream), \
- ##__VA_ARGS__); \
- } \
+#include "core_internal.h"
+
+#define DO_AUDIOPATH_CB(ap, callback, substream, ...) \
+ do { \
+ if ((ap)->pcm_ops->callback) { \
+ return (ap)->pcm_ops->callback((substream), \
+ ##__VA_ARGS__); \
+ } \
} while (0)
/**
- * pcm_buff_complete_cb - PCM buffer complete callback
+ * avirt_pcm_period_elapsed - PCM buffer complete callback
* @substreamid: pointer to ALSA PCM substream
- * @return 0 on success or error code otherwise
*
* This should be called from a child Audio Path once it has finished processing
* the pcm buffer
*/
-int pcm_buff_complete_cb(struct snd_pcm_substream *substream)
+void avirt_pcm_period_elapsed(struct snd_pcm_substream *substream)
{
// Notify ALSA middle layer of the elapsed period boundary
snd_pcm_period_elapsed(substream);
-
- return 0;
}
+EXPORT_SYMBOL_GPL(avirt_pcm_period_elapsed);
-static struct avirt_stream_group *avirt_stream_get_group(int direction)
-{
- switch (direction) {
- case SNDRV_PCM_STREAM_PLAYBACK:
- return &coreinfo.playback;
- case SNDRV_PCM_STREAM_CAPTURE:
- return &coreinfo.capture;
- default:
- pr_err("[%s] Direction must be SNDRV_PCM_STREAM_XXX!",
- __func__);
- return NULL;
- }
-}
/*******************************************************************************
* ALSA PCM Callbacks
@@ -63,13 +47,14 @@ static struct avirt_stream_group *avirt_stream_get_group(int direction)
static int pcm_open(struct snd_pcm_substream *substream)
{
struct avirt_audiopath *audiopath;
- struct avirt_stream_group *group;
+ struct avirt_stream *stream;
struct snd_pcm_hardware *hw;
unsigned int bytes_per_sample = 0, blocksize = 0, chans = 0;
char *uid = "ap_fddsp"; // TD MF: Make this dynamic!
audiopath = avirt_audiopath_get(uid);
- CHK_NULL_V(audiopath, "Cannot find Audio Path uid: '%s'!", uid);
+ CHK_NULL_V(audiopath, -EFAULT, "Cannot find Audio Path uid: '%s'!",
+ uid);
substream->private_data = audiopath;
blocksize = audiopath->blocksize;
@@ -87,20 +72,12 @@ static int pcm_open(struct snd_pcm_substream *substream)
return -EINVAL;
}
- // Get device group (playback/capture)
- group = avirt_stream_get_group(substream->stream);
- CHK_NULL(group);
-
- // Check if substream id is valid
- pr_info("%d substream is < %d", substream->pcm->device, group->devices);
- if (substream->pcm->device >= group->devices) {
- pr_err("%s %d substream id is invalid expecting %d", __func__,
- substream->pcm->device, group->devices);
- return -1;
- }
+ stream = __avirt_stream_find_by_device(substream->pcm->device);
+ if (IS_ERR_VALUE(stream) || !stream)
+ return PTR_ERR(stream);
// Setup remaining hw properties
- chans = group->streams[substream->pcm->device].channels;
+ chans = stream->channels;
hw->channels_min = chans;
hw->channels_max = chans;
hw->buffer_bytes_max =
@@ -145,18 +122,17 @@ static int pcm_close(struct snd_pcm_substream *substream)
static int pcm_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *hw_params)
{
- int channels, err;
+ int err;
size_t bufsz;
struct avirt_audiopath *audiopath;
- struct avirt_stream_group *group;
-
- group = avirt_stream_get_group(substream->stream);
- CHK_NULL(group);
+ struct avirt_stream *stream;
- channels = group->streams[substream->pcm->device].channels;
+ stream = __avirt_stream_find_by_device(substream->pcm->device);
+ if (IS_ERR_VALUE(stream) || !stream)
+ return PTR_ERR(stream);
- if ((params_channels(hw_params) > channels) ||
- (params_channels(hw_params) < channels)) {
+ if ((params_channels(hw_params) > stream->channels)
+ || (params_channels(hw_params) < stream->channels)) {
pr_err("Requested number of channels not supported.\n");
return -EINVAL;
}
@@ -306,11 +282,11 @@ static int pcm_copy_user(struct snd_pcm_substream *substream, int channel,
snd_pcm_uframes_t pos, void __user *src,
snd_pcm_uframes_t count)
{
- //struct snd_pcm_runtime *runtime;
- //int offset;
+ // struct snd_pcm_runtime *runtime;
+ // int offset;
- //runtime = substream->runtime;
- //offset = frames_to_bytes(runtime, pos);
+ // runtime = substream->runtime;
+ // offset = frames_to_bytes(runtime, pos);
// Do additional Audio Path 'copy_user' callback
DO_AUDIOPATH_CB(((struct avirt_audiopath *)substream->private_data),