-
Notifications
You must be signed in to change notification settings - Fork 364
Expand file tree
/
Copy pathtopology.h
More file actions
360 lines (299 loc) · 10.8 KB
/
Copy pathtopology.h
File metadata and controls
360 lines (299 loc) · 10.8 KB
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
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
/*
* SPDX-License-Identifier: BSD-3-Clause
*
* Copyright(c) 2019 Intel Corporation. All rights reserved.
*
* Author: Liam Girdwood <liam.r.girdwood@linux.intel.com>
* Ranjani Sridharan <ranjani.sridharan@linux.intel.com>
*/
#ifndef _COMMON_TPLG_H
#define _COMMON_TPLG_H
#include <stdbool.h>
#include <stdarg.h>
#include <stddef.h>
#include <assert.h>
#include <stdio.h>
#include <ipc/dai.h>
#include <ipc/topology.h>
#include <ipc/stream.h>
#include <ipc4/module.h>
#include <kernel/tokens.h>
#include <sof/list.h>
#include <volume/peak_volume.h>
#include <src/src_ipc.h>
#include <asrc/asrc_ipc4.h>
#include "copier/copier.h"
#ifdef TPLG_DEBUG
#define DEBUG_MAX_LENGTH 256
static inline void tplg_debug(char *fmt, ...)
{
char msg[DEBUG_MAX_LENGTH];
va_list va;
va_start(va, fmt);
vsnprintf(msg, DEBUG_MAX_LENGTH, fmt, va);
va_end(va);
fprintf(stdout, "%s", msg);
}
#else
static inline void tplg_debug(char *fmt, ...) {}
#endif
/* temporary - current MAXLEN is not define in UAPI header - fix pending */
#ifndef SNDRV_CTL_ELEM_ID_NAME_MAXLEN
#define SNDRV_CTL_ELEM_ID_NAME_MAXLEN 44
#endif
#include <linux/types.h>
#include <alsa/sound/asoc.h>
#define TPLG_PARSER_SOF_DEV 1
#define TPLG_PARSER_FUZZER_DEV 2
#define TPLG_MAX_PCM_PIPELINES 16
#define MOVE_POINTER_BY_BYTES(p, b) ((typeof(p))((uint8_t *)(p) + (b)))
struct testbench_prm;
struct snd_soc_tplg_vendor_array;
struct snd_soc_tplg_ctl_hdr;
struct sof_topology_token;
struct sof;
struct fuzz;
struct sof_topology_module_desc;
struct sof_ipc4_audio_format {
uint32_t sampling_frequency;
uint32_t bit_depth;
uint32_t ch_map;
uint32_t ch_cfg; /* sof_ipc4_channel_config */
uint32_t interleaving_style;
uint32_t fmt_cfg; /* channels_count valid_bit_depth s_type */
} __packed __aligned(4);
/**
* struct sof_ipc4_pin_format - Module pin format
* @pin_index: pin index
* @buffer_size: buffer size in bytes
* @audio_fmt: audio format for the pin
*
* This structure can be used for both output or input pins and the pin_index is relative to the
* pin type i.e output/input pin
*/
struct sof_ipc4_pin_format {
uint32_t pin_index;
uint32_t buffer_size;
struct sof_ipc4_audio_format audio_fmt;
};
/**
* struct sof_ipc4_available_audio_format - Available audio formats
* @output_pin_fmts: Available output pin formats
* @input_pin_fmts: Available input pin formats
* @num_input_formats: Number of input pin formats
* @num_output_formats: Number of output pin formats
*/
struct sof_ipc4_available_audio_format {
struct sof_ipc4_pin_format *output_pin_fmts;
struct sof_ipc4_pin_format *input_pin_fmts;
uint32_t num_input_formats;
uint32_t num_output_formats;
};
struct tplg_pipeline_info {
int id;
int instance_id;
int usage_count;
int mem_usage;
char *name;
struct list_item item; /* item in a list */
};
struct tplg_pins_info {
uint32_t num_input_pins;
uint32_t num_output_pins;
};
struct tplg_comp_info {
struct list_item item; /* item in a list */
struct sof_ipc4_available_audio_format available_fmt; /* available formats in tplg */
struct ipc4_module_init_instance module_init;
struct ipc4_base_module_cfg basecfg;
struct tplg_pipeline_info *pipe_info;
struct sof_uuid uuid;
struct tplg_pins_info pins_info;
char *name;
char *stream_name;
int id;
int type;
int pipeline_id;
void *ipc_payload;
int ipc_size;
int instance_id;
int module_id;
};
struct tplg_route_info {
struct tplg_comp_info *source;
struct tplg_comp_info *sink;
struct list_item item; /* item in a list */
};
struct tplg_pipeline_list {
int count;
struct tplg_pipeline_info *pipelines[TPLG_MAX_PCM_PIPELINES];
};
struct tplg_pcm_info {
char *name;
int id;
struct tplg_comp_info *playback_host;
struct tplg_comp_info *capture_host;
struct list_item item; /* item in a list */
struct tplg_pipeline_list playback_pipeline_list;
struct tplg_pipeline_list capture_pipeline_list;
};
/*
* Per topology data.
*
* TODO: Some refactoring still required to move pipeline specific data.
*/
struct tplg_context {
/* pipeline and core IDs we are processing */
int pipeline_id;
int core_id;
/* current IPC object and widget */
struct snd_soc_tplg_hdr *hdr;
struct snd_soc_tplg_dapm_widget *widget;
struct tplg_comp_info *current_comp_info;
int comp_id;
size_t widget_size;
int dev_type;
int sched_id;
int dir;
/* global data */
void *tplg_base;
size_t tplg_size;
long tplg_offset;
struct sof *sof;
const char *tplg_file;
struct fuzz *fuzzer;
int ipc_major;
/* kcontrol creation */
void *ctl_arg;
int (*ctl_cb)(struct snd_soc_tplg_ctl_hdr *tplg_ctl,
void *comp, void *arg, int index);
};
#define tplg_get(ctx) ((void *)(ctx->tplg_base + ctx->tplg_offset))
#define tplg_check_bounds(ctx, advance) \
do { \
if ((long)(advance) < 0 || \
(ctx)->tplg_offset + (long)(advance) > (long)(ctx)->tplg_size) { \
printf("%s %d topology offset %ld + %ld > size %zu\n", \
__func__, __LINE__, (ctx)->tplg_offset, \
(long)(advance), (ctx)->tplg_size); \
exit(1); \
} \
} while (0)
#define tplg_get_hdr(ctx) \
({struct snd_soc_tplg_hdr *ptr; \
tplg_check_bounds(ctx, sizeof(*ptr)); \
ptr = (struct snd_soc_tplg_hdr *)((ctx)->tplg_base + (ctx)->tplg_offset); \
if (ptr->size != sizeof(*ptr)) { \
printf("%s %d hdr size mismatch 0x%x:0x%zx at offset %ld\n", \
__func__, __LINE__, ptr->size, sizeof(*ptr), \
(ctx)->tplg_offset); assert(0); \
} \
ctx->tplg_offset += sizeof(*ptr); (void *)ptr; })
#define tplg_skip_hdr_payload(ctx) \
({struct snd_soc_tplg_hdr *ptr; \
tplg_check_bounds(ctx, hdr->payload_size); \
ptr = (struct snd_soc_tplg_hdr *)((ctx)->tplg_base + (ctx)->tplg_offset); \
(ctx)->tplg_offset += hdr->payload_size; (void *)ptr; })
#define tplg_get_object(ctx, obj) \
({void *ptr; \
tplg_check_bounds(ctx, sizeof(*(obj))); \
ptr = (ctx)->tplg_base + (ctx)->tplg_offset; \
(ctx)->tplg_offset += sizeof(*(obj)); ptr; })
#define tplg_get_object_priv(ctx, obj, priv_size) \
({void *ptr; \
tplg_check_bounds(ctx, sizeof(*(obj)) + (priv_size)); \
ptr = (ctx)->tplg_base + (ctx)->tplg_offset; \
(ctx)->tplg_offset += sizeof(*(obj)) + (priv_size); ptr; })
#define tplg_get_widget(ctx) \
({struct snd_soc_tplg_dapm_widget *w; \
tplg_check_bounds(ctx, sizeof(*w)); \
w = (struct snd_soc_tplg_dapm_widget *)((ctx)->tplg_base + (ctx)->tplg_offset); \
tplg_check_bounds(ctx, sizeof(*w) + w->priv.size); \
(ctx)->tplg_offset += sizeof(*w) + w->priv.size; w; })
#define tplg_get_graph(ctx) \
({struct snd_soc_tplg_dapm_graph_elem *w; \
tplg_check_bounds(ctx, sizeof(*w)); \
w = (struct snd_soc_tplg_dapm_graph_elem *)((ctx)->tplg_base + (ctx)->tplg_offset); \
(ctx)->tplg_offset += sizeof(*w); w; })
#define tplg_get_pcm(ctx) \
({struct snd_soc_tplg_pcm *pcm; \
tplg_check_bounds(ctx, sizeof(*pcm)); \
pcm = (struct snd_soc_tplg_pcm *)((ctx)->tplg_base + (ctx)->tplg_offset); \
tplg_check_bounds(ctx, sizeof(*pcm) + pcm->priv.size); \
(ctx)->tplg_offset += sizeof(*pcm) + pcm->priv.size; pcm; })
static inline int tplg_valid_widget(struct snd_soc_tplg_dapm_widget *widget)
{
if (widget->size == sizeof(struct snd_soc_tplg_dapm_widget))
return 1;
else
return 0;
}
enum sof_ipc_frame tplg_find_format(const char *name);
int tplg_token_get_uint32_t(void *elem, void *object, uint32_t offset,
uint32_t size);
int tplg_token_get_comp_format(void *elem, void *object, uint32_t offset,
uint32_t size);
int tplg_token_get_uuid(void *elem, void *object, uint32_t offset, uint32_t size);
int sof_parse_tokens(void *object,
const struct sof_topology_token *tokens,
int count, struct snd_soc_tplg_vendor_array *array,
int priv_size);
int sof_parse_string_tokens(void *object,
const struct sof_topology_token *tokens,
int count,
struct snd_soc_tplg_vendor_array *array);
int sof_parse_uuid_tokens(void *object,
const struct sof_topology_token *tokens,
int count,
struct snd_soc_tplg_vendor_array *array);
int sof_parse_word_tokens(void *object,
const struct sof_topology_token *tokens,
int count,
struct snd_soc_tplg_vendor_array *array);
int tplg_read_array(struct snd_soc_tplg_vendor_array *array);
int tplg_new_buffer(struct tplg_context *ctx, void *buffer, size_t buffer_size,
struct snd_soc_tplg_ctl_hdr *rctl, size_t buffer_ctl_size);
int tplg_create_dai(struct tplg_context *ctx,
struct sof_ipc_comp_dai *comp_dai);
int tplg_create_pipeline(struct tplg_context *ctx,
struct sof_ipc_pipe_new *pipeline);
int tplg_get_single_control(struct tplg_context *ctx,
struct snd_soc_tplg_ctl_hdr **ctl,
struct snd_soc_tplg_private **priv);
int tplg_create_controls(struct tplg_context *ctx, int num_kcontrols,
struct snd_soc_tplg_ctl_hdr *rctl,
size_t max_ctl_size, void *object);
int tplg_new_pcm(struct tplg_context *ctx, void *host, size_t host_size);
int tplg_new_pipeline(struct tplg_context *ctx, void *pipeline,
size_t pipeline_size, struct snd_soc_tplg_ctl_hdr *rctl);
int tplg_new_mixer(struct tplg_context *ctx, void *mixer, size_t mixer_size,
struct snd_soc_tplg_ctl_hdr *rctl, size_t max_ctl_size);
int tplg_new_src(struct tplg_context *ctx, void *src, size_t src_size,
struct snd_soc_tplg_ctl_hdr *rctl, size_t ctl_size);
int tplg_new_asrc(struct tplg_context *ctx, void *asrc, size_t asrc_size,
struct snd_soc_tplg_ctl_hdr *rctl, size_t ctl_size);
int tplg_new_pga(struct tplg_context *ctx, void *pga, size_t pga_size,
struct snd_soc_tplg_ctl_hdr *rctl, size_t ctl_size);
int tplg_new_dai(struct tplg_context *ctx, void *dai, size_t dai_size,
struct snd_soc_tplg_ctl_hdr *rctl, size_t max_ctl_size);
int tplg_new_process(struct tplg_context *ctx, void *process, size_t process_size,
struct snd_soc_tplg_ctl_hdr *rctl, size_t max_ctl_size);
int tplg_create_graph(struct tplg_context *ctx, int count, int pipeline_id,
struct tplg_comp_info *temp_comp_list, char *pipeline_string,
size_t pipeline_string_size,
struct sof_ipc_pipe_comp_connect *connection,
int route_num);
bool tplg_is_valid_priv_size(size_t size_read, size_t priv_size,
struct snd_soc_tplg_vendor_array *array);
int tplg_create_object(struct tplg_context *ctx,
const struct sof_topology_module_desc *desc, int num_desc,
const char *name, void *object, size_t max_object_size);
int sof_parse_token_sets(void *object, const struct sof_topology_token *tokens,
int count, struct snd_soc_tplg_vendor_array *array,
int priv_size, int num_sets, int object_size);
int tplg_parse_widget_audio_formats(struct tplg_context *ctx);
int tplg_parse_graph(struct tplg_context *ctx, struct list_item *widget_list,
struct list_item *route_list);
int tplg_parse_pcm(struct tplg_context *ctx, struct list_item *widget_list,
struct list_item *pcm_list);
#endif