forked from thesofproject/sof
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathcommon.h
More file actions
316 lines (260 loc) · 6.72 KB
/
common.h
File metadata and controls
316 lines (260 loc) · 6.72 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
/* SPDX-License-Identifier: BSD-3-Clause
*
* Copyright(c) 2022-2023 Intel Corporation. All rights reserved.
*
* Author: Liam Girdwood <liam.r.girdwood@linux.intel.com>
*/
#ifndef __SOF_PLUGIN_COMMON_H__
#define __SOF_PLUGIN_COMMON_H__
#include <stdint.h>
#include <mqueue.h>
#include <semaphore.h>
#include <alsa/asoundlib.h>
/* 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 <alsa/sound/uapi/asoc.h>
#define IPC3_MAX_MSG_SIZE 384
#define NAME_SIZE 256
#define MAX_CTLS 256
#define MS_TO_US(_msus) (_msus * 1000)
#define MS_TO_NS(_msns) (MS_TO_US(_msns * 1000))
#define MS_TO_US(_msus) (_msus * 1000)
#define MS_TO_NS(_msns) (MS_TO_US(_msns * 1000))
#define SEM_PERMS (S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP)
#define SHM_SIZE (4096 * 64) /* get from topology - and set for context */
#define NUM_EP_CONFIGS 8
/*
* Run with valgrind
* valgrind --trace-children=yes aplay -v -Dsof:blah.tplg,1,hw:1,2 -f dat /dev/zero
*/
//#define VALGRIND
#ifdef VALGRIND
#define DEBUG_TV_SECS 10
#define DEBUG_RETRIES 1000
#else
#define DEBUG_RETRIES 10
#define DEBUG_TV_SECS 0
#endif
#define SOF_MAGIC "sofpipe"
enum plugin_state {
SOF_PLUGIN_STATE_INIT = 0,
SOF_PLUGIN_STATE_READY = 1,
SOF_PLUGIN_STATE_DEAD = 2,
SOF_PLUGIN_STATE_STREAM_RUNNING = 3,
SOF_PLUGIN_STATE_STREAM_ERROR = 5,
};
struct plug_shm_ctl {
unsigned int comp_id;
unsigned int type;
union {
struct snd_soc_tplg_mixer_control mixer_ctl;
struct snd_soc_tplg_enum_control enum_ctl;
struct snd_soc_tplg_bytes_control bytes_ctl;
};
};
/*
* config.48k2c {
* rate 48000
* channels 2
* period_time 0
* period_frames 6000
* buffer_time 0
* buffer_frames 24000
* }
*/
struct plug_config {
char name[44];
unsigned long buffer_frames;
unsigned long buffer_time;
unsigned long period_frames;
unsigned long period_time;
int rate;
int channels;
unsigned long format;
};
/*
* :[pcm:card:dev:config[pcm:card:dev:config]...]
*/
struct plug_cmdline_item {
int pcm;
char card_name[44];
char dev_name[44];
char config_name[44];
};
/*
* Endpoint pipeline configuration
*/
struct endpoint_hw_config {
int pipeline;
char card_name[44];
char dev_name[44];
char config_name[44];
unsigned long buffer_frames;
unsigned long buffer_time;
unsigned long period_frames;
unsigned long period_time;
int rate;
int channels;
unsigned long format;
};
struct plug_shm_endpoint {
char magic[8]; /* SOF_MAGIC */
uint64_t state;
uint32_t pipeline_id;
uint32_t comp_id;
uint32_t idx;
unsigned long rpos; /* current position in ring buffer */
unsigned long rwrap;
unsigned long wpos; /* current position in ring buffer */
unsigned long wwrap;
unsigned long buffer_size; /* buffer size */
unsigned long wtotal; /* total frames copied */
unsigned long rtotal; /* total frames copied */
int frame_size;
char data[0]; // TODO: align this on SIMD/cache
};
struct plug_shm_glb_state {
char magic[8]; /* SOF_MAGIC */
uint64_t size; /* size of this structure in bytes */
uint64_t state; /* enum plugin_state */
struct endpoint_hw_config ep_config[NUM_EP_CONFIGS];
int num_ep_configs;
uint64_t num_ctls; /* number of ctls */
struct plug_shm_ctl ctl[];
};
struct plug_shm_desc {
/* SHM for stream context sync */
int fd;
int size;
char name[NAME_SIZE];
void *addr;
};
struct plug_mq_desc {
/* IPC message queue */
mqd_t mq;
struct mq_attr attr;
char queue_name[NAME_SIZE];
};
struct plug_sem_desc {
char name[NAME_SIZE];
sem_t *sem;
};
struct plug_ctl_container {
struct snd_soc_tplg_ctl_hdr *tplg[MAX_CTLS];
int updated[MAX_CTLS];
int count;
};
static inline void *plug_ep_rptr(struct plug_shm_endpoint *ep)
{
return ep->data + ep->rpos;
}
static inline void *plug_ep_wptr(struct plug_shm_endpoint *ep)
{
return ep->data + ep->wpos;
}
static inline int plug_ep_wrap_rsize(struct plug_shm_endpoint *ep)
{
return ep->buffer_size - ep->rpos;
}
static inline int plug_ep_wrap_wsize(struct plug_shm_endpoint *ep)
{
return ep->buffer_size - ep->wpos;
}
static inline int plug_ep_get_free(struct plug_shm_endpoint *ep)
{
if (ep->rwrap == ep->wwrap) {
/* calculate available bytes */
if (ep->rpos < ep->wpos)
return ep->buffer_size - (ep->wpos - ep->rpos);
else
return ep->buffer_size;
} else {
return ep->rpos - ep->wpos;
}
}
static inline int plug_ep_get_avail(struct plug_shm_endpoint *ep)
{
if (ep->rwrap == ep->wwrap) {
/* calculate available bytes */
if (ep->rpos < ep->wpos)
return ep->wpos - ep->rpos;
else
return 0;
} else {
return (ep->buffer_size - ep->rpos) + ep->wpos;
}
}
static inline void *plug_ep_consume(struct plug_shm_endpoint *ep, unsigned int bytes)
{
ep->rtotal += bytes;
ep->rpos += bytes;
if (ep->rpos >= ep->buffer_size) {
ep->rpos -= ep->buffer_size;
ep->rwrap++;
}
return ep->data + ep->rpos;
}
static inline void *plug_ep_produce(struct plug_shm_endpoint *ep, unsigned int bytes)
{
ep->wtotal += bytes;
ep->wpos += bytes;
if (ep->wpos >= ep->buffer_size) {
ep->wpos -= ep->buffer_size;
ep->wwrap++;
}
return ep->data + ep->wpos;
}
/*
* SHM
*/
int plug_shm_init(struct plug_shm_desc *shm, const char *tplg, const char *type, int index);
int plug_shm_create(struct plug_shm_desc *shm);
int plug_shm_open(struct plug_shm_desc *shm);
void plug_shm_free(struct plug_shm_desc *shm);
/*
* IPC
*/
int plug_mq_create(struct plug_mq_desc *ipc);
int plug_mq_open(struct plug_mq_desc *ipc);
int plug_mq_init(struct plug_mq_desc *ipc, const char *tplg, const char *type, int index);
void plug_mq_free(struct plug_mq_desc *ipc);
int plug_mq_cmd(struct plug_mq_desc *ipc, void *msg, size_t len, void *reply, size_t rlen);
int plug_mq_cmd_tx_rx(struct plug_mq_desc *ipc_tx, struct plug_mq_desc *ipc_rx,
void *msg, size_t len, void *reply, size_t rlen);
/*
* Locking
*/
int plug_lock_create(struct plug_sem_desc *lock);
void plug_lock_free(struct plug_sem_desc *lock);
int plug_lock_init(struct plug_sem_desc *lock, const char *tplg, const char *type, int index);
int plug_lock_open(struct plug_sem_desc *lock);
/*
* Timing.
*/
void plug_timespec_add_ms(struct timespec *ts, unsigned long ms);
long plug_timespec_delta_ns(struct timespec *before, struct timespec *after);
/* dump the IPC data - dont print lines of 0s */
static inline void data_dump(void *vdata, size_t bytes)
{
uint32_t *data = vdata;
size_t words = bytes >> 2;
int i;
for (i = 0; i < words; i++) {
/* 4 words per line */
if (i % 4 == 0) {
/* delete lines with all 0s */
if (i > 0 && data[i - 3] == 0 && data[i - 2] == 0 &&
data[i - 1] == 0 && data[i - 0] == 0)
printf("\r");
else
printf("\n");
printf("0x%4.4x: 0x%8.8x", i, data[i]);
} else {
printf(" 0x%8.8x", data[i]);
}
}
printf("\n");
}
#endif