summaryrefslogtreecommitdiffstats
path: root/sound
diff options
context:
space:
mode:
authorMark Farrugia <mark.farrugia@fiberdyne.com.au>2019-03-27 17:47:26 +1100
committerMark Farrugia <mark.farrugia@fiberdyne.com.au>2019-03-27 17:49:12 +1100
commitc22d65351d533a2077caae117e3baf5558d20963 (patch)
treee61b7162bbbe6939eeb1afddaf53001aba683dab /sound
parent07068446e60502bbd4b7b3a5df16a6246183e1ed (diff)
Rework routing system
- Add 'route' to snd_avirt_stream, remove from audio path - Add route checking - ensure that source ap and ink ap have compatible hw params - Add private data support for both source and sink Audio Paths, to ensure that the PCM can hold multiple private data(s). - Add ability to use copy_kernel and exttriggers from AVIRT instead of from Audio Paths - Reintroduce pcm_trigger and pcm_prepare, so that they may be called appropriately from AVIRT, rather than child Audio Paths. Signed-off-by: Mark Farrugia <mark.farrugia@fiberdyne.com.au>
Diffstat (limited to 'sound')
-rw-r--r--sound/avirt.h96
1 files changed, 77 insertions, 19 deletions
diff --git a/sound/avirt.h b/sound/avirt.h
index 8378004..ecb0a21 100644
--- a/sound/avirt.h
+++ b/sound/avirt.h
@@ -39,6 +39,34 @@ typedef int (*snd_avirt_audiopath_configure)(
typedef void (*snd_avirt_pcm_exttrigger)(void);
/**
+ * ALSA copy_kernel function type
+ * A standard PCM operation from ALSA. This is used in AVIRT to copy PCM data
+ * between Audio Paths, along given routes.
+ */
+typedef int (*snd_pcm_copy_kernel)(struct snd_pcm_substream *substream,
+ int channel, unsigned long pos, void *buf,
+ unsigned long bytes);
+
+/*
+ * AVIRT route source/sink enumeration types
+ */
+typedef enum snd_avirt_route_endpoint_t {
+ SND_AVIRT_ROUTE_SOURCE,
+ SND_AVIRT_ROUTE_SINK,
+} snd_avirt_route_endpoint;
+
+/**
+ * Audio routing
+ */
+struct snd_avirt_route {
+ char uid[MAX_NAME_LEN]; /* Unique identifier */
+ unsigned int channels; /* Route stream channel count */
+ unsigned int direction; /* Route stream direction */
+ struct snd_avirt_audiopath *endpoint_ap[2]; /* Source/sink */
+ struct config_item item; /* configfs item reference */
+};
+
+/**
* AVIRT Audio Path info
*/
typedef struct snd_avirt_audiopath snd_avirt_audiopath;
@@ -50,24 +78,8 @@ struct snd_avirt_audiopath {
const struct snd_pcm_ops *pcm_playback_ops; /* ALSA PCM playback ops */
const struct snd_pcm_ops *pcm_capture_ops; /* ALSA PCM capture ops */
snd_avirt_audiopath_configure configure; /* Config callback function */
- snd_avirt_pcm_exttrigger pcm_exttrigger;
+ snd_avirt_pcm_exttrigger pcm_exttrigger; /* External trigger callback */
void *context;
-
- // MUST be at the end
- struct snd_avirt_audiopath *route_from_ap;
- struct snd_avirt_audiopath *route_to_ap;
-};
-
-/**
- * Audio routing
- */
-struct snd_avirt_route {
- char name[MAX_NAME_LEN];
- unsigned int channels;
- unsigned int direction;
- struct snd_avirt_audiopath *from_ap;
- struct snd_avirt_audiopath *to_ap;
- struct config_item item;
};
/**
@@ -81,6 +93,7 @@ struct snd_avirt_stream {
unsigned int direction; /* Stream direction */
struct snd_pcm *pcm; /* ALSA PCM */
struct snd_pcm_ops *pcm_ops; /* ALSA PCM ops */
+ struct snd_avirt_route *route; /* Associated route, if any */
struct config_item item; /* configfs item reference */
};
@@ -101,9 +114,10 @@ typedef void (*snd_avirt_ap_private_free)(struct snd_pcm *pcm);
* Private Data Expansion
*/
struct snd_avirt_private_data {
+ /* Initial Audio Path in the route */
struct snd_avirt_audiopath *audiopath;
- void *ap_private_data;
-
+ /* Private data for source/sink Audio Paths */
+ void *ap_private_data[2];
snd_avirt_ap_private_free ap_private_free;
};
@@ -128,4 +142,48 @@ int snd_avirt_audiopath_deregister(struct snd_avirt_audiopath *audiopath);
*/
struct snd_avirt_audiopath *snd_avirt_audiopath_get(const char *uid);
+/*
+ * snd_avirt_audiopath_set_private_data - set PCM private data for an Audio Path
+ * @ap: The Audio Path whose private data to set.
+ * @pcm: The PCM where the private data is stored.
+ * @ap_private_data: The value to set to the private data.
+ * @return: 0 on success, -1 on failure.
+ */
+int snd_avirt_audiopath_set_private_data(struct snd_avirt_audiopath *ap,
+ struct snd_pcm *pcm,
+ void *ap_private_data);
+
+/*
+ * snd_avirt_audiopath_get_private_data - get PCM private data for an Audio Path
+ * @ap: The Audio Path whose private data to get.
+ * @pcm: The PCM where the private data is stored.
+ * @return: The value assigned to the private data.
+ */
+void *snd_avirt_audiopath_get_private_data(struct snd_avirt_audiopath *ap,
+ struct snd_pcm *pcm);
+
+/**
+ * snd_avirt_route_endpoint_copy - get endpoint copy function for a given
+ * Audio Path's source/sink.
+ * @ap: The Audio Path whose endpoint copy function to find.
+ * @endpoint: The endpoint (SND_AVIRT_ROUTE_SOURCE or SND_AVIRT_ROUTE_SINK).
+ * @return: A snd_pcm_copy_kernel function pointer that can be used to either:
+ * 1. Source PCM data into the Audio Path, or,
+ * 2. Sink PCM data out of the Audio Path.
+ * If no Audio Path endpoint is routed for 'endpoint', NULL is returned.
+ */
+snd_pcm_copy_kernel
+snd_avirt_route_endpoint_copy(struct snd_pcm_substream *substream,
+ snd_avirt_route_endpoint endpoint);
+
+/**
+ * snd_avirt_route_endpoint_trigger - Trigger an Audio Path's endpoint
+ * (sink/source).
+ * @uid: The Audio Path whose endpoint trigger function to call.
+ * @endpoint: The endpoint (SND_AVIRT_ROUTE_SOURCE or SND_AVIRT_ROUTE_SINK).
+ * @return: 0 on success or -1 on failure.
+ */
+int snd_avirt_route_endpoint_trigger(struct snd_pcm_substream *substream,
+ snd_avirt_route_endpoint endpoint);
+
#endif // __SOUND_AVIRT_H