summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMark Farrugia <mark.farrugia@fiberdyne.com.au>2018-09-20 12:09:20 +1000
committerMark Farrugia <mark.farrugia@fiberdyne.com.au>2018-10-26 17:27:33 +1100
commit3786b607d4dd5e738cbe491dbfb03c2283e74358 (patch)
tree83f150ee7eee8ab42d827f6a1b3c5af68ac9fcbd
parent99a09bc4fe16d275b2bf839cb8f37192b2235e24 (diff)
Add 'uid' field to AP, store AP in PCM private data, fix helper macros
We want to use a UID when registering APs, that must start with "ap_", and acts as a unique identifier for each AP. To move forward with the adoption of routing PCMs to differing APs, we now store the AP in the PCM private data - set at pcm_open. A fix to the helper macros now allows additional args to be passed in for inclusion to the debug string Signed-off-by: Mark Farrugia <mark.farrugia@fiberdyne.com.au>
-rw-r--r--alsa-pcm.c53
-rwxr-xr-xalsa.c1
-rwxr-xr-xalsa.h20
-rw-r--r--core.c33
-rw-r--r--core.h27
-rw-r--r--dummy/dummy.c1
6 files changed, 79 insertions, 56 deletions
diff --git a/alsa-pcm.c b/alsa-pcm.c
index 9b55a14..ac9175b 100644
--- a/alsa-pcm.c
+++ b/alsa-pcm.c
@@ -9,13 +9,8 @@
#include "alsa.h"
-#define AP_LOGNAME "CORE"
-
-#define DO_AUDIOPATH_CB(callback, substream, ...) \
+#define DO_AUDIOPATH_CB(ap, callback, substream, ...) \
do { \
- struct avirt_audiopath *ap; \
- ap = avirt_get_current_audiopath(); \
- CHK_NULL_V(ap, "Cannot find Audio Path!"); \
if (ap->pcm_ops->callback) { \
return ap->pcm_ops->callback((substream), \
##__VA_ARGS__); \
@@ -42,8 +37,10 @@ static int pcm_open(struct snd_pcm_substream *substream)
struct snd_pcm_hardware *hw;
unsigned int bytes_per_sample = 0, blocksize = 0;
- audiopath = avirt_get_current_audiopath();
- CHK_NULL_V(audiopath, "Cannot find Audio Path!");
+ char *uid = "ap_dummy"; // TD MF: Make this dynamic!
+ audiopath = avirt_get_audiopath(uid);
+ CHK_NULL_V(audiopath, "Cannot find Audio Path uid: '%s'!", uid);
+ substream->private_data = audiopath;
blocksize = audiopath->blocksize;
@@ -82,7 +79,7 @@ static int pcm_open(struct snd_pcm_substream *substream)
hw->period_bytes_max = blocksize * bytes_per_sample * config->channels;
// Do additional Audio Path 'open' callback
- DO_AUDIOPATH_CB(open, substream);
+ DO_AUDIOPATH_CB(audiopath, open, substream);
return 0;
}
@@ -99,7 +96,8 @@ static int pcm_close(struct snd_pcm_substream *substream)
{
DINFO(AP_LOGNAME, "");
// Do additional Audio Path 'close' callback
- DO_AUDIOPATH_CB(close, substream);
+ DO_AUDIOPATH_CB(((struct avirt_audiopath *)substream->private_data),
+ close, substream);
return 0;
}
@@ -133,9 +131,7 @@ static int pcm_hw_params(struct snd_pcm_substream *substream,
return -EINVAL;
}
- audiopath = avirt_get_current_audiopath();
- CHK_NULL_V(audiopath, "Cannot find Audio Path!");
-
+ audiopath = ((struct avirt_audiopath *)substream->private_data);
bufsz = params_buffer_bytes(hw_params) * audiopath->hw->periods_max;
err = snd_pcm_lib_alloc_vmalloc_buffer(substream, bufsz);
@@ -183,7 +179,8 @@ static int pcm_hw_free(struct snd_pcm_substream *substream)
static int pcm_prepare(struct snd_pcm_substream *substream)
{
// Do additional Audio Path 'prepare' callback
- DO_AUDIOPATH_CB(prepare, substream);
+ DO_AUDIOPATH_CB(((struct avirt_audiopath *)substream->private_data),
+ prepare, substream);
return 0;
}
@@ -212,7 +209,8 @@ static int pcm_trigger(struct snd_pcm_substream *substream, int cmd)
}
// Do additional Audio Path 'trigger' callback
- DO_AUDIOPATH_CB(trigger, substream, cmd);
+ DO_AUDIOPATH_CB(((struct avirt_audiopath *)substream->private_data),
+ trigger, substream, cmd);
return 0;
}
@@ -230,7 +228,8 @@ static int pcm_trigger(struct snd_pcm_substream *substream, int cmd)
static snd_pcm_uframes_t pcm_pointer(struct snd_pcm_substream *substream)
{
// Do additional Audio Path 'pointer' callback
- DO_AUDIOPATH_CB(pointer, substream);
+ DO_AUDIOPATH_CB(((struct avirt_audiopath *)substream->private_data),
+ pointer, substream);
return 0;
}
@@ -258,7 +257,8 @@ static int pcm_get_time_info(
group = avirt_alsa_get_group(substream->stream);
CHK_NULL(group);
- DO_AUDIOPATH_CB(get_time_info, substream, system_ts, audio_ts,
+ DO_AUDIOPATH_CB(((struct avirt_audiopath *)substream->private_data),
+ get_time_info, substream, system_ts, audio_ts,
audio_tstamp_config, audio_tstamp_report);
return 0;
@@ -288,8 +288,8 @@ static int pcm_copy_user(struct snd_pcm_substream *substream, int channel,
//offset = frames_to_bytes(runtime, pos);
// Do additional Audio Path 'copy_user' callback
- DINFO(AP_LOGNAME, "");
- DO_AUDIOPATH_CB(copy_user, substream, channel, pos, src, count);
+ DO_AUDIOPATH_CB(((struct avirt_audiopath *)substream->private_data),
+ copy_user, substream, channel, pos, src, count);
return 0;
}
@@ -310,8 +310,9 @@ static int pcm_copy_user(struct snd_pcm_substream *substream, int channel,
static int pcm_copy_kernel(struct snd_pcm_substream *substream, int channel,
unsigned long pos, void *buf, unsigned long count)
{
- DINFO(AP_LOGNAME, "");
- DO_AUDIOPATH_CB(copy_kernel, substream, channel, pos, buf, count);
+ DO_AUDIOPATH_CB(((struct avirt_audiopath *)substream->private_data),
+ copy_kernel, substream, channel, pos, buf, count);
+
return 0;
}
@@ -326,16 +327,18 @@ static int pcm_copy_kernel(struct snd_pcm_substream *substream, int channel,
*/
int pcm_ack(struct snd_pcm_substream *substream)
{
- DINFO(AP_LOGNAME, "");
- DO_AUDIOPATH_CB(ack, substream);
+ DO_AUDIOPATH_CB(((struct avirt_audiopath *)substream->private_data),
+ ack, substream);
+
return 0;
}
static int pcm_silence(struct snd_pcm_substream *substream, int channel,
snd_pcm_uframes_t pos, snd_pcm_uframes_t count)
{
- DINFO(AP_LOGNAME, "");
- DO_AUDIOPATH_CB(fill_silence, substream, channel, pos, count);
+ DO_AUDIOPATH_CB(((struct avirt_audiopath *)substream->private_data),
+ fill_silence, substream, channel, pos, count);
+
return 0;
}
diff --git a/alsa.c b/alsa.c
index a899bb1..fdbe6b0 100755
--- a/alsa.c
+++ b/alsa.c
@@ -7,7 +7,6 @@
* Copyright (C) 2010-2018 Fiberdyne Systems Pty Ltd
*/
-#include <linux/slab.h>
#include <sound/core.h>
#include <sound/initval.h>
diff --git a/alsa.h b/alsa.h
index 12148b9..c22a93c 100755
--- a/alsa.h
+++ b/alsa.h
@@ -13,10 +13,11 @@
#include "core.h"
#include <linux/platform_device.h>
+#include <linux/slab.h>
#include <sound/pcm.h>
-#define PRINT_ERR(errno, errmsg, ...) \
- pr_err("[%s()] %s [ERRNO:%d]", __func__, errmsg, ##__VA_ARGS__, errno);
+#define PRINT_ERR(errno, errmsg) \
+ pr_err("[%s]:[ERRNO:%d]: %s ", __func__, errno, (errmsg));
#define CHK_ERR(errno) \
do { \
@@ -38,12 +39,15 @@
return -EFAULT; \
} while (0)
-#define CHK_NULL_V(x, errmsg, ...) \
- do { \
- if (!(x)) { \
- PRINT_ERR(EFAULT, (errmsg), ##__VA_ARGS__) \
- return -EFAULT; \
- } \
+#define CHK_NULL_V(x, errmsg, ...) \
+ do { \
+ if (!(x)) { \
+ char *errmsg_done = \
+ kasprintf(GFP_KERNEL, errmsg, ##__VA_ARGS__); \
+ PRINT_ERR(EFAULT, errmsg_done); \
+ kfree(errmsg_done); \
+ return -EFAULT; \
+ } \
} while (0)
extern struct avirt_coreinfo coreinfo;
diff --git a/core.c b/core.c
index e77dfb9..360f174 100644
--- a/core.c
+++ b/core.c
@@ -8,7 +8,6 @@
*/
#include <linux/module.h>
-#include <linux/slab.h>
#include <linux/platform_device.h>
#include "avirt/core.h"
@@ -279,13 +278,13 @@ static struct kobj_type avirt_audiopath_ktype = {
/**
* create_avirt_audiopath_obj - creates an Audio Path object
- * @name: name of the Audio Path
+ * @uid: Unique ID of the Audio Path
*
* This creates an Audio Path object and assigns the kset and registers
* it with sysfs.
* @return: Pointer to the Audio Path object or NULL if it failed.
*/
-static struct avirt_audiopath_obj *create_avirt_audiopath_obj(const char *name)
+static struct avirt_audiopath_obj *create_avirt_audiopath_obj(const char *uid)
{
struct avirt_audiopath_obj *avirt_audiopath;
int retval;
@@ -295,7 +294,7 @@ static struct avirt_audiopath_obj *create_avirt_audiopath_obj(const char *name)
return NULL;
avirt_audiopath->kobj.kset = avirt_audiopath_kset;
retval = kobject_init_and_add(&avirt_audiopath->kobj,
- &avirt_audiopath_ktype, kobj, "%s", name);
+ &avirt_audiopath_ktype, kobj, "%s", uid);
if (retval) {
kobject_put(&avirt_audiopath->kobj);
return NULL;
@@ -314,14 +313,20 @@ static void destroy_avirt_audiopath_obj(struct avirt_audiopath_obj *p)
}
/**
- * avirt_get_current_audiopath - retrieves the current Audio Path
- * @return: Current Audio Path
+ * avirt_get_audiopath - retrieves the Audio Path by its UID
+ * @uid: Unique ID for the Audio Path
+ * @return: Corresponding Audio Path
*/
-struct avirt_audiopath *avirt_get_current_audiopath(void)
+struct avirt_audiopath *avirt_get_audiopath(const char *uid)
{
- struct avirt_audiopath_obj *ap_obj = list_entry(
- audiopath_list.next, struct avirt_audiopath_obj, list);
- return ap_obj->path;
+ struct avirt_audiopath_obj *ap_obj;
+ list_for_each_entry (ap_obj, &audiopath_list, list) {
+ pr_info("get_ap %s\n", ap_obj->path->uid);
+ if (!strcmp(ap_obj->path->uid, uid))
+ return ap_obj->path;
+ }
+
+ return NULL;
}
/**
@@ -340,7 +345,7 @@ int avirt_register_audiopath(struct avirt_audiopath *audiopath,
return -EINVAL;
}
- audiopath_obj = create_avirt_audiopath_obj(audiopath->name);
+ audiopath_obj = create_avirt_audiopath_obj(audiopath->uid);
if (!audiopath_obj) {
pr_info("failed to alloc driver object\n");
return -ENOMEM;
@@ -348,8 +353,8 @@ int avirt_register_audiopath(struct avirt_audiopath *audiopath,
audiopath_obj->path = audiopath;
audiopath->context = audiopath_obj;
- D_INFOK("Registered new Audio Path: %s", audiopath->name);
- D_INFOK("\tBlocksize: %d, Periods: %d", audiopath->blocksize,
+ pr_info("Registered new Audio Path: %s\n", audiopath->uid);
+ pr_info("\tBlocksize: %d, Periods: %d\n", audiopath->blocksize,
audiopath->hw->periods_max);
list_add_tail(&audiopath_obj->list, &audiopath_list);
@@ -382,7 +387,7 @@ int avirt_deregister_audiopath(struct avirt_audiopath *audiopath)
list_del(&audiopath_obj->list);
destroy_avirt_audiopath_obj(audiopath_obj);
- pr_info("Deregistered Audio Path %s\n", audiopath->name);
+ pr_info("Deregistered Audio Path %s\n", audiopath->uid);
return 0;
}
diff --git a/core.h b/core.h
index fb64030..98d1bbd 100644
--- a/core.h
+++ b/core.h
@@ -26,11 +26,12 @@ typedef int (*avirt_buff_complete)(struct snd_pcm_substream *substream);
* AVIRT Audio Path info
*/
struct avirt_audiopath {
- const char *name;
- unsigned int version[3];
- struct snd_pcm_hardware *hw;
- struct snd_pcm_ops *pcm_ops;
- unsigned int blocksize;
+ const char *uid; /* Unique identifier */
+ const char *name; /* Pretty name */
+ unsigned int version[3]; /* Version - Major.Minor.Ext */
+ struct snd_pcm_hardware *hw; /* ALSA PCM HW conf */
+ struct snd_pcm_ops *pcm_ops; /* ALSA PCM op table */
+ unsigned int blocksize; /* Audio frame size accepted */
void *context;
};
@@ -80,9 +81,19 @@ int avirt_register_audiopath(struct avirt_audiopath *audiopath,
int avirt_deregister_audiopath(struct avirt_audiopath *audiopath);
/**
- * avirt_get_current_audiopath - retrieves the current Audio Path
- * @return: Current Audio Path
+ * avirt_get_audiopath - retrieves the Audio Path by it's UID
+ * @uid: Unique ID for the Audio Path
+ * @return: Corresponding Audio Path
+ */
+struct avirt_audiopath *avirt_get_audiopath(const char *uid);
+
+/**
+ * avirt_subscribe_stream - subscribe the Audio Path to the given streams
+ * @audiopath: Audio Path to subscribe for
+ * @streams: The streams to subscribe the Audio Path to
+ * return: 0 on success or error code otherwise
*/
-struct avirt_audiopath *avirt_get_current_audiopath(void);
+int avirt_subscribe_stream(struct avirt_audiopath *audiopath,
+ const char **streams);
#endif // __AVIRT_CORE_H__
diff --git a/dummy/dummy.c b/dummy/dummy.c
index 54d4dcc..fa9dd41 100644
--- a/dummy/dummy.c
+++ b/dummy/dummy.c
@@ -244,6 +244,7 @@ static struct snd_pcm_hardware dummyap_hw = {
};
static struct avirt_audiopath dummyap_module = {
+ .uid = "ap_dummy",
.name = "Dummy Audio Path",
.version = { 0, 0, 1 },
.hw = &dummyap_hw,