blob: 6b5862df68fc26af13293c6e8bc3edd6f2d6ece3 [file] [log] [blame]
Steve Muckle0a9c0872022-02-16 05:58:07 +00001/*******************************************************************************
2* Copyright (C) 2018 Cadence Design Systems, Inc.
3*
4* Permission is hereby granted, free of charge, to any person obtaining
5* a copy of this software and associated documentation files (the
6* "Software"), to use this Software with Cadence processor cores only and
7* not with any other processors and platforms, subject to
8* the following conditions:
9*
10* The above copyright notice and this permission notice shall be included
11* in all copies or substantial portions of the Software.
12*
13* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
14* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
15* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
16* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
17* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
18* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
19* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20
21******************************************************************************/
22#include "xf.h"
23#include "xaf-api.h"
24#include "xaf-structs.h"
25
26#ifdef XAF_HOSTLESS
27#include "xos-msgq-if.h"
28#endif
29#define MODULE_TAG DEVAPI
30
31/*******************************************************************************
32 * Tracing configuration
33 ******************************************************************************/
34
35TRACE_TAG(INIT, 1);
36TRACE_TAG(DEBUG, 1);
37TRACE_TAG(INFO, 1);
38
39#define XAF_4BYTE_ALIGN 4
40#define XAF_8BYTE_ALIGN 8
41#define XAF_32BYTE_ALIGN 32
42
43
44static void xaf_comp_response(xf_handle_t *h, xf_user_msg_t *msg)
45{
46 if (msg->opcode == XF_UNREGISTER)
47 {
48 /* ...component execution failed unexpectedly; die */
49 BUG(1, _x("[%p] Abnormal termination"), h);
50 }
51 else
52 {
53 /* ...submit response to asynchronous delivery queue */
54 xf_response_put(h, msg);
55 }
56}
57
58static XAF_ERR_CODE xaf_comp_add(xaf_comp_t **pp_comp_chain, xaf_comp_t *p_comp)
59{
60 XAF_CHK_PTR(pp_comp_chain);
61 XAF_CHK_PTR(p_comp);
62
63 p_comp->next = *pp_comp_chain;
64 *pp_comp_chain = p_comp;
65
66 return XAF_NO_ERROR;
67}
68
69static XAF_ERR_CODE xaf_comp_post_init_config(xaf_adev_t *p_adev, xaf_comp_t *p_comp, void *p_msg)
70{
71 xf_proxy_t *p_proxy = &p_adev->proxy;
72 xf_start_msg_t *smsg = p_msg;
73
74 p_comp->out_format.sample_rate = smsg->sample_rate;
75 p_comp->out_format.channels = smsg->channels;
76 p_comp->out_format.pcm_width = smsg->pcm_width;
77 p_comp->out_format.input_length = smsg->input_length;
78 p_comp->out_format.output_length = smsg->output_length;
79
80 TRACE(INFO, _b("Component[%x] Params: f=%d, c=%d, w=%d i=%d o=%d"), p_comp->handle.id, smsg->sample_rate, smsg->channels, smsg->pcm_width, smsg->input_length, smsg->output_length);
81
82 if (p_comp->noutbuf)
83 {
84 XF_CHK_API(xf_pool_alloc(p_proxy, p_comp->noutbuf, smsg->output_length, XF_POOL_OUTPUT, &p_comp->outpool, XAF_MEM_ID_COMP,
85 p_adev->pxf_mem_malloc_fxn, p_adev->pxf_mem_free_fxn));
86 }
87
88 p_comp->init_done = 1;
89 p_comp->comp_status = XAF_INIT_DONE;
90
91 return XAF_NO_ERROR;
92}
93
94#ifdef XAF_HOSTLESS
95XAF_ERR_CODE xaf_xos_start()
96{
97#if defined BOARD
98 xos_set_clock_freq(xtbsp_clock_freq_hz());
99#else
100 xos_set_clock_freq(XOS_CLOCK_FREQ);
101#endif
102
103 xos_start("main", 7, 0);
104#if XCHAL_NUM_TIMERS > 0
105 xos_start_system_timer(0, TICK_CYCLES);
106#endif
107
108 return XAF_NO_ERROR;
109}
110#endif
111
112XAF_ERR_CODE xaf_adev_open(void** pp_adev, s32 audio_frmwk_buf_size, s32 audio_comp_buf_size, xaf_mem_malloc_fxn_t mem_malloc, xaf_mem_free_fxn_t mem_free)
113{
114 int size;
115 void * pTmp;
116 xaf_adev_t *p_adev;
117 xf_proxy_t *p_proxy;
118
119 XAF_CHK_PTR(pp_adev);
120 XAF_CHK_PTR(mem_malloc);
121 XAF_CHK_PTR(mem_free);
122
123 /* ...unused arg */
124 (void) audio_comp_buf_size;
125
126 //Memory allocation for adev struct pointer
127 size = (sizeof(xaf_adev_t) +(XAF_4BYTE_ALIGN-1));
128 pTmp = mem_malloc(size, XAF_MEM_ID_DEV);
129 XAF_CHK_PTR(pTmp);
130 memset(pTmp, 0, size);
131
132 p_adev = (xaf_adev_t *) (((unsigned long)pTmp + (XAF_4BYTE_ALIGN-1))& ~(XAF_4BYTE_ALIGN-1));
133 p_adev->adev_ptr = pTmp;
134 *pp_adev = (void *)p_adev;
135
136 p_proxy = &p_adev->proxy;
137
138 // Host side Memory allocation (BSS)
139 p_adev->pxf_mem_malloc_fxn = mem_malloc;
140 p_adev->pxf_mem_free_fxn = mem_free;
141
142 size = sizeof(xaf_ap_utils_t)+(XAF_8BYTE_ALIGN-1);
143 p_adev->p_ap_utils = mem_malloc(size, XAF_MEM_ID_DEV);
144 XAF_CHK_PTR(p_adev->p_ap_utils);
145 //reset memory size stats
146 memset(p_adev->p_ap_utils, 0, sizeof(xaf_ap_utils_t));
147
148 // shmmem Memory allocation
149 p_adev->p_ap_utils->xf_cfg_remote_ipc_pool_size = audio_frmwk_buf_size; //minimum size 256 KB, mmap multiple is 0x1000
150
151 //DSP localbuf allocation is done in the DSP core; nothing to be done here
152
153 /* ...open DSP proxy - specify "DSP#0" */
154 XF_CHK_API(xf_proxy_init(p_proxy, 0, (void *)&p_adev->p_ap_utils->xf_cfg_remote_ipc_pool_size));
155
156 /* ...create auxiliary buffers pool for control commands */
157 XF_CHK_API(xf_pool_alloc(p_proxy, XAF_AUX_POOL_SIZE, XAF_AUX_POOL_MSG_LENGTH, XF_POOL_AUX, &p_proxy->aux, XAF_MEM_ID_DEV,
158 p_adev->pxf_mem_malloc_fxn, p_adev->pxf_mem_free_fxn));
159
160 return XAF_NO_ERROR;
161}
162
163XAF_ERR_CODE xaf_adev_close(void* adev_ptr, xaf_comp_flag flag)
164{
165 xaf_adev_t *p_adev;
166 xf_proxy_t *p_proxy;
167
168 XAF_CHK_PTR(adev_ptr);
169 p_adev = (xaf_adev_t *)adev_ptr;
170
171 /* ...unused arg */
172 (void) flag;
173
174 p_proxy = &p_adev->proxy;
175 if(p_proxy->aux != NULL)
176 {
177 xf_pool_free(p_proxy->aux, XAF_MEM_ID_DEV, p_adev->pxf_mem_free_fxn);
178 }
179
180 xf_proxy_close(p_proxy);
181
182 p_adev->pxf_mem_free_fxn(p_adev->p_ap_utils, XAF_MEM_ID_DEV);
183 p_adev->p_ap_utils = NULL;
184 p_adev->pxf_mem_free_fxn(p_adev->adev_ptr, XAF_MEM_ID_DEV);
185 p_adev->adev_ptr = NULL;
186
187 p_adev->pxf_mem_malloc_fxn = NULL;
188 p_adev->pxf_mem_free_fxn = NULL;
189
190 return XAF_NO_ERROR;
191}
192
193XAF_ERR_CODE xaf_comp_create(void *adev_ptr, void **pp_comp, xf_id_t comp_id, u32 ninbuf, u32 noutbuf, void *pp_inbuf[], xaf_comp_type comp_type)
194{
195 xf_handle_t *p_handle;
196 void * pTmp;
197 int size;
198
199 xaf_adev_t *p_adev;
200 p_adev = (xaf_adev_t *)adev_ptr;
201 xaf_comp_t *p_comp;
202
203 XAF_CHK_PTR(p_adev);
204 XAF_CHK_PTR(pp_comp);
205 XAF_CHK_PTR(comp_id);
206 if (ninbuf) XAF_CHK_PTR(pp_inbuf);
207
208 XAF_CHK_RANGE(ninbuf, 0, XAF_MAX_INBUFS);
209 XAF_CHK_RANGE(noutbuf, 0, 1);
210 XAF_CHK_RANGE(comp_type, XAF_DECODER, XAF_POST_PROC);
211
212 //Memory allocation for component struct pointer
213 size = (sizeof(xaf_comp_t) + (XAF_4BYTE_ALIGN-1));
214 pTmp = p_adev->pxf_mem_malloc_fxn(size, XAF_MEM_ID_COMP);
215 XAF_CHK_PTR(pTmp);
216 memset(pTmp, 0, size);
217 p_comp = (xaf_comp_t *) (((unsigned long)pTmp + (XAF_4BYTE_ALIGN-1))& ~(XAF_4BYTE_ALIGN-1));
218
219 p_comp->comp_ptr = pTmp;
220 *pp_comp = (void*)p_comp;
221
222 memset(p_comp, 0, sizeof(xaf_comp_t));
223 p_handle = &p_comp->handle;
224
225 /* ...create component instance (select core-0) */
226 XF_CHK_API(xf_open(&p_adev->proxy, p_handle, comp_id, 0, xaf_comp_response));
227
228 xaf_comp_add(&p_adev->comp_chain, p_comp);
229
230 // Temporary solution in place of component chain handling
231 p_comp->p_adev = p_adev;
232 p_adev->n_comp += 1;
233 p_comp->ninbuf = ninbuf;
234
235 /* ...allocate input buffer */
236 if (ninbuf)
237 {
238 xf_buffer_t *buf;
239 u32 i;
240 XF_CHK_API(xf_pool_alloc(&p_adev->proxy, ninbuf, XAF_INBUF_SIZE, XF_POOL_INPUT, &p_comp->inpool, XAF_MEM_ID_COMP,
241 p_adev->pxf_mem_malloc_fxn, p_adev->pxf_mem_free_fxn));
242
243 for (i=0; i<ninbuf; i++)
244 {
245 buf = xf_buffer_get(p_comp->inpool);
246 pp_inbuf[i] = xf_buffer_data(buf);
247 }
248
249 }
250 p_comp->noutbuf = noutbuf;
251
252 p_comp->comp_type = comp_type;
253 p_comp->comp_status = XAF_STARTING;
254
255 switch (comp_type)
256 {
257 case XAF_DECODER:
258 case XAF_ENCODER:
259 case XAF_PRE_PROC:
260 case XAF_POST_PROC:
261 p_comp->inp_ports = 1; p_comp->out_ports = 1;
262 break;
263 case XAF_MIXER:
264 p_comp->inp_ports = 4; p_comp->out_ports = 1;
265 break;
266 }
267
268 return XAF_NO_ERROR;
269}
270
271XAF_ERR_CODE xaf_comp_delete(void *comp_ptr)
272{
273 xaf_adev_t *p_adev;
274
275 xaf_comp_t *p_comp;
276 p_comp = (xaf_comp_t *)comp_ptr;
277
278 XAF_CHK_PTR(p_comp);
279
280 // Temporary solution in place of component chain handling
281 p_adev = (xaf_adev_t *)(p_comp->p_adev);
282 XF_CHK_ERR((p_adev->n_comp > 0), XAF_API_ERR);
283 p_adev->n_comp -= 1;
284
285
286 if (p_comp->inpool) xf_pool_free(p_comp->inpool, XAF_MEM_ID_COMP, p_adev->pxf_mem_free_fxn);
287 if (p_comp->outpool) xf_pool_free(p_comp->outpool, XAF_MEM_ID_COMP, p_adev->pxf_mem_free_fxn);
288
289 xf_close(&p_comp->handle);
290
291 /* ...tbd - remove from chain */
292 p_adev->pxf_mem_free_fxn(p_comp->comp_ptr, XAF_MEM_ID_COMP);
293 p_comp->comp_ptr = NULL;
294
295 return XAF_NO_ERROR;
296}
297
298XAF_ERR_CODE xaf_comp_set_config(void *comp_ptr, s32 num_param, s32 *p_param)
299{
300 xaf_comp_t *p_comp;
301 xf_user_msg_t rmsg;
302 xf_set_param_msg_t *smsg;
303 xf_handle_t *p_handle;
304 s32 i, j;
305
306 p_comp = (xaf_comp_t *)comp_ptr;
307
308 XAF_CHK_PTR(p_comp);
309 XAF_CHK_PTR(p_param);
310 XAF_CHK_RANGE(num_param, 1, XAF_MAX_CONFIG_PARAMS);
311
312 p_handle = &p_comp->handle;
313 XAF_CHK_PTR(p_handle);
314
315 /* ...set persistent stream characteristics */
316 smsg = xf_buffer_data(p_handle->aux);
317
318 j = 0;
319 for (i=0; i<num_param; i++)
320 {
321 smsg->item[i].id = p_param[j++];
322 smsg->item[i].value = p_param[j++];
323 }
324
325 /* ...pass command to the component */
326 /* ...tbd - command goes port 0 always, check if okay */
327 XF_CHK_API(xf_command(p_handle, 0, XF_SET_PARAM, smsg, sizeof(xf_set_param_item_t)*num_param));
328
329 /* ...wait until result is delivered */
330 XF_CHK_API(xf_response_get(p_handle, &rmsg));
331
332 /* ...make sure response is expected */
333 XF_CHK_ERR(rmsg.opcode == (u32) XF_SET_PARAM && rmsg.buffer == smsg, XAF_API_ERR);
334
335 return XAF_NO_ERROR;
336}
337
338XAF_ERR_CODE xaf_comp_get_config(void *comp_ptr, s32 num_param, s32 *p_param)
339{
340 xaf_comp_t *p_comp;
341 xf_user_msg_t rmsg;
342 xf_get_param_msg_t *smsg;
343 xf_handle_t *p_handle;
344 s32 i;
345
346 p_comp = (xaf_comp_t *)comp_ptr;
347
348 XAF_CHK_PTR(p_comp);
349 XAF_CHK_PTR(p_param);
350 XAF_CHK_RANGE(num_param, 1, XAF_MAX_CONFIG_PARAMS);
351
352 p_handle = &p_comp->handle;
353 XAF_CHK_PTR(p_handle);
354
355 /* ...set persistent stream characteristics */
356 smsg = xf_buffer_data(p_handle->aux);
357
358 for (i=0; i<num_param; i++)
359 {
360 smsg->c.id[i] = p_param[i];
361 }
362
363 /* ...pass command to the component */
364 /* ...tbd - command goes port 0 always, check if okay */
365 XF_CHK_API(xf_command(p_handle, 0, XF_GET_PARAM, smsg, XF_GET_PARAM_CMD_LEN(num_param)));
366
367 /* ...wait until result is delivered */
368 XF_CHK_API(xf_response_get(p_handle, &rmsg));
369
370 /* ...make sure response is expected */
371 XF_CHK_ERR(rmsg.opcode == (u32) XF_GET_PARAM && rmsg.buffer == smsg, XAF_API_ERR);
372
373 for (i=0; i<num_param; i++)
374 {
375 p_param[i] = smsg->r.value[i];
376 }
377
378 return XAF_NO_ERROR;
379}
380#ifdef XAF_HOSTLESS
381XAF_ERR_CODE xaf_comp_get_status(xaf_adev_t *p_adev, xaf_comp_t *p_comp, xaf_comp_status *p_status, void *p_info)
382#else
383XAF_ERR_CODE xaf_comp_get_status(void *adev_ptr, void *comp_ptr, xaf_comp_status *p_status, xaf_info_t *p_info)
384#endif
385{
386 xaf_adev_t *p_adev;
387 xaf_comp_t *p_comp;
388 xf_handle_t *p_handle;
389
390 p_adev = (xaf_adev_t *)adev_ptr;
391 p_comp = (xaf_comp_t *)comp_ptr;
392
393 XAF_CHK_PTR(p_comp);
394 XAF_CHK_PTR(p_status);
395 XAF_CHK_PTR(p_info);
396 if (!p_comp->init_done) XAF_CHK_PTR(p_adev);
397
398 p_handle = &p_comp->handle;
399
400 if (p_comp->pending_resp)
401 {
402 xf_user_msg_t rmsg;
403 /* ...wait until result is delivered */
404 XF_CHK_API(xf_response_get(p_handle, &rmsg));
405
406 if (rmsg.opcode == XF_FILL_THIS_BUFFER)
407 {
408 if (rmsg.buffer == p_comp->start_buf)
409 {
410 XF_CHK_API(xaf_comp_post_init_config(p_adev, p_comp, p_comp->start_buf));
411 }
412 else
413 {
414#ifdef XAF_HOSTLESS
415 s32 *p_buf = (s32 *) p_info;
416 p_buf[0] = (s32) rmsg.buffer;
417 p_buf[1] = (s32) rmsg.length;
418#else
419 p_info->buf = (void*) rmsg.buffer;
420 p_info->length = (s32) rmsg.length;
421#endif
422 if (!p_comp->inpool && p_comp->outpool) p_comp->pending_resp--;
423
424 if (!rmsg.length) p_comp->comp_status = XAF_EXEC_DONE;
425 else
426 {
427 p_comp->comp_status = XAF_OUTPUT_READY;
428 p_comp->expect_out_cmd++;
429 }
430 }
431 }
432 else
433 {
434 /* ...make sure response is expected */
435 XF_CHK_ERR(rmsg.opcode == (u32) XF_EMPTY_THIS_BUFFER, XAF_API_ERR);
436#ifdef XAF_HOSTLESS
437 s32 *p_buf = (s32 *) p_info;
438 p_buf[0] = (s32) rmsg.buffer;
439 p_buf[1] = (s32) rmsg.length;
440#else
441 p_info->buf = (void*) rmsg.buffer;
442 p_info->length = (s32) rmsg.length;
443#endif
444 p_comp->pending_resp--;
445
446 if (p_comp->input_over && rmsg.buffer == NULL) p_comp->comp_status = XAF_EXEC_DONE;
447 else p_comp->comp_status = XAF_NEED_INPUT;
448 }
449 }
450 else if ((p_comp->comp_status == XAF_STARTING && p_comp->start_cmd_issued) ||
451 (p_comp->comp_status == XAF_INIT_DONE && p_comp->exec_cmd_issued))
452 {
453 if (p_comp->inpool) p_comp->comp_status = XAF_NEED_INPUT;
454 }
455
456 *p_status = p_comp->comp_status;
457
458 return XAF_NO_ERROR;
459}
460
461XAF_ERR_CODE xaf_comp_process(void *adev_ptr, void *comp_ptr, void *p_buf, u32 length, xaf_comp_flag flag)
462{
463 xaf_adev_t *p_adev;
464 xaf_comp_t *p_comp;
465 xf_handle_t *p_handle;
466
467 p_adev = (xaf_adev_t *)adev_ptr;
468 p_comp = (xaf_comp_t *)comp_ptr;
469
470 XAF_CHK_PTR(p_comp);
471 if (!p_comp->init_done) XAF_CHK_PTR(p_adev);
472 XAF_CHK_RANGE(flag, XAF_START_FLAG, XAF_NEED_OUTPUT_FLAG);
473 if (flag == XAF_INPUT_READY_FLAG) XAF_CHK_RANGE(length, 0, XAF_INBUF_SIZE);
474
475 p_handle = &p_comp->handle;
476
477 switch (flag)
478 {
479 case XAF_START_FLAG:
480 if (p_comp->start_cmd_issued)
481 break;
482 else
483 {
484 p_comp->start_buf = xf_buffer_data(p_handle->aux);
485 XF_CHK_API(xf_command(p_handle, (p_comp->inp_ports), XF_FILL_THIS_BUFFER, p_comp->start_buf, 0));
486 p_comp->start_cmd_issued = 1;
487
488 if(p_comp->comp_type != XAF_DECODER)
489 {
490 xf_user_msg_t rmsg;
491 /* ...wait until result is delivered */
492 XF_CHK_API(xf_response_get(p_handle, &rmsg));
493
494 /* ...make sure response is expected */
495 XF_CHK_ERR(rmsg.opcode == XF_FILL_THIS_BUFFER && rmsg.buffer == p_comp->start_buf, XAF_API_ERR);
496
497 XF_CHK_API(xaf_comp_post_init_config(p_adev, p_comp, p_comp->start_buf));
498 }
499 }
500 break;
501
502 case XAF_EXEC_FLAG:
503 if (!p_comp->init_done || p_comp->exec_cmd_issued)
504 break;
505 p_comp->exec_cmd_issued = 1;
506 if (p_comp->outpool)
507 {
508 u32 i;
509 xf_buffer_t *p_buf;
510 void *p_data;
511
512 for (i=0; i<p_comp->noutbuf; i++)
513 {
514 p_buf = xf_buffer_get(p_comp->outpool);
515 p_data = xf_buffer_data(p_buf);
516
517 XF_CHK_API(xf_command(&p_comp->handle, (p_comp->inp_ports), XF_FILL_THIS_BUFFER, p_data, p_comp->out_format.output_length));
518 }
519
520 if (!p_comp->inpool) p_comp->pending_resp = p_comp->noutbuf;
521 }
522 break;
523
524 case XAF_INPUT_OVER_FLAG:
525 if (!p_comp->input_over)
526 {
527 XF_CHK_API(xf_command(p_handle, 0, XF_EMPTY_THIS_BUFFER, NULL, 0));
528 p_comp->input_over = 1;
529 p_comp->pending_resp++;
530 }
531 break;
532
533 case XAF_INPUT_READY_FLAG:
534 if (!p_comp->input_over)
535 {
536 XAF_CHK_PTR(p_buf);
537 XF_CHK_API(xf_command(p_handle, 0, XF_EMPTY_THIS_BUFFER, p_buf, length));
538 p_comp->pending_resp++;
539 }
540 break;
541
542 case XAF_NEED_OUTPUT_FLAG:
543 if (p_comp->expect_out_cmd)
544 {
545 XAF_CHK_PTR(p_buf);
546 XF_CHK_API(xf_command(p_handle, (p_comp->inp_ports), XF_FILL_THIS_BUFFER, p_buf, length));
547 p_comp->expect_out_cmd--;
548
549 if (!p_comp->inpool && p_comp->outpool) p_comp->pending_resp++;
550 }
551 break;
552 }
553
554 return XAF_NO_ERROR;
555}
556
557XAF_ERR_CODE xaf_connect(void *src_ptr, void *dest_ptr, s32 num_buf)
558{
559 xaf_comp_t *p_src;
560 xaf_comp_t *p_dest;
561
562 p_src = (xaf_comp_t *)src_ptr;
563 p_dest = (xaf_comp_t *)dest_ptr;
564
565 XAF_CHK_PTR(p_src);
566 XAF_CHK_PTR(p_dest);
567 XAF_CHK_RANGE(num_buf, 2, 4);
568
569 if (!p_src->init_done || p_src->out_routed == p_src->out_ports || p_dest->inp_routed == p_dest->inp_ports)
570 return XAF_ROUTING_ERROR;
571
572 XF_CHK_API(xf_route(&p_src->handle, (p_src->inp_ports + p_src->out_routed), &p_dest->handle, (p_dest->inp_routed), num_buf, p_src->out_format.output_length, 8));
573
574 p_src->out_routed++;
575 p_dest->inp_routed++;
576
577 return XAF_NO_ERROR;
578}
579
580XAF_ERR_CODE xaf_disconnect(xaf_comp_t *p_comp)
581{
582 XAF_CHK_PTR(p_comp);
583
584 /* ...tbd - support for multiple output ports */
585 if (!p_comp->init_done || p_comp->out_routed != p_comp->out_ports)
586 return XAF_ROUTING_ERROR;
587
588 XF_CHK_API(xf_unroute(&p_comp->handle, (p_comp->inp_ports)));
589
590 return XAF_NO_ERROR;
591}
592
593
594
595
596
597