1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
|
// SPDX-License-Identifier: GPL-2.0
/*
* AVIRT - ALSA Virtual Soundcard
*
* Copyright (c) 2010-2018 Fiberdyne Systems Pty Ltd
*
* avirt.h - AVIRT system-level header
*/
#ifndef __SOUND_AVIRT_H
#define __SOUND_AVIRT_H
#include <sound/core.h>
#include <sound/pcm.h>
#include <linux/configfs.h>
#define MAX_STREAMS 16
#define MAX_NAME_LEN 80
#define DINFO(logname, fmt, args...) \
snd_printk(KERN_INFO "AVIRT: %s: " fmt "\n", logname, ##args)
#define DERROR(logname, fmt, args...) \
snd_printk(KERN_ERR "AVIRT: %s: " fmt "\n", logname, ##args)
#define DDEBUG(logname, fmt, args...) \
snd_printk(KERN_DEBUG "AVIRT: %s: " fmt "\n", logname, ##args)
struct snd_avirt_stream_array; /* Forward declaration */
/**
* AVIRT Audio Path configure function type
* Each Audio Path registers this at snd_avirt_audiopath_register time.
* It is then called by the core once AVIRT has been configured
*/
typedef int (*snd_avirt_audiopath_configure)(
struct snd_card *card, struct snd_avirt_stream_array *stream_array);
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;
struct snd_avirt_audiopath {
const char *uid; /* Unique identifier */
const char *name; /* Pretty name */
unsigned int version[3]; /* Version - Major.Minor.Ext */
const struct snd_pcm_hardware *hw; /* ALSA PCM HW conf */
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; /* External trigger callback */
void *context;
};
/**
* Audio stream configuration
*/
struct snd_avirt_stream {
char name[MAX_NAME_LEN]; /* Stream name */
char map[MAX_NAME_LEN]; /* Stream Audio Path mapping */
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 snd_pcm_ops *pcm_ops; /* ALSA PCM ops */
struct snd_avirt_route *route; /* Associated route, if any */
struct config_item item; /* configfs item reference */
};
/**
* Audio stream group
*/
struct snd_avirt_stream_array {
struct snd_avirt_stream *streams[MAX_STREAMS];
int count;
};
/**
* snd_avirt_private_free - free Audio Path private data from function prototype
* @pcm: The PCM object
*/
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;
/* Private data for source/sink Audio Paths */
void *ap_private_data[2];
snd_avirt_ap_private_free ap_private_free;
};
/**
* snd_avirt_audiopath_register - register Audio Path with AVIRT
* @audiopath: Audio Path to be registered
* @return: 0 on success or error code otherwise
*/
int snd_avirt_audiopath_register(struct snd_avirt_audiopath *audiopath);
/**
* snd_avirt_audiopath_deregister - deregister Audio Path with AVIRT
* @audiopath: Audio Path to be deregistered
* @return: 0 on success or error code otherwise
*/
int snd_avirt_audiopath_deregister(struct snd_avirt_audiopath *audiopath);
/**
* snd_avirt_audiopath_get - get Audio Path by it's UID
* @uid: The Audio Path UID to get
* @return: The Audio Path if it exists, NULL otherwise.
*/
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
|