source: svn/newcon3bcm2_21bu/magnum/portinginterface/ape/7552/bape_output_capture.c

Last change on this file was 76, checked in by megakiss, 10 years ago

1W 대기전력을 만족시키기 위하여 POWEROFF시 튜너를 Standby 상태로 함

  • Property svn:executable set to *
File size: 24.7 KB
Line 
1/***************************************************************************
2 *     Copyright (c) 2006-2012, Broadcom Corporation
3 *     All Rights Reserved
4 *     Confidential Property of Broadcom Corporation
5 *
6 *  THIS SOFTWARE MAY ONLY BE USED SUBJECT TO AN EXECUTED SOFTWARE LICENSE
7 *  AGREEMENT  BETWEEN THE USER AND BROADCOM.  YOU HAVE NO RIGHT TO USE OR
8 *  EXPLOIT THIS MATERIAL EXCEPT SUBJECT TO THE TERMS OF SUCH AN AGREEMENT.
9 *
10 * $brcm_Workfile: bape_output_capture.c $
11 * $brcm_Revision: Hydra_Software_Devel/17 $
12 * $brcm_Date: 3/6/12 3:01p $
13 *
14 * Module Description: Audio Decoder Interface
15 *
16 * Revision History:
17 *
18 * $brcm_Log: /magnum/portinginterface/ape/7422/bape_output_capture.c $
19 *
20 * Hydra_Software_Devel/17   3/6/12 3:01p gskerl
21 * SW7425-2570: Renamed OutputPortObject substruct from connector to
22 * outputPort.
23 *
24 * Hydra_Software_Devel/16   1/27/12 4:53p jgarrett
25 * SW7429-55: Allowing setMclk_isr to be called prior to enable on 7429
26 *
27 * Hydra_Software_Devel/15   11/14/11 3:36p gskerl
28 * SW7429-18: Merging 7429 changes back to main branch.
29 *
30 * Hydra_Software_Devel/SW7429-18/1   10/21/11 6:29p jgarrett
31 * SW7429-18: Initial compileable version for 7429
32 *
33 * Hydra_Software_Devel/14   11/1/11 1:54p gskerl
34 * SW7425-1645: Set interrupte handlers using new passed in values instead
35 * of existing values.
36 *
37 * Hydra_Software_Devel/13   8/22/11 4:16p gskerl
38 * SW7425-1179: Corrected BAPE_OutputCapture_Open() to use reasonable
39 * default settings when called with a NULL settings argument. Also
40 * modified BAPE_OutputCapture_GetDefaultOpenSettings() to provide
41 * defaults for numBuffers and watermarkThreshold settings.
42 *
43 * Hydra_Software_Devel/12   5/23/11 6:49p jgarrett
44 * SW7425-402: Adding multichannel capture support
45 *
46 * Hydra_Software_Devel/11   5/20/11 5:16p jgarrett
47 * SW7425-402: Adding error code to handle output enable callback failing.
48 *
49 * Hydra_Software_Devel/10   5/3/11 10:47a gskerl
50 * SW7422-354: Added index and type args to APE_P_InitOutputPort macro
51 *
52 * Hydra_Software_Devel/9   4/16/11 12:59p jgarrett
53 * SW7425-372: Fixing loopback output resolution
54 *
55 * Hydra_Software_Devel/8   4/16/11 12:15p jgarrett
56 * SW7425-371: Removing tab characters
57 *
58 * Hydra_Software_Devel/7   4/6/11 1:23a jgarrett
59 * SW35330-35: Merge to main branch
60 *
61 * Hydra_Software_Devel/SW35330-35/1   4/5/11 12:49p jgarrett
62 * SW35330-35: FMM Abstraction refactoring to support DTV
63 *
64 * Hydra_Software_Devel/6   3/22/11 3:00p gskerl
65 * SW7422-146: Changed audio output connector callbacks to take the output
66 * connector as an argument
67 *
68 * Hydra_Software_Devel/5   3/21/11 7:08p jgarrett
69 * SW7422-356: Adding MuxOutput
70 *
71 * Hydra_Software_Devel/4   3/10/11 7:03p jgarrett
72 * SW7422-146: Refactored DFIFO code, added support for input capture from
73 * compressed/multichannel
74 *
75 * Hydra_Software_Devel/3   2/28/11 1:28p jgarrett
76 * SW7422-146: Filter graph reworked to remove mixer dependencies
77 *
78 * Hydra_Software_Devel/2   2/22/11 5:43p jgarrett
79 * SW7422-146: Implemented type renaming based on filter graph review
80 * comments
81 *
82 * Hydra_Software_Devel/1   12/16/10 4:05p jgarrett
83 * SW7422-146: Initial compilable APE for 7422
84 *
85 ***************************************************************************/
86
87#include "bstd.h"
88#include "bkni.h"
89#include "bape.h"
90#include "bape_priv.h"
91
92BDBG_MODULE(bape_output_capture);
93
94BDBG_OBJECT_ID(BAPE_OutputCapture);
95
96typedef struct BAPE_OutputCapture
97{
98    BDBG_OBJECT(BAPE_OutputCapture)
99    BAPE_Handle deviceHandle;
100    unsigned bufferSize, watermark;
101    BAPE_OutputCaptureSettings settings;
102    unsigned index;
103    BAPE_OutputPortObject outputPort;
104    unsigned sampleRate;
105    unsigned numBuffers;
106    void *pBuffers[BAPE_Channel_eMax];
107    uint32_t bufferOffset[BAPE_Channel_eMax];
108    BAPE_DfifoGroupHandle dfifoGroup;
109    BAPE_LoopbackGroupHandle loopbackGroup;
110#if BAPE_CHIP_MAX_FS > 0
111    unsigned fs;
112#else
113    BAPE_MclkSource mclkSource;
114    unsigned pllChannel;
115    unsigned mclkFreqToFsRatio;
116#endif
117    bool enabled;
118    BAPE_OutputCaptureInterruptHandlers interrupts;
119    char name[7];   /* CAP %d */
120} BAPE_OutputCapture;
121
122static void BAPE_OutputCapture_P_ClearInterrupts_isr(BAPE_OutputCaptureHandle handle);
123
124/* Connector callbacks */
125static void BAPE_OutputCapture_P_SetTimingParams_isr(BAPE_OutputPort output, unsigned sampleRate, BAVC_Timebase timebase);
126static BERR_Code BAPE_OutputCapture_P_Enable(BAPE_OutputPort output);
127static void BAPE_OutputCapture_P_Disable(BAPE_OutputPort output);
128#if BAPE_CHIP_MAX_FS > 0
129static void BAPE_OutputCapture_P_SetFs(BAPE_OutputPort output, unsigned fsNum);
130#else
131static void BAPE_OutputCapture_P_SetMclk_isr(BAPE_OutputPort output, BAPE_MclkSource mclkSource, unsigned pllChannel, unsigned mclkFreqToFsRatio);
132#endif
133
134void BAPE_OutputCapture_GetDefaultOpenSettings(
135    BAPE_OutputCaptureOpenSettings *pSettings       /* [out] */
136    )
137{
138    BKNI_Memset(pSettings, 0, sizeof(*pSettings));   
139    pSettings->bufferSize = BDSP_AF_P_NON_DELAY_RBUF_SIZE*2;
140    pSettings->numBuffers = 1;
141    pSettings->watermarkThreshold = pSettings->bufferSize / 2;
142}
143
144BERR_Code BAPE_OutputCapture_Open(
145    BAPE_Handle deviceHandle,
146    unsigned index,
147    const BAPE_OutputCaptureOpenSettings *pSettings,
148    BAPE_OutputCaptureHandle *pHandle             /* [out] */
149    )
150{
151    BERR_Code errCode;
152    BAPE_OutputCaptureHandle handle;
153    BAPE_OutputCaptureOpenSettings defaultSettings;
154    void *pMem, *pCachedMem;
155    unsigned bufferSize=0, watermark=0;
156    unsigned maxChannelPairs, numBuffers=1;
157    unsigned i;
158
159    BDBG_OBJECT_ASSERT(deviceHandle, BAPE_Device);
160    BDBG_ASSERT(NULL != pHandle);
161
162    if ( index >= BAPE_CHIP_MAX_OUTPUT_CAPTURES )
163    {
164        BDBG_ERR(("Unable to open output capture %u.  Max output captures is %u on this platform.", index, BAPE_CHIP_MAX_OUTPUT_CAPTURES));
165        return BERR_TRACE(BERR_NOT_SUPPORTED);
166    }
167   
168    if ( NULL == pSettings )
169    {
170        BAPE_OutputCapture_GetDefaultOpenSettings(&defaultSettings);
171        pSettings = &defaultSettings;
172    }
173
174    /* Determine buffer size */
175    if ( NULL != pSettings )
176    {
177        bufferSize = pSettings->bufferSize;
178        watermark = pSettings->watermarkThreshold;
179        if ( pSettings->numBuffers > BAPE_Channel_eMax )
180        {
181            BDBG_WRN(("Requested %u buffers but only %u channels are possible.  Allocating %u buffers.",
182                      pSettings->numBuffers, BAPE_Channel_eMax, BAPE_Channel_eMax));
183            numBuffers = BAPE_Channel_eMax;
184        }
185        else
186        {
187            numBuffers = pSettings->numBuffers;
188        }
189    }
190    if ( 0 == bufferSize )
191    {
192        bufferSize = deviceHandle->pcmBufferSize;
193    }
194    if ( 0 == watermark )
195    {
196        watermark = bufferSize/4;
197    }
198
199    /* Allocate handle */
200    handle = BKNI_Malloc(sizeof(BAPE_OutputCapture));
201    if ( NULL == handle )
202    {
203        return BERR_TRACE(BERR_OUT_OF_SYSTEM_MEMORY);
204    }
205    BKNI_Memset(handle, 0, sizeof(BAPE_OutputCapture));
206
207    BDBG_OBJECT_SET(handle, BAPE_OutputCapture);
208    handle->deviceHandle = deviceHandle;
209    handle->bufferSize = bufferSize;
210    handle->watermark = watermark;
211    handle->settings.bitsPerSample = 32;
212    handle->settings.interleaveData = true;
213    handle->index = index;
214    BAPE_P_InitOutputPort(&handle->outputPort, BAPE_OutputPortType_eOutputCapture, index, handle);
215    maxChannelPairs = BAPE_CHIP_MAX_LOOPBACKS;
216    if ( maxChannelPairs > BAPE_CHIP_MAX_DFIFOS )
217    {
218        maxChannelPairs = BAPE_CHIP_MAX_DFIFOS;
219    }
220    if ( maxChannelPairs > pSettings->numBuffers )
221    {
222        maxChannelPairs = pSettings->numBuffers;
223    }
224    if ( maxChannelPairs > BAPE_ChannelPair_eMax )
225    {
226        maxChannelPairs = BAPE_ChannelPair_eMax;
227    }
228    handle->outputPort.maxChannelPairs = maxChannelPairs;
229    handle->outputPort.compressedSupported = true;
230    handle->outputPort.enable = BAPE_OutputCapture_P_Enable;
231    handle->outputPort.disable = BAPE_OutputCapture_P_Disable;
232    handle->outputPort.setTimingParams_isr = BAPE_OutputCapture_P_SetTimingParams_isr;
233    handle->sampleRate = 0;
234#if BAPE_CHIP_MAX_FS > 0
235    handle->outputPort.fsTiming = true;
236    handle->outputPort.setFs = BAPE_OutputCapture_P_SetFs;
237    handle->fs = (unsigned)-1;
238#else
239    handle->outputPort.setMclk_isr = BAPE_OutputCapture_P_SetMclk_isr;
240    handle->mclkSource = BAPE_MclkSource_eNone;
241    handle->pllChannel = 0;
242    handle->mclkFreqToFsRatio = BAPE_BASE_PLL_TO_FS_RATIO;
243#endif
244    BKNI_Snprintf(handle->name, sizeof(handle->name), "CAP %u", index); 
245    handle->outputPort.pName = handle->name;
246
247    handle->numBuffers = numBuffers;
248    for ( i = 0; i < numBuffers; i++ )
249    {
250        /* Allocate buffer */
251        handle->pBuffers[i] = pMem = BMEM_Heap_AllocAligned(deviceHandle->memHandle, bufferSize, 8, 0);
252        if ( NULL == pMem )
253        {
254            errCode = BERR_TRACE(BERR_OUT_OF_DEVICE_MEMORY);
255            goto err_buffer;
256        }
257   
258        errCode = BMEM_Heap_ConvertAddressToOffset(deviceHandle->memHandle, pMem, &handle->bufferOffset[i]);
259        if ( errCode )
260        {
261            errCode = BERR_TRACE(errCode);
262            goto err_offset;
263        }
264   
265        errCode = BMEM_Heap_ConvertAddressToCached(deviceHandle->memHandle, pMem, &pCachedMem);
266        if ( BERR_SUCCESS == errCode )
267        {
268            /* Flush once at open to make sure the buffer has been invalidated from the cache. */
269            BMEM_Heap_FlushCache(deviceHandle->memHandle, pCachedMem, bufferSize);
270        }
271        /* Not fatal if it fails, assume no cache support */
272    }
273
274    handle->deviceHandle->outputCaptures[index] = handle;
275
276    *pHandle = handle;
277    return BERR_SUCCESS;
278
279err_offset:
280err_buffer:
281    for ( i = 0; i < BAPE_Channel_eMax; i++ )
282    {
283        if ( handle->pBuffers[i] )
284        {
285            BMEM_Heap_Free(deviceHandle->memHandle, handle->pBuffers[i]);
286        }
287    }
288    BDBG_OBJECT_DESTROY(handle, BAPE_OutputCapture);
289    BKNI_Free(handle);
290    return errCode;
291}
292
293void BAPE_OutputCapture_Close(
294    BAPE_OutputCaptureHandle handle
295    )
296{
297    unsigned i;
298    BDBG_OBJECT_ASSERT(handle, BAPE_OutputCapture);
299    BDBG_ASSERT(handle->enabled == false);
300    BDBG_ASSERT(handle->outputPort.mixer == NULL);
301    BDBG_ASSERT(NULL == handle->dfifoGroup);
302    BDBG_ASSERT(NULL == handle->loopbackGroup);
303    for ( i = 0; i < BAPE_Channel_eMax; i++ )
304    {
305        if ( handle->pBuffers[i] )
306        {
307            BMEM_Heap_Free(handle->deviceHandle->memHandle, handle->pBuffers[i]);
308        }
309    }
310    handle->deviceHandle->outputCaptures[handle->index] = NULL;
311    BDBG_OBJECT_DESTROY(handle, BAPE_OutputCapture);
312    BKNI_Free(handle);
313}
314
315void BAPE_OutputCapture_GetSettings(
316    BAPE_OutputCaptureHandle handle,
317    BAPE_OutputCaptureSettings *pSettings       /* [out] */
318    )
319{
320    BDBG_OBJECT_ASSERT(handle, BAPE_OutputCapture);
321    BDBG_ASSERT(NULL != pSettings);
322    *pSettings = handle->settings;
323}
324
325BERR_Code BAPE_OutputCapture_SetSettings(
326    BAPE_OutputCaptureHandle handle,
327    const BAPE_OutputCaptureSettings *pSettings
328    )
329{
330    BDBG_OBJECT_ASSERT(handle, BAPE_OutputCapture);
331    BDBG_ASSERT(NULL != pSettings);
332#if BAPE_CHIP_DFIFO_SUPPORTS_16BIT_CAPTURE
333    if ( pSettings->bitsPerSample != 32 && pSettings->bitsPerSample != 16)
334    {
335        BDBG_ERR(("Only 16-bit and 32-bit capture samples are supported on this chipset."));
336        return BERR_TRACE(BERR_INVALID_PARAMETER);
337    }
338#else
339    if ( pSettings->bitsPerSample != 32 )
340    {
341        BDBG_ERR(("Only 32-bit capture samples are supported on this chipset."));
342        return BERR_TRACE(BERR_INVALID_PARAMETER);
343    }
344#endif
345    handle->settings = *pSettings;
346    return BERR_SUCCESS;
347}
348
349void BAPE_OutputCapture_Flush(
350    BAPE_OutputCaptureHandle handle
351    )
352{
353    BDBG_OBJECT_ASSERT(handle, BAPE_OutputCapture);
354    BKNI_EnterCriticalSection();
355    BAPE_OutputCapture_Flush_isr(handle);
356    BKNI_LeaveCriticalSection();
357}
358
359void BAPE_OutputCapture_Flush_isr(
360    BAPE_OutputCaptureHandle handle
361    )
362{
363    BDBG_OBJECT_ASSERT(handle, BAPE_OutputCapture);
364   
365    if ( handle->dfifoGroup )
366    {
367        BAPE_DfifoGroup_P_Flush_isr(handle->dfifoGroup);
368    }
369}
370
371BERR_Code BAPE_OutputCapture_GetBuffer(
372    BAPE_OutputCaptureHandle handle,
373    BAPE_BufferDescriptor *pBuffers         /* [out] */
374    )
375{   
376    BERR_Code errCode;
377
378    BDBG_OBJECT_ASSERT(handle, BAPE_OutputCapture);
379    BDBG_ASSERT(NULL != pBuffers);
380
381    BKNI_Memset(pBuffers, 0, sizeof(*pBuffers));
382    pBuffers->interleaved = handle->settings.interleaveData;
383    if ( !handle->enabled )
384    {
385        return BERR_SUCCESS;
386    }
387
388    BDBG_ASSERT(NULL != handle->dfifoGroup);
389    BKNI_EnterCriticalSection();
390    errCode = BAPE_DfifoGroup_P_GetBuffer_isr(handle->dfifoGroup, pBuffers);
391    BKNI_LeaveCriticalSection();
392    if ( errCode )
393    {
394        return BERR_TRACE(errCode);
395    }
396
397    return BERR_SUCCESS;
398}
399
400BERR_Code BAPE_OutputCapture_ConsumeData(
401    BAPE_OutputCaptureHandle handle,
402    unsigned numBytes                   /* Number of bytes read from the buffer */
403    )
404{
405    BERR_Code errCode;
406
407    BDBG_OBJECT_ASSERT(handle, BAPE_OutputCapture);
408
409    if ( !handle->enabled )
410    {
411        return BERR_SUCCESS;
412    }
413
414    BDBG_ASSERT(NULL != handle->dfifoGroup);
415    BKNI_EnterCriticalSection();
416    errCode = BAPE_DfifoGroup_P_CommitData_isr(handle->dfifoGroup, numBytes);
417    BAPE_OutputCapture_P_ClearInterrupts_isr(handle);
418    BKNI_LeaveCriticalSection();
419
420    if ( errCode )
421    {
422        return BERR_TRACE(errCode);
423    }
424
425    return BERR_SUCCESS;
426}
427
428void BAPE_OutputCapture_GetOutputPort(
429    BAPE_OutputCaptureHandle handle,
430    BAPE_OutputPort *pOutputPort
431    )
432{
433    BDBG_OBJECT_ASSERT(handle, BAPE_OutputCapture);
434    BDBG_ASSERT(NULL != pOutputPort);
435    *pOutputPort = &handle->outputPort;
436}
437
438void BAPE_OutputCapture_GetInterruptHandlers(
439    BAPE_OutputCaptureHandle handle,
440    BAPE_OutputCaptureInterruptHandlers *pInterrupts    /* [out] */
441    )
442{
443    BDBG_OBJECT_ASSERT(handle, BAPE_OutputCapture);
444    BDBG_ASSERT(NULL != pInterrupts);
445    *pInterrupts = handle->interrupts;
446}
447
448BERR_Code BAPE_OutputCapture_SetInterruptHandlers(
449    BAPE_OutputCaptureHandle handle,
450    const BAPE_OutputCaptureInterruptHandlers *pInterrupts
451    )
452{
453    BERR_Code errCode;
454
455    BDBG_OBJECT_ASSERT(handle, BAPE_OutputCapture);
456    BDBG_ASSERT(NULL != pInterrupts);
457
458    if ( handle->enabled )
459    {
460        BDBG_ASSERT(NULL != handle->dfifoGroup);
461        /* Install interrupt handlers */
462        errCode = BAPE_DfifoGroup_P_SetFullmarkInterrupt(handle->dfifoGroup,
463                                                         pInterrupts->watermark.pCallback_isr,
464                                                         pInterrupts->watermark.pParam1,
465                                                         pInterrupts->watermark.param2);
466        if ( errCode )
467        {
468            return BERR_TRACE(errCode);
469        }
470        errCode = BAPE_DfifoGroup_P_SetOverflowInterrupt(handle->dfifoGroup,
471                                                         pInterrupts->overflow.pCallback_isr,
472                                                         pInterrupts->overflow.pParam1,
473                                                         pInterrupts->overflow.param2);
474        if ( errCode )
475        {
476            BAPE_DfifoGroup_P_SetFullmarkInterrupt(handle->dfifoGroup, NULL, NULL, 0);
477            return BERR_TRACE(errCode);
478        }
479    }
480
481    handle->interrupts = *pInterrupts;
482    return BERR_SUCCESS;
483}
484
485static BERR_Code BAPE_OutputCapture_P_Enable(BAPE_OutputPort output)
486{
487    BERR_Code errCode;
488    BAPE_DfifoGroupSettings dfifoSettings;
489    BAPE_LoopbackGroupSettings loopbackSettings;
490    BAPE_OutputCaptureHandle handle;
491    BAPE_LoopbackGroupCreateSettings loopbackCreateSettings;
492    BAPE_DfifoGroupCreateSettings dfifoCreateSettings;
493    unsigned numBuffersRequired, i, step;
494
495    BDBG_OBJECT_ASSERT(output, BAPE_OutputPort);
496
497    handle = output->pHandle;
498    BDBG_OBJECT_ASSERT(handle, BAPE_OutputCapture);
499
500    BDBG_ASSERT(false == handle->enabled);
501
502    /* Make sure we have enough buffers to satisfy this request */
503    numBuffersRequired = output->mixer->numChannelPairs;
504    if ( handle->settings.interleaveData )
505    {
506        step = 2;
507    }
508    else
509    {
510        numBuffersRequired *= 2;
511        step = 1;
512    }
513    if ( numBuffersRequired > handle->numBuffers )
514    {
515        BDBG_ERR(("To support %u channels %s requires %u buffers but only %u are allocated for OutputCapture %u", 
516                  output->mixer->numChannelPairs, 
517                  (handle->settings.interleaveData)?"interleaved":"non-interleaved",
518                  numBuffersRequired, handle->numBuffers, handle->index));
519        return BERR_TRACE(BERR_INVALID_PARAMETER);
520    }
521
522    /* Allocate needed loopback resources */
523    BAPE_LoopbackGroup_P_GetDefaultCreateSettings(&loopbackCreateSettings);
524    loopbackCreateSettings.numChannelPairs = output->mixer->numChannelPairs;
525    errCode = BAPE_LoopbackGroup_P_Create(handle->deviceHandle, &loopbackCreateSettings, &handle->loopbackGroup);
526    if ( errCode )
527    {
528        errCode = BERR_TRACE(errCode);
529        goto err_loopback_alloc;
530    }
531
532    /* Allocate needed DFIFO resources */
533    BAPE_DfifoGroup_P_GetDefaultCreateSettings(&dfifoCreateSettings);
534    dfifoCreateSettings.numChannelPairs = output->mixer->numChannelPairs;
535    errCode = BAPE_DfifoGroup_P_Create(handle->deviceHandle, &dfifoCreateSettings, &handle->dfifoGroup);
536    if ( errCode )
537    {
538        errCode = BERR_TRACE(errCode);
539        goto err_dfifo_alloc;
540    }
541
542    /* Setup and enable the DFIFO first, then Loopback */
543    BAPE_DfifoGroup_P_GetSettings(handle->dfifoGroup, &dfifoSettings);
544    dfifoSettings.highPriority = (output->mixer->sampleRate) >= 96000 ? true : false;
545    BAPE_LoopbackGroup_P_GetCaptureFciIds(handle->loopbackGroup, &dfifoSettings.input);
546    dfifoSettings.interleaveData = handle->settings.interleaveData;
547    dfifoSettings.dataWidth = handle->settings.bitsPerSample;
548    for ( i = 0; i < numBuffersRequired; i++ )
549    {
550        unsigned dfifoBufIndex = i*step;
551        dfifoSettings.bufferInfo[dfifoBufIndex].base = handle->bufferOffset[i];
552        dfifoSettings.bufferInfo[dfifoBufIndex].length = handle->bufferSize;
553        dfifoSettings.bufferInfo[dfifoBufIndex].watermark = handle->watermark;
554    }
555    errCode = BAPE_DfifoGroup_P_SetSettings(handle->dfifoGroup, &dfifoSettings);
556    if ( errCode )
557    {
558        errCode = BERR_TRACE(errCode);
559        goto err_dfifo_settings;
560    }
561
562    /* Configure Loopback */
563    BAPE_LoopbackGroup_P_GetSettings(handle->loopbackGroup, &loopbackSettings);
564#if BAPE_CHIP_MAX_FS > 0
565    loopbackSettings.fs = handle->fs;
566#else
567    loopbackSettings.mclkSource = handle->mclkSource;   
568    loopbackSettings.pllChannel = handle->pllChannel;
569    loopbackSettings.mclkFreqToFsRatio = handle->mclkFreqToFsRatio;
570#endif
571    loopbackSettings.input = handle->outputPort.sourceMixerFci;
572    loopbackSettings.resolution = handle->settings.bitsPerSample > 24 ? 24 : handle->settings.bitsPerSample;
573    errCode = BAPE_LoopbackGroup_P_SetSettings(handle->loopbackGroup, &loopbackSettings);
574    if ( errCode )
575    {
576        errCode = BERR_TRACE(errCode);
577        goto err_loopback_settings;
578    }
579
580    /* Install interrupt handlers */
581    if ( handle->interrupts.watermark.pCallback_isr )
582    {
583        errCode = BAPE_DfifoGroup_P_SetFullmarkInterrupt(handle->dfifoGroup,
584                                                         handle->interrupts.watermark.pCallback_isr,
585                                                         handle->interrupts.watermark.pParam1,
586                                                         handle->interrupts.watermark.param2);
587        if ( errCode )
588        {
589            errCode = BERR_TRACE(errCode);
590            goto err_fullmark;
591        }
592    }
593    if ( handle->interrupts.overflow.pCallback_isr )
594    {
595        errCode = BAPE_DfifoGroup_P_SetOverflowInterrupt(handle->dfifoGroup,
596                                                         handle->interrupts.overflow.pCallback_isr,
597                                                         handle->interrupts.overflow.pParam1,
598                                                         handle->interrupts.overflow.param2);
599        if ( errCode )
600        {
601            errCode = BERR_TRACE(errCode);
602            goto err_overflow;
603        }
604    }
605
606    /* Enable DFIFO */
607    errCode = BAPE_DfifoGroup_P_Start(handle->dfifoGroup, false);
608    if ( errCode )
609    {
610        errCode = BERR_TRACE(errCode);
611        goto err_dfifo_start;
612    }
613
614    /* Enable Loopback */
615    errCode = BAPE_LoopbackGroup_P_Start(handle->loopbackGroup);
616    if ( errCode )
617    {
618        errCode = BERR_TRACE(errCode);
619        goto err_loopback_start;
620    }
621
622    /* Done */
623    handle->enabled = true;
624    return BERR_SUCCESS;
625
626err_loopback_start:
627    BAPE_DfifoGroup_P_Stop(handle->dfifoGroup);
628err_dfifo_start:
629    BAPE_DfifoGroup_P_SetOverflowInterrupt(handle->dfifoGroup, NULL, NULL, 0);
630err_overflow:
631    BAPE_DfifoGroup_P_SetFullmarkInterrupt(handle->dfifoGroup, NULL, NULL, 0);
632err_fullmark:
633err_loopback_settings:
634err_dfifo_settings:
635    BAPE_DfifoGroup_P_Destroy(handle->dfifoGroup);
636    handle->dfifoGroup = NULL;
637err_dfifo_alloc:
638    BAPE_LoopbackGroup_P_Destroy(handle->loopbackGroup);
639    handle->loopbackGroup = NULL;
640err_loopback_alloc:
641    return errCode;
642}
643
644static void BAPE_OutputCapture_P_Disable(BAPE_OutputPort output)
645{
646    BAPE_OutputCaptureHandle handle;
647
648    BDBG_OBJECT_ASSERT(output, BAPE_OutputPort);
649
650    handle = output->pHandle;
651    BDBG_OBJECT_ASSERT(handle, BAPE_OutputCapture);
652
653    if ( handle->loopbackGroup )
654    {
655        /* Disable Loopback */
656        BAPE_LoopbackGroup_P_Stop(handle->loopbackGroup);
657
658        if ( handle->dfifoGroup )
659        {
660            /* Disable DFIFO */
661            BAPE_DfifoGroup_P_Stop(handle->dfifoGroup);
662
663            /* Clear interrupts */
664            BAPE_DfifoGroup_P_SetFullmarkInterrupt(handle->dfifoGroup, NULL, NULL, 0);
665            BAPE_DfifoGroup_P_SetOverflowInterrupt(handle->dfifoGroup, NULL, NULL, 0);
666
667            BAPE_DfifoGroup_P_Destroy(handle->dfifoGroup);
668            handle->dfifoGroup = NULL;
669        }
670
671        BAPE_LoopbackGroup_P_Destroy(handle->loopbackGroup);
672        handle->loopbackGroup = NULL;
673    }
674
675    handle->enabled = false;
676}
677
678#if BAPE_CHIP_MAX_FS > 0
679static void BAPE_OutputCapture_P_SetFs(BAPE_OutputPort output, unsigned fsNum)
680{
681    BAPE_OutputCaptureHandle handle;
682    BAPE_LoopbackGroupSettings loopbackSettings;
683    BERR_Code errCode;
684
685    BDBG_OBJECT_ASSERT(output, BAPE_OutputPort);
686
687    handle = output->pHandle;
688    BDBG_OBJECT_ASSERT(handle, BAPE_OutputCapture);
689
690    handle->fs = fsNum;   
691
692    /* Update timing source in loopback */
693    if ( handle->loopbackGroup )
694    {
695        BAPE_LoopbackGroup_P_GetSettings(handle->loopbackGroup, &loopbackSettings);
696        loopbackSettings.fs = fsNum;
697        errCode = BAPE_LoopbackGroup_P_SetSettings(handle->loopbackGroup, &loopbackSettings);
698        BDBG_ASSERT(errCode == BERR_SUCCESS);
699    }
700}
701#else
702static void BAPE_OutputCapture_P_SetMclk_isr(BAPE_OutputPort output, BAPE_MclkSource mclkSource, unsigned pllChannel, unsigned mclkFreqToFsRatio)
703{
704    BAPE_OutputCaptureHandle handle;
705    BAPE_LoopbackGroupSettings loopbackSettings;
706    BERR_Code errCode;
707
708    BDBG_OBJECT_ASSERT(output, BAPE_OutputPort);
709
710    handle = output->pHandle;
711    BDBG_OBJECT_ASSERT(handle, BAPE_OutputCapture);
712
713    BDBG_ASSERT(false == handle->enabled);
714
715    if ( handle->loopbackGroup )
716    {
717        /* Set Input Parameters */
718        BAPE_LoopbackGroup_P_GetSettings(handle->loopbackGroup, &loopbackSettings);
719        loopbackSettings.mclkSource = mclkSource;
720        loopbackSettings.pllChannel = pllChannel;
721        loopbackSettings.mclkFreqToFsRatio = mclkFreqToFsRatio;
722        errCode = BAPE_LoopbackGroup_P_SetSettings(handle->loopbackGroup, &loopbackSettings);
723        BDBG_ASSERT(BERR_SUCCESS == errCode);
724    }
725
726    handle->mclkSource = mclkSource;
727    handle->pllChannel = pllChannel;
728    handle->mclkFreqToFsRatio = mclkFreqToFsRatio;
729}
730#endif
731
732static void BAPE_OutputCapture_P_SetTimingParams_isr(BAPE_OutputPort output, unsigned sampleRate, BAVC_Timebase timebase)
733{
734    BAPE_OutputCaptureHandle handle;
735
736    BDBG_OBJECT_ASSERT(output, BAPE_OutputPort);
737
738    handle = output->pHandle;
739    BDBG_OBJECT_ASSERT(handle, BAPE_OutputCapture);
740    BSTD_UNUSED(timebase);
741
742    if ( handle->sampleRate != sampleRate )
743    {
744        handle->sampleRate = sampleRate;
745        if ( handle->interrupts.sampleRate.pCallback_isr )
746        {
747            handle->interrupts.sampleRate.pCallback_isr(handle->interrupts.sampleRate.pParam1,
748                                                        handle->interrupts.sampleRate.param2,
749                                                        sampleRate);
750        }
751    }
752}
753
754static void BAPE_OutputCapture_P_ClearInterrupts_isr(BAPE_OutputCaptureHandle handle)
755{
756    BDBG_OBJECT_ASSERT(handle, BAPE_OutputCapture);
757
758    if ( handle->enabled )
759    {
760        BDBG_ASSERT(NULL != handle->dfifoGroup);
761        BAPE_DfifoGroup_P_RearmFullmarkInterrupt_isr(handle->dfifoGroup);
762        BAPE_DfifoGroup_P_RearmOverflowInterrupt_isr(handle->dfifoGroup);
763    }
764}
765
766
Note: See TracBrowser for help on using the repository browser.