1 /*******************************************************************************
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 
35 TRACE_TAG(INIT, 1);
36 TRACE_TAG(DEBUG, 1);
37 TRACE_TAG(INFO, 1);
38 
39 #define XAF_4BYTE_ALIGN    4
40 #define XAF_8BYTE_ALIGN    8
41 #define XAF_32BYTE_ALIGN   32
42 
43 
xaf_comp_response(xf_handle_t * h,xf_user_msg_t * msg)44 static 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 
xaf_comp_add(xaf_comp_t ** pp_comp_chain,xaf_comp_t * p_comp)58 static 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 
xaf_comp_post_init_config(xaf_adev_t * p_adev,xaf_comp_t * p_comp,void * p_msg)69 static 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
xaf_xos_start()95 XAF_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 
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)112 XAF_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 
xaf_adev_close(void * adev_ptr,xaf_comp_flag flag)163 XAF_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 
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)193 XAF_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 
xaf_comp_delete(void * comp_ptr)271 XAF_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 
xaf_comp_set_config(void * comp_ptr,s32 num_param,s32 * p_param)298 XAF_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 
xaf_comp_get_config(void * comp_ptr,s32 num_param,s32 * p_param)338 XAF_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
xaf_comp_get_status(xaf_adev_t * p_adev,xaf_comp_t * p_comp,xaf_comp_status * p_status,void * p_info)381 XAF_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
383 XAF_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 
xaf_comp_process(void * adev_ptr,void * comp_ptr,void * p_buf,u32 length,xaf_comp_flag flag)461 XAF_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 
xaf_connect(void * src_ptr,void * dest_ptr,s32 num_buf)557 XAF_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 
xaf_disconnect(xaf_comp_t * p_comp)580 XAF_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 
598