From c22d65351d533a2077caae117e3baf5558d20963 Mon Sep 17 00:00:00 2001 From: Mark Farrugia Date: Wed, 27 Mar 2019 17:47:26 +1100 Subject: 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 --- sound/avirt.h | 96 +++++++++++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 77 insertions(+), 19 deletions(-) (limited to 'sound') diff --git a/sound/avirt.h b/sound/avirt.h index 8378004..ecb0a21 100644 --- a/sound/avirt.h +++ b/sound/avirt.h @@ -38,6 +38,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 */ @@ -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 -- cgit 1.2.3-korg