Steve Muckle | 0a9c087 | 2022-02-16 05:58:07 +0000 | [diff] [blame] | 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 | |
| 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 | |
| 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 | |
| 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 |
| 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 | |
| 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 | |
| 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 | |
| 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 | |
| 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 | |
| 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 | |
| 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 |
| 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 | |
| 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 | |
| 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 | |
| 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 | |