source: svn/newcon3bcm2_21bu/magnum/portinginterface/ape/7552/bape.c @ 45

Last change on this file since 45 was 45, checked in by megakiss, 11 years ago
  • Property svn:executable set to *
File size: 40.2 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.c $
11 * $brcm_Revision: Hydra_Software_Devel/34 $
12 * $brcm_Date: 3/7/12 4:35p $
13 *
14 * Module Description: Audio PI Device Level Interface
15 *
16 * Revision History:
17 *
18 * $brcm_Log: /magnum/portinginterface/ape/7422/bape.c $
19 *
20 * Hydra_Software_Devel/34   3/7/12 4:35p jgarrett
21 * SW7435-24: Adding DSP index for decode and dsp mixer
22 *
23 * Hydra_Software_Devel/33   11/14/11 3:42p gskerl
24 * SW7429-18: Merging 7429 changes back to main branch.
25 *
26 * Hydra_Software_Devel/SW7429-18/3   10/26/11 12:44p jgarrett
27 * SW7429-18: Merging latest changes from main branch
28 *
29 * Hydra_Software_Devel/SW7429-18/2   10/25/11 5:34p jgarrett
30 * SW7429-18: Adding 7429 reset logic
31 *
32 * Hydra_Software_Devel/SW7429-18/1   10/21/11 6:29p jgarrett
33 * SW7429-18: Initial compileable version for 7429
34 *
35 * Hydra_Software_Devel/32   10/26/11 5:54p gskerl
36 * SW7231-129: Added BAPE_P_StandbyFmmHw() to get APE hardware ready to go
37 * to Standby mode.
38 *
39 * Hydra_Software_Devel/31   10/25/11 1:32p gskerl
40 * SW7231-129: Added power standby/resume support for NCOs.
41 *
42 * Hydra_Software_Devel/30   10/24/11 2:46p gskerl
43 * SW7231-129: Added power standby/resume support for PLLs, SPDIF inputs,
44 * and MAI inputs.
45 *
46 * Hydra_Software_Devel/29   10/6/11 2:39p gskerl
47 * SW7231-129: Added calls to BAPE_Xxxxx_ResumeFromStandby().
48 *
49 * Hydra_Software_Devel/28   10/2/11 2:43p gskerl
50 * SW7231-129: Added power standby/resume support for AudioReturnChannel
51 * outputs
52 *
53 * Hydra_Software_Devel/27   9/30/11 11:53a gskerl
54 * SW7231-129: Added power standby/resume support for LoopbackGroup,
55 * DummysinkGroups, and DummyOutputs
56 *
57 * Hydra_Software_Devel/26   9/28/11 5:39p gskerl
58 * SW7231-129: In BAPE_P_ResumeFmmHw(), added call to
59 * BAPE_I2sOutput_P_ResumeFromStandby()
60 *
61 * Hydra_Software_Devel/25   9/26/11 2:43p gskerl
62 * SW7231-129: For APE's global interrupts... destroy at Suspend, then
63 * recreate at Resume.
64 *
65 * Hydra_Software_Devel/24   9/26/11 10:38a gskerl
66 * SW7231-129: Added AIO reset via SUN_TOP_CTRL_SW_RESET reg (for 35230)
67 *
68 * Hydra_Software_Devel/23   9/23/11 5:23p gskerl
69 * SW7231-129: Added AIO reset via SUN_TOP_CTRL_SW_INIT reg
70 *
71 * Hydra_Software_Devel/22   9/20/11 11:10a gskerl
72 * SW7231-129: Resolved compiler warnings.
73 *
74 * Hydra_Software_Devel/21   9/19/11 5:30p gskerl
75 * SW7231-129: Added support for recovering hardware state after power
76 * standby/resume. Only works for DACs so far.
77 *
78 * Hydra_Software_Devel/20   9/16/11 6:48p gskerl
79 * SW7231-129: Refactored to put hardware and software initialization into
80 * separate functions.
81 *
82 * Hydra_Software_Devel/19   7/8/11 6:38p jgarrett
83 * SWDTV-6760: Adding I2sMultiOutput
84 *
85 * Hydra_Software_Devel/18   6/24/11 4:40p gskerl
86 * SW7231-128: Added BCHP_PWR_RESOURCE_AUD_PLL2 power resource
87 *
88 * Hydra_Software_Devel/17   5/23/11 12:48p gskerl
89 * SW7231-128: Changed tabs to spaces
90 *
91 * Hydra_Software_Devel/16   5/20/11 7:24p gskerl
92 * SW7231-128: Added DAC power control
93 *
94 * Hydra_Software_Devel/15   5/18/11 2:31p gskerl
95 * SW7231-128: Added BCHP_PWR support to APE
96 *
97 * Hydra_Software_Devel/SW7231-128/3   5/16/11 2:29p gmohile
98 * SW7231-128 : Add Power Management Support
99 *
100 * Hydra_Software_Devel/SW7231-128/2   5/13/11 5:14p gmohile
101 * SW7231-128 : Add Standby support
102 *
103 * Hydra_Software_Devel/SW7231-128/1   5/12/11 1:38p gmohile
104 * SW7231-128 : Add power management support
105 *
106 * Hydra_Software_Devel/14   5/3/11 6:59p gskerl
107 * SW7422-354: First attempt at adding support for the audio return
108 * channel
109 *
110 * Hydra_Software_Devel/13   4/16/11 12:15p jgarrett
111 * SW7425-371: Removing tab characters
112 *
113 * Hydra_Software_Devel/12   4/11/11 5:54p jgarrett
114 * SWDTV-6305: Adding ADC/RF Inputs for DTV
115 *
116 * Hydra_Software_Devel/11   4/6/11 1:24a jgarrett
117 * SW35330-35: Merge to main branch
118 *
119 * Hydra_Software_Devel/SW35330-35/1   4/5/11 12:50p jgarrett
120 * SW35330-35: FMM Abstraction refactoring to support DTV
121 *
122 * Hydra_Software_Devel/10   3/21/11 7:08p jgarrett
123 * SW7422-356: Adding MuxOutput
124 *
125 * Hydra_Software_Devel/9   3/11/11 6:02p jgarrett
126 * SW7422-146: Decoder supports external inputs
127 *
128 * Hydra_Software_Devel/8   3/10/11 7:03p jgarrett
129 * SW7422-146: Refactored DFIFO code, added support for input capture from
130 * compressed/multichannel
131 *
132 * Hydra_Software_Devel/7   2/28/11 5:02p jgarrett
133 * SW7422-146: Adding watchdog handling
134 *
135 * Hydra_Software_Devel/6   1/28/11 11:45a jgarrett
136 * SW7422-146: Fixing warning
137 *
138 * Hydra_Software_Devel/5   1/19/11 2:58p jgarrett
139 * SW7422-146: Initial decode/passthrough of ac3
140 *
141 * Hydra_Software_Devel/4   1/13/11 2:26p jgarrett
142 * SW7422-146: Adding 7346 APE support
143 *
144 * Hydra_Software_Devel/3   1/6/11 2:33p jgarrett
145 * SW7422-146: Adding initial input capture API
146 *
147 * Hydra_Software_Devel/2   12/17/10 3:58p jgarrett
148 * SW7422-146: Nexus APE integration on 7422
149 *
150 * Hydra_Software_Devel/1   12/16/10 4:05p jgarrett
151 * SW7422-146: Initial compilable APE for 7422
152 *
153 ***************************************************************************/
154
155#include "bstd.h"
156#include "bkni.h"
157#include "bape.h"
158#include "bape_priv.h"
159#include "bchp_aud_fmm_bf_ctrl.h"
160#include "bchp_sun_top_ctrl.h"
161#include "bdsp_raaga.h"
162
163#if BCHP_PWR_SUPPORT
164#include "bchp_pwr.h"
165#endif
166
167BDBG_MODULE(bape);
168
169BDBG_OBJECT_ID(BAPE_Device);
170BDBG_OBJECT_ID(BAPE_BufferNode);
171
172static BERR_Code BAPE_P_InitFmmSw(BAPE_Handle handle);
173static BERR_Code BAPE_P_InitFmmHw(BAPE_Handle handle);
174
175void BAPE_GetDefaultSettings(
176    BAPE_Settings *pSettings    /* [out] */
177    )
178{
179    BDBG_ASSERT(NULL != pSettings);
180    BKNI_Memset(pSettings, 0, sizeof(*pSettings));
181    pSettings->maxDspTasks = BAPE_CHIP_MAX_DSP_TASKS;
182    pSettings->rampPcmSamples = true;
183    pSettings->highBitRateEnabled = true;
184    pSettings->maxIndependentDelay = 300;
185    pSettings->maxPcmSampleRate = 48000;
186    pSettings->numCompressedBuffers = BAPE_CHIP_DEFAULT_NUM_COMPRESSED_BUFFERS;
187    pSettings->numPcmBuffers = BAPE_CHIP_DEFAULT_NUM_PCM_BUFFERS;
188}
189
190BERR_Code BAPE_Open(
191    BAPE_Handle *pHandle,   /* [out] returned handle */
192    BCHP_Handle chpHandle,
193    BREG_Handle regHandle,
194    BMEM_Handle memHandle,
195    BINT_Handle intHandle,
196    BTMR_Handle tmrHandle,
197    BDSP_Handle dspHandle,
198    const BAPE_Settings *pSettings  /* NULL will use default settings */
199    )
200{
201    BAPE_Settings defaultSettings;
202    BAPE_Handle handle;
203    BERR_Code errCode;
204    BAPE_BufferNode *pNode;
205    unsigned bufferSize;
206    unsigned i;
207
208    BDBG_ASSERT(NULL != pHandle);
209    BDBG_ASSERT(NULL != chpHandle);
210    BDBG_ASSERT(NULL != regHandle);
211    BDBG_ASSERT(NULL != memHandle);
212    BDBG_ASSERT(NULL != intHandle);
213    BDBG_ASSERT(NULL != tmrHandle);
214   
215    if ( NULL == pSettings )
216    {
217        BAPE_GetDefaultSettings(&defaultSettings);
218        pSettings = &defaultSettings;
219    }
220
221    /* Allocate device structure */
222    handle = BKNI_Malloc(sizeof(BAPE_Device));
223    if ( NULL == handle )
224    {
225        errCode = BERR_TRACE(BERR_OUT_OF_SYSTEM_MEMORY);
226        goto err_handle;
227    }
228    /* Initialize structure */   
229    BKNI_Memset(handle, 0, sizeof(BAPE_Device));
230    BDBG_OBJECT_SET(handle, BAPE_Device);
231    handle->chpHandle = chpHandle;
232    handle->regHandle = regHandle;
233    handle->memHandle = memHandle;
234    handle->intHandle = intHandle;
235    handle->tmrHandle = tmrHandle;
236    handle->dspHandle = dspHandle;
237    handle->settings = *pSettings;
238    BLST_S_INIT(&handle->pcmBufferList);
239    BLST_S_INIT(&handle->compressedBufferList);
240    BLST_S_INIT(&handle->mixerList);
241
242    if ( false == pSettings->rampPcmSamples )
243    {
244        /* Should only be used for test purposes.  */
245        BDBG_WRN(("PCM Sample Ramping is disabled in SRC.  This should only be done for test purposes."));
246    }
247
248#ifdef BCHP_PWR_RESOURCE_AUD_AIO
249    BCHP_PWR_AcquireResource(chpHandle, BCHP_PWR_RESOURCE_AUD_AIO);
250#endif
251#ifdef BCHP_PWR_RESOURCE_AUD_PLL0
252    BCHP_PWR_AcquireResource(chpHandle, BCHP_PWR_RESOURCE_AUD_PLL0);
253#endif
254#ifdef BCHP_PWR_RESOURCE_AUD_PLL1
255    BCHP_PWR_AcquireResource(chpHandle, BCHP_PWR_RESOURCE_AUD_PLL1);
256#endif
257#ifdef BCHP_PWR_RESOURCE_AUD_PLL2
258    BCHP_PWR_AcquireResource(chpHandle, BCHP_PWR_RESOURCE_AUD_PLL2);
259#endif
260
261    errCode = BAPE_P_InitFmmSw(handle);
262    if ( errCode )
263    {
264        goto err_fmm;
265    }
266
267    errCode = BAPE_P_InitFmmHw(handle);
268    if ( errCode )
269    {
270        goto err_fmm;
271    }
272
273    errCode = BAPE_P_InitInterrupts(handle);
274    if ( errCode )
275    {
276        goto err_interrupt;
277    }
278
279    bufferSize = pSettings->maxIndependentDelay > 0 ? 2*BDSP_AF_P_DELAY_RBUF_SIZE : 2*BDSP_AF_P_NON_DELAY_RBUF_SIZE;/*((BAPE_CHIP_MAX_PATH_DELAY + pSettings->maxIndependentDelay) * (pSettings->maxPcmSampleRate/1000)) * BAPE_CHIP_BYTES_PER_PCM_SAMPLE_PAIR;*/
280    handle->pcmBufferSize = bufferSize;
281    BDBG_MSG(("Allocating %u PCM buffers (size %u bytes)", pSettings->numPcmBuffers, bufferSize));
282    for ( i = 0; i < pSettings->numPcmBuffers; i++ )
283    {
284        pNode = BKNI_Malloc(sizeof(BAPE_BufferNode));
285        if ( NULL == pNode )
286        {
287            errCode = BERR_TRACE(BERR_OUT_OF_SYSTEM_MEMORY);
288            goto err_buffer;
289        }
290        pNode->pMemory = BMEM_AllocAligned(memHandle, bufferSize, 8, 0);
291        if ( NULL == pNode->pMemory )
292        {
293            errCode = BERR_TRACE(BERR_OUT_OF_DEVICE_MEMORY);
294            BKNI_Free(pNode);
295            goto err_buffer;
296        }
297        BMEM_ConvertAddressToOffset(memHandle, pNode->pMemory, &pNode->offset);
298        pNode->bufferSize = bufferSize;
299        pNode->type = BAPE_BufferType_ePcm;
300        BDBG_OBJECT_SET(pNode, BAPE_BufferNode);
301        BLST_S_INSERT_HEAD(&handle->pcmBufferList, pNode, node);
302    }
303
304    if ( pSettings->highBitRateEnabled )
305    {
306        bufferSize *= 2;    /* HBR = 4x default sample rate, but samples are 1/2 size of PCM */
307    }
308    handle->compressedBufferSize = bufferSize;
309    BDBG_MSG(("Allocating %u compressed buffers (size %u bytes)", pSettings->numCompressedBuffers, bufferSize));
310    for ( i = 0; i < pSettings->numCompressedBuffers; i++ )
311    {
312        pNode = BKNI_Malloc(sizeof(BAPE_BufferNode));
313        if ( NULL == pNode )
314        {
315            errCode = BERR_TRACE(BERR_OUT_OF_SYSTEM_MEMORY);
316            goto err_buffer;
317        }
318        pNode->pMemory = BMEM_AllocAligned(memHandle, bufferSize, 8, 0);
319        if ( NULL == pNode->pMemory )
320        {
321            errCode = BERR_TRACE(BERR_OUT_OF_DEVICE_MEMORY);
322            BKNI_Free(pNode);
323            goto err_buffer;
324        }
325        pNode->bufferSize = bufferSize;       
326        pNode->type = BAPE_BufferType_eCompressed;
327        BDBG_OBJECT_SET(pNode, BAPE_BufferNode);
328        BLST_S_INSERT_HEAD(&handle->compressedBufferList, pNode, node);
329        errCode = BMEM_ConvertAddressToOffset(memHandle, pNode->pMemory, &pNode->offset);
330        if ( errCode )
331        {
332            (void)BERR_TRACE(errCode);
333            goto err_buffer;
334        }
335    }
336
337    if ( handle->dspHandle )
338    {
339        BDSP_ContextCreateSettings dspContextSettings;
340        BDSP_Status dspStatus;
341
342        /* Determine num dsps */
343        BDSP_GetStatus(handle->dspHandle, &dspStatus);
344        handle->numDsps = dspStatus.numDsp;
345
346        /* Create DSP Context */
347        BDSP_Context_GetDefaultCreateSettings(handle->dspHandle, BDSP_ContextType_eAudio, &dspContextSettings);
348        dspContextSettings.maxTasks = pSettings->maxDspTasks;
349        errCode = BDSP_Context_Create(handle->dspHandle, &dspContextSettings, &handle->dspContext);
350        if ( errCode )
351        {
352            (void)BERR_TRACE(errCode);
353            goto err_context;
354        }
355    }
356   
357    handle->bStandby = false;
358
359    /* Success */
360    *pHandle = handle;
361
362    return BERR_SUCCESS;
363
364err_context:
365err_buffer:
366    /* Remove and free all pcm and compressed buffers and nodes */
367    while ( (pNode = BLST_S_FIRST(&handle->pcmBufferList)) )
368    {
369        BLST_S_REMOVE_HEAD(&handle->pcmBufferList, node);
370        BMEM_Free(memHandle, pNode->pMemory);
371        BDBG_OBJECT_DESTROY(pNode, BAPE_BufferNode);
372        BKNI_Free(pNode);
373    }
374    while ( (pNode = BLST_S_FIRST(&handle->compressedBufferList)) )
375    {
376        BLST_S_REMOVE_HEAD(&handle->compressedBufferList, node);
377        BMEM_Free(memHandle, pNode->pMemory);
378        BDBG_OBJECT_DESTROY(pNode, BAPE_BufferNode);
379        BKNI_Free(pNode);
380    }
381    BAPE_P_UninitInterrupts(handle);
382err_interrupt:   
383err_fmm:
384    BDBG_OBJECT_DESTROY(handle, BAPE_Device);
385    BKNI_Free(handle);
386err_handle:
387    *pHandle = NULL;
388
389#ifdef BCHP_PWR_RESOURCE_AUD_PLL0
390    BCHP_PWR_ReleaseResource(chpHandle, BCHP_PWR_RESOURCE_AUD_PLL0);
391#endif
392#ifdef BCHP_PWR_RESOURCE_AUD_PLL1
393    BCHP_PWR_ReleaseResource(chpHandle, BCHP_PWR_RESOURCE_AUD_PLL1);
394#endif
395#ifdef BCHP_PWR_RESOURCE_AUD_PLL2
396    BCHP_PWR_ReleaseResource(chpHandle, BCHP_PWR_RESOURCE_AUD_PLL2);
397#endif
398#ifdef BCHP_PWR_RESOURCE_AUD_AIO
399    BCHP_PWR_ReleaseResource(chpHandle, BCHP_PWR_RESOURCE_AUD_AIO);
400#endif
401    return errCode;
402}
403
404void BAPE_Close(
405    BAPE_Handle handle
406    )
407{
408    unsigned i=0;
409    BAPE_BufferNode *pNode;
410    BAPE_MixerHandle mixer;
411    BAPE_MuxOutputHandle muxOutput;
412
413    /* Stop all potential mixer inputs first */
414#if BAPE_CHIP_MAX_DECODERS > 0
415    for ( i = 0; i < BAPE_CHIP_MAX_DECODERS; i++ )
416    {
417        if ( handle->decoders[i] )
418        {
419            BDBG_MSG(("Stopping decoder %p (%d)", handle->decoders[i], i));
420            BAPE_Decoder_Stop(handle->decoders[i]);
421        }
422    }
423#endif
424#if BAPE_CHIP_MAX_INPUT_CAPTURES > 0
425    for ( i = 0; i < BAPE_CHIP_MAX_INPUT_CAPTURES; i++ )
426    {
427        if ( handle->inputCaptures[i] )
428        {
429            BDBG_MSG(("Stopping input capture %p (%d)", handle->inputCaptures[i], i));
430            BAPE_InputCapture_Stop(handle->inputCaptures[i]);
431        }
432    }
433#endif
434#if BAPE_CHIP_MAX_PLAYBACKS > 0
435    for ( i = 0; i < BAPE_CHIP_MAX_PLAYBACKS; i++ )
436    {
437        if ( handle->playbacks[i] )
438        {
439            BDBG_MSG(("Stopping playback %p (%d)", handle->playbacks[i], i));
440            BAPE_Playback_Stop(handle->playbacks[i]);
441        }
442    }
443#endif
444
445    /* Close all mixers next */
446    while ( (mixer=BLST_S_FIRST(&handle->mixerList)) )
447    {
448        BDBG_MSG(("Destroying mixer %p)", mixer));
449        BAPE_Mixer_Destroy(mixer);
450    }
451
452    /* Close all MuxOutputs */
453    while ( (muxOutput=BLST_S_FIRST(&handle->muxOutputList)) )
454    {
455        BDBG_MSG(("Destroying muxOutput %p", muxOutput));
456        BAPE_MuxOutput_Destroy(muxOutput);
457    }
458
459    /* Close all inputs */
460#if BAPE_CHIP_MAX_DECODERS > 0
461    for ( i = 0; i < BAPE_CHIP_MAX_DECODERS; i++ )
462    {
463        if ( handle->decoders[i] )
464        {
465            BDBG_MSG(("Closing decoder %p (%d)", handle->decoders[i], i));
466            BAPE_Decoder_Close(handle->decoders[i]);
467        }
468    }
469#endif
470#if BAPE_CHIP_MAX_INPUT_CAPTURES > 0
471    for ( i = 0; i < BAPE_CHIP_MAX_INPUT_CAPTURES; i++ )
472    {
473        if ( handle->inputCaptures[i] )
474        {
475            BDBG_MSG(("Closing input capture %p (%d)", handle->inputCaptures[i], i));
476            BAPE_InputCapture_Close(handle->inputCaptures[i]);
477        }
478    }
479#endif
480#if BAPE_CHIP_MAX_PLAYBACKS > 0
481    for ( i = 0; i < BAPE_CHIP_MAX_PLAYBACKS; i++ )
482    {
483        if ( handle->playbacks[i] )
484        {
485            BDBG_MSG(("Closing playback %p (%d)", handle->playbacks[i], i));
486            BAPE_Playback_Close(handle->playbacks[i]);
487        }
488    }
489#endif
490
491    /* Close all input and output ports */
492#if BAPE_CHIP_MAX_DACS > 0
493    for ( i = 0; i < BAPE_CHIP_MAX_DACS; i++ )
494    {
495        if ( handle->dacs[i] )
496        {
497            BDBG_MSG(("Closing DAC %p (%d)", handle->dacs[i], i));
498            BAPE_Dac_Close(handle->dacs[i]);
499        }
500    }
501#endif
502#if BAPE_CHIP_MAX_I2S_OUTPUTS > 0
503    for ( i = 0; i < BAPE_CHIP_MAX_I2S_OUTPUTS; i++ )
504    {
505        if ( handle->i2sOutputs[i] )
506        {
507            BDBG_MSG(("Closing I2S Output %p (%d)", handle->i2sOutputs[i], i));
508            BAPE_I2sOutput_Close(handle->i2sOutputs[i]);
509        }
510    }
511#endif
512#if BAPE_CHIP_MAX_I2S_MULTI_OUTPUTS > 0
513    for ( i = 0; i < BAPE_CHIP_MAX_I2S_MULTI_OUTPUTS; i++ )
514    {
515        if ( handle->i2sMultiOutputs[i] )
516        {
517            BDBG_MSG(("Closing I2S Multi Output %p (%d)", handle->i2sMultiOutputs[i], i));
518            BAPE_I2sMultiOutput_Close(handle->i2sMultiOutputs[i]);
519        }
520    }
521#endif
522#if BAPE_CHIP_MAX_SPDIF_OUTPUTS > 0
523    for ( i = 0; i < BAPE_CHIP_MAX_SPDIF_OUTPUTS; i++ )
524    {
525        if ( handle->spdifOutputs[i] )
526        {
527            BDBG_MSG(("Closing SPDIF Output %p (%d)", handle->spdifOutputs[i], i));
528            BAPE_SpdifOutput_Close(handle->spdifOutputs[i]);
529        }
530    }
531#endif
532#if BAPE_CHIP_MAX_MAI_OUTPUTS > 0
533    for ( i = 0; i < BAPE_CHIP_MAX_MAI_OUTPUTS; i++ )
534    {
535        if ( handle->maiOutputs[i] )
536        {
537            BDBG_MSG(("Closing MAI Output %p (%d)", handle->maiOutputs[i], i));
538            BAPE_MaiOutput_Close(handle->maiOutputs[i]);
539        }
540    }
541#endif
542#if BAPE_CHIP_MAX_OUTPUT_CAPTURES > 0
543    for ( i = 0; i < BAPE_CHIP_MAX_OUTPUT_CAPTURES; i++ )
544    {
545        if ( handle->outputCaptures[i] )
546        {
547            BDBG_MSG(("Closing Output Capture %p (%d)", handle->outputCaptures[i], i));
548            BAPE_OutputCapture_Close(handle->outputCaptures[i]);
549        }
550    }
551#endif
552#if BAPE_CHIP_MAX_DUMMYSINKS > 0
553    for ( i = 0; i < BAPE_CHIP_MAX_DUMMYSINKS; i++ )
554    {
555        if ( handle->dummyOutputs[i] )
556        {
557            BDBG_MSG(("Closing Dummy Output %p (%d)", handle->dummyOutputs[i], i));
558            BAPE_DummyOutput_Close(handle->dummyOutputs[i]);
559        }
560    }
561#endif
562#if BAPE_CHIP_MAX_I2S_INPUTS > 0
563    for ( i = 0; i < BAPE_CHIP_MAX_I2S_INPUTS; i++ )
564    {
565        if ( handle->i2sInputs[i] )
566        {
567            BDBG_MSG(("Closing I2S Input %p (%d)", handle->i2sInputs[i], i));
568            BAPE_I2sInput_Close(handle->i2sInputs[i]);
569        }
570    }
571#endif
572#if BAPE_CHIP_MAX_SPDIF_INPUTS > 0
573    for ( i = 0; i < BAPE_CHIP_MAX_SPDIF_INPUTS; i++ )
574    {
575        if ( handle->spdifInputs[i] )
576        {
577            BDBG_MSG(("Closing SPDIF Input %p (%d)", handle->spdifInputs[i], i));
578            BAPE_SpdifInput_Close(handle->spdifInputs[i]);
579        }
580    }
581#endif
582#if BAPE_CHIP_MAX_MAI_INPUTS > 0
583    for ( i = 0; i < BAPE_CHIP_MAX_MAI_INPUTS; i++ )
584    {
585        if ( handle->maiInputs[i] )
586        {
587            BDBG_MSG(("Closing MAI Input %p (%d)", handle->maiInputs[i], i));
588            BAPE_MaiInput_Close(handle->maiInputs[i]);
589        }
590    }
591#endif
592#if BAPE_CHIP_MAX_AUDIO_RETURN_CHANNELS > 0
593    for ( i = 0; i < BAPE_CHIP_MAX_AUDIO_RETURN_CHANNELS; i++ )
594    {
595        if ( handle->audioReturnChannels[i] )
596        {
597            BDBG_MSG(("Closing Audio Return Channel %p (%d)", handle->audioReturnChannels[i], i));
598            BAPE_AudioReturnChannel_Close(handle->audioReturnChannels[i]);
599        }
600    }
601#endif
602#if BAPE_CHIP_MAX_RFMODS > 0
603    for ( i = 0; i < BAPE_CHIP_MAX_RFMODS; i++ )
604    {
605        if ( handle->rfmods[i] )
606        {
607            BDBG_MSG(("Closing RFMOD %p (%d)", handle->rfmods[i], i));
608            BAPE_RfMod_Close(handle->rfmods[i]);
609        }
610    }
611#endif
612#if BAPE_CHIP_MAX_ADC_INPUTS > 0
613    for ( i = 0; i < BAPE_CHIP_MAX_ADC_INPUTS; i++ )
614    {
615        if ( handle->adcInputs[i] )
616        {
617            BDBG_MSG(("Closing ADC Input %p (%d)", handle->adcInputs[i], i));
618            BAPE_AdcInput_Close(handle->adcInputs[i]);
619        }
620    }
621#endif
622
623    if ( handle->dspContext )
624    {
625        BDSP_Context_Destroy(handle->dspContext);
626        handle->dspContext = NULL;
627    }
628
629    /* Remove and free all pcm and compressed buffers and nodes */
630    while ( (pNode = BLST_S_FIRST(&handle->pcmBufferList)) )
631    {
632        BLST_S_REMOVE_HEAD(&handle->pcmBufferList, node);
633        BMEM_Free(handle->memHandle, pNode->pMemory);
634        BDBG_OBJECT_DESTROY(pNode, BAPE_BufferNode);
635        BKNI_Free(pNode);
636    }
637    while ( (pNode = BLST_S_FIRST(&handle->compressedBufferList)) )
638    {
639        BLST_S_REMOVE_HEAD(&handle->compressedBufferList, node);
640        BMEM_Free(handle->memHandle, pNode->pMemory);
641        BDBG_OBJECT_DESTROY(pNode, BAPE_BufferNode);
642        BKNI_Free(pNode);
643    }
644
645    BAPE_P_UninitIopSw(handle);
646    BAPE_P_UninitSrcSw(handle);
647    BAPE_P_UninitDpSw(handle);
648    BAPE_P_UninitBfSw(handle);
649    BAPE_P_UninitInterrupts(handle);
650
651#ifdef BCHP_PWR_RESOURCE_AUD_PLL0
652    BCHP_PWR_ReleaseResource(handle->chpHandle, BCHP_PWR_RESOURCE_AUD_PLL0);
653#endif
654#ifdef BCHP_PWR_RESOURCE_AUD_PLL1
655    BCHP_PWR_ReleaseResource(handle->chpHandle, BCHP_PWR_RESOURCE_AUD_PLL1);
656#endif
657#ifdef BCHP_PWR_RESOURCE_AUD_PLL2
658    BCHP_PWR_ReleaseResource(handle->chpHandle, BCHP_PWR_RESOURCE_AUD_PLL2);
659#endif
660#ifdef BCHP_PWR_RESOURCE_AUD_AIO
661    BCHP_PWR_ReleaseResource(handle->chpHandle, BCHP_PWR_RESOURCE_AUD_AIO);
662#endif
663
664    BDBG_OBJECT_DESTROY(handle, BAPE_Device);
665    BKNI_Free(handle);
666}
667
668unsigned BAPE_P_GetSampleRateCstatCode(unsigned sampleRate)
669{
670    switch ( sampleRate )
671    {
672    case 32000:      /* 32K Sample rate */
673        return 0x3;
674    case 44100:    /* 44.1K Sample rate */
675        return 0x0;
676    case 48000:      /* 48K Sample rate */
677        return 0x2;
678    case 96000:      /* 96K Sample rate */
679        return 0xc;
680    case 22050:   /* 22.05K Sample rate */
681        return 0x4;
682    case 24000:      /* 24K Sample rate */
683        return 0x6;
684    case 88200:    /* 88.2K Sample rate */
685        return 0x8;
686    case 176400:   /* 176.4K Sample rate */
687        return 0xc;
688    case 192000:     /* 192K Sample rate */
689        return 0xe;
690    default:
691        return 0x8; /* not indicated */
692    }
693}
694
695/**************************************************************************/
696
697static BERR_Code BAPE_P_InitFmmSw(BAPE_Handle handle)
698{
699    BERR_Code errCode;
700
701    BDBG_OBJECT_ASSERT(handle, BAPE_Device);
702
703    errCode = BAPE_P_InitBfSw(handle);
704    if ( errCode )
705    {
706        (void)BERR_TRACE(errCode);
707        goto err_init_bf;
708    }
709
710    errCode = BAPE_P_InitDpSw(handle);
711    if ( errCode )
712    {
713        (void)BERR_TRACE(errCode);
714        goto err_init_dp;
715    }
716
717    BDBG_MSG(("Initializing SRC registers"));
718    errCode = BAPE_P_InitSrcSw(handle);
719    if ( errCode )
720    {
721        (void)BERR_TRACE(errCode);
722        goto err_init_src;
723    }
724
725    errCode = BAPE_P_InitIopSw(handle);
726    if ( errCode )
727    {
728        (void)BERR_TRACE(errCode);
729        goto err_init_iop;
730    }
731
732    return BERR_SUCCESS;
733
734err_init_iop:
735    BAPE_P_UninitSrcSw(handle);
736err_init_src:
737    BAPE_P_UninitDpSw(handle);
738err_init_dp:
739    BAPE_P_UninitBfSw(handle);
740err_init_bf:
741    return BERR_TRACE(errCode);
742}
743
744
745static BERR_Code BAPE_P_InitFmmHw(BAPE_Handle handle)
746{
747    BREG_Handle regHandle;
748    uint32_t regVal;
749    BERR_Code errCode;
750
751    BDBG_OBJECT_ASSERT(handle, BAPE_Device);
752
753    regHandle = handle->regHandle;
754
755    #ifdef BCHP_SUN_TOP_CTRL_SW_RESET
756        /* Note, older SW_RESET registers DO need read-modify-write (atomic update) */
757        BREG_AtomicUpdate32_isr(regHandle, BCHP_SUN_TOP_CTRL_SW_RESET, 
758                0,                                                  /* Clear these bits */
759                BCHP_MASK( SUN_TOP_CTRL_SW_RESET, aio_sw_reset));   /* Set these bits   */
760
761        BREG_AtomicUpdate32_isr(regHandle, BCHP_SUN_TOP_CTRL_SW_RESET,
762                BCHP_MASK( SUN_TOP_CTRL_SW_RESET, aio_sw_reset),    /* Clear these bits */
763                0);                                                 /* Set these bits   */
764    #else
765        /* Note, newer SW_INIT set/clear registers DON'T need read-modify-write. */
766        BREG_Write32(regHandle, BCHP_SUN_TOP_CTRL_SW_INIT_0_SET,
767              BCHP_FIELD_DATA( SUN_TOP_CTRL_SW_INIT_0_SET, aio_sw_init, 1 ));
768
769        /* Now clear the reset. */
770        BREG_Write32(regHandle, BCHP_SUN_TOP_CTRL_SW_INIT_0_CLEAR,
771              BCHP_FIELD_DATA( SUN_TOP_CTRL_SW_INIT_0_CLEAR, aio_sw_init, 1 ));
772    #endif
773
774
775    BDBG_MSG(("Resetting FMM"));
776#ifdef BCHP_AUD_FMM_MISC_RESET
777    /* Assert toplevel reset */
778    BREG_Write32(regHandle, BCHP_AUD_FMM_MISC_RESET, 0);
779    regVal = BREG_Read32(regHandle, BCHP_AUD_FMM_MISC_RESET);
780    regVal |= 
781            (BCHP_FIELD_ENUM (AUD_FMM_MISC_RESET, RESET_TOP_LOGIC_B, Inactive))
782    #ifdef BCHP_AUD_FMM_MISC_RESET_RESET_SPDIFRX_LOGIC_B_Inactive
783          | (BCHP_FIELD_ENUM (AUD_FMM_MISC_RESET, RESET_HDMIRX_LOGIC_B, Inactive))
784          | (BCHP_FIELD_ENUM (AUD_FMM_MISC_RESET, RESET_HDMIRX_REGS_B, Inactive))
785          | (BCHP_FIELD_ENUM (AUD_FMM_MISC_RESET, RESET_SPDIFRX_LOGIC_B, Inactive))
786          | (BCHP_FIELD_ENUM (AUD_FMM_MISC_RESET, RESET_SPDIFRX_REGS_B, Inactive))     
787    #else 
788        #ifdef BCHP_AUD_FMM_MISC_RESET_RESET_SPDIFRX_0_LOGIC_B_Inactive
789          | (BCHP_FIELD_ENUM (AUD_FMM_MISC_RESET, RESET_SPDIFRX_0_LOGIC_B, Inactive))
790          | (BCHP_FIELD_ENUM (AUD_FMM_MISC_RESET, RESET_SPDIFRX_0_REGS_B, Inactive)) 
791          | (BCHP_FIELD_ENUM (AUD_FMM_MISC_RESET, RESET_SPDIFRX_1_LOGIC_B, Inactive))
792          | (BCHP_FIELD_ENUM (AUD_FMM_MISC_RESET, RESET_SPDIFRX_1_REGS_B, Inactive))
793        #endif
794    #endif
795
796          | (BCHP_FIELD_ENUM (AUD_FMM_MISC_RESET, RESET_OP_LOGIC_B, Inactive))
797          | (BCHP_FIELD_ENUM (AUD_FMM_MISC_RESET, RESET_OP_REGS_B, Inactive))
798          | (BCHP_FIELD_ENUM (AUD_FMM_MISC_RESET, RESET_MS_PROC_B, Inactive))
799          | (BCHP_FIELD_ENUM (AUD_FMM_MISC_RESET, RESET_MS_LOGIC_B, Inactive))
800          | (BCHP_FIELD_ENUM (AUD_FMM_MISC_RESET, RESET_MS_REGS_B, Inactive))
801          | (BCHP_FIELD_ENUM (AUD_FMM_MISC_RESET, RESET_SRC_LOGIC_B, Inactive))
802          | (BCHP_FIELD_ENUM (AUD_FMM_MISC_RESET, RESET_SRC_REGS_B, Inactive))
803    #ifdef BCHP_AUD_FMM_MISC_RESET_RESET_ADC_CIC_REGS_B_Inactive
804          | (BCHP_FIELD_ENUM (AUD_FMM_MISC_RESET, RESET_ADC_CIC_REGS_B, Inactive))
805    #endif     
806          | (BCHP_FIELD_ENUM (AUD_FMM_MISC_RESET, RESET_DP_LOGIC_B, Inactive))
807          | (BCHP_FIELD_ENUM (AUD_FMM_MISC_RESET, RESET_DP_REGS_B, Inactive))
808          | (BCHP_FIELD_ENUM (AUD_FMM_MISC_RESET, RESET_BF_LOGIC_B, Inactive))
809          | (BCHP_FIELD_ENUM (AUD_FMM_MISC_RESET, RESET_BF_REGS_B, Inactive))
810          | (BCHP_FIELD_ENUM (AUD_FMM_MISC_RESET, RESET_TOP_LOGIC_B, Inactive))
811          | (BCHP_FIELD_ENUM (AUD_FMM_MISC_RESET, RESET_OP_LOGIC_B, Inactive))
812          | (BCHP_FIELD_ENUM (AUD_FMM_MISC_RESET, RESET_OP_REGS_B, Inactive))
813          | (BCHP_FIELD_ENUM (AUD_FMM_MISC_RESET, RESET_MS_PROC_B, Inactive))
814          | (BCHP_FIELD_ENUM (AUD_FMM_MISC_RESET, RESET_MS_LOGIC_B, Inactive))
815          | (BCHP_FIELD_ENUM (AUD_FMM_MISC_RESET, RESET_MS_REGS_B, Inactive))
816          | (BCHP_FIELD_ENUM (AUD_FMM_MISC_RESET, RESET_SRC_LOGIC_B, Inactive))
817          | (BCHP_FIELD_ENUM (AUD_FMM_MISC_RESET, RESET_SRC_REGS_B, Inactive))
818          | (BCHP_FIELD_ENUM (AUD_FMM_MISC_RESET, RESET_DP_LOGIC_B, Inactive))
819          | (BCHP_FIELD_ENUM (AUD_FMM_MISC_RESET, RESET_DP_REGS_B, Inactive))
820          | (BCHP_FIELD_ENUM (AUD_FMM_MISC_RESET, RESET_BF_LOGIC_B, Inactive))
821          | (BCHP_FIELD_ENUM (AUD_FMM_MISC_RESET, RESET_BF_REGS_B, Inactive));
822    BREG_Write32(regHandle, BCHP_AUD_FMM_MISC_RESET, regVal);
823
824    /* Powerup the FMM Modules */       
825    regVal = BREG_Read32(regHandle, BCHP_AIO_MISC_PWRDOWN);
826
827#if BCHP_AIO_MISC_PWRDOWN_ADC_RESET_Reset
828    /* Don't bother with DAC-related fields... they're handled by BAPE_P_InitDacs */
829    regVal &= ~((BCHP_MASK (AIO_MISC_PWRDOWN, ADC_IDDQ_PWRUP)) |
830                (BCHP_MASK (AIO_MISC_PWRDOWN, ADC_REF_PWRUP)) |
831                (BCHP_MASK (AIO_MISC_PWRDOWN, ADC_R_PWRUP)) |
832                (BCHP_MASK (AIO_MISC_PWRDOWN, ADC_L_PWRUP)) |
833                (BCHP_MASK (AIO_MISC_PWRDOWN, ADC_RESET)) |
834                (BCHP_MASK (AIO_MISC_PWRDOWN, ADC_PWRUP_CORE)) |
835                (BCHP_MASK (AIO_MISC_PWRDOWN, SPDIF_RX0)));
836
837    regVal |= ((BCHP_FIELD_DATA (AIO_MISC_PWRDOWN, ADC_IDDQ_PWRUP, 1)) |
838               (BCHP_FIELD_DATA (AIO_MISC_PWRDOWN, ADC_REF_PWRUP, 1)) |
839               (BCHP_FIELD_DATA (AIO_MISC_PWRDOWN, ADC_R_PWRUP, 1)) |
840               (BCHP_FIELD_DATA (AIO_MISC_PWRDOWN, ADC_L_PWRUP, 1)) |
841               (BCHP_FIELD_ENUM (AIO_MISC_PWRDOWN, ADC_RESET, Normal)) |
842               (BCHP_FIELD_ENUM (AIO_MISC_PWRDOWN, ADC_PWRUP_CORE, Normal)) |
843               (BCHP_FIELD_ENUM (AIO_MISC_PWRDOWN, SPDIF_RX0, Normal)));   
844#endif
845
846#if BCHP_AIO_MISC_PWRDOWN_SPDIF_RX_Powerdown       
847    regVal &= ~(BCHP_MASK (AIO_MISC_PWRDOWN, SPDIF_RX));
848    regVal |= (BCHP_FIELD_ENUM (AIO_MISC_PWRDOWN, SPDIF_RX, Normal)); 
849#endif
850
851    BREG_Write32(regHandle, BCHP_AIO_MISC_PWRDOWN, regVal);
852#else
853    /* Newer 7429-style chips have a single-bit reset for the entire audio block */
854    regVal = BCHP_FIELD_ENUM(AUD_MISC_INIT, AUDIO_INIT, Init);
855    BREG_Write32(regHandle, BCHP_AUD_MISC_INIT, regVal);
856    (void)BREG_Read32(regHandle, BCHP_AUD_MISC_INIT);
857    regVal = BCHP_FIELD_ENUM(AUD_MISC_INIT, AUDIO_INIT, Inactive);
858    BREG_Write32(regHandle, BCHP_AUD_MISC_INIT, regVal);
859
860    /* Powerup the FMM Modules */       
861    regVal = BREG_Read32(regHandle, BCHP_AUD_MISC_PWRDOWN);
862
863    #if BCHP_AUD_MISC_PWRDOWN_ADC_RESET_Reset
864    /* Don't bother with DAC-related fields... they're handled by BAPE_P_InitDacs */
865    regVal &= ~((BCHP_MASK (AUD_MISC_PWRDOWN, ADC_IDDQ_PWRUP)) |
866                (BCHP_MASK (AUD_MISC_PWRDOWN, ADC_REF_PWRUP)) |
867                (BCHP_MASK (AUD_MISC_PWRDOWN, ADC_R_PWRUP)) |
868                (BCHP_MASK (AUD_MISC_PWRDOWN, ADC_L_PWRUP)) |
869                (BCHP_MASK (AUD_MISC_PWRDOWN, ADC_RESET)) |
870                (BCHP_MASK (AUD_MISC_PWRDOWN, ADC_PWRUP_CORE)) |
871                (BCHP_MASK (AUD_MISC_PWRDOWN, SPDIF_RX0)));
872
873    regVal |= ((BCHP_FIELD_DATA (AUD_MISC_PWRDOWN, ADC_IDDQ_PWRUP, 1)) |
874               (BCHP_FIELD_DATA (AUD_MISC_PWRDOWN, ADC_REF_PWRUP, 1)) |
875               (BCHP_FIELD_DATA (AUD_MISC_PWRDOWN, ADC_R_PWRUP, 1)) |
876               (BCHP_FIELD_DATA (AUD_MISC_PWRDOWN, ADC_L_PWRUP, 1)) |
877               (BCHP_FIELD_ENUM (AUD_MISC_PWRDOWN, ADC_RESET, Normal)) |
878               (BCHP_FIELD_ENUM (AUD_MISC_PWRDOWN, ADC_PWRUP_CORE, Normal)) |
879               (BCHP_FIELD_ENUM (AUD_MISC_PWRDOWN, SPDIF_RX0, Normal)));   
880    #endif
881
882    #if BCHP_AUD_MISC_PWRDOWN_SPDIF_RX_Powerdown       
883    regVal &= ~(BCHP_MASK (AUD_MISC_PWRDOWN, SPDIF_RX));
884    regVal |= (BCHP_FIELD_ENUM (AUD_MISC_PWRDOWN, SPDIF_RX, Normal)); 
885    #endif
886
887    BREG_Write32(regHandle, BCHP_AUD_MISC_PWRDOWN, regVal);
888#endif
889
890    errCode = BAPE_P_InitDacHw(handle);
891    if ( errCode ) return BERR_TRACE(errCode);
892
893    errCode = BAPE_P_InitBfHw(handle);
894    if ( errCode ) return BERR_TRACE(errCode);
895
896    errCode = BAPE_P_InitDpHw(handle);
897    if ( errCode ) return BERR_TRACE(errCode);
898
899    errCode = BAPE_P_InitSrcHw(handle);
900    if ( errCode ) return BERR_TRACE(errCode);
901
902    errCode = BAPE_P_InitIopHw(handle);
903    if ( errCode ) return BERR_TRACE(errCode);
904
905    return BERR_SUCCESS;
906}
907
908
909void BAPE_GetInterruptHandlers(
910    BAPE_Handle handle,
911    BAPE_InterruptHandlers *pInterrupts     /* [out] */
912    )
913{
914    BDBG_OBJECT_ASSERT(handle, BAPE_Device);
915    BDBG_ASSERT(NULL != pInterrupts);
916    *pInterrupts = handle->interrupts;
917}
918
919BERR_Code BAPE_SetInterruptHandlers(
920    BAPE_Handle handle,
921    const BAPE_InterruptHandlers *pInterrupts
922    )
923{
924    BDBG_OBJECT_ASSERT(handle, BAPE_Device);
925    BDBG_ASSERT(NULL != pInterrupts);
926
927    if ( NULL != handle->dspContext )
928    {
929        BERR_Code errCode;
930        BDSP_ContextInterruptHandlers contextInterrupts;
931
932        BDSP_Context_GetInterruptHandlers(handle->dspContext, &contextInterrupts);
933        contextInterrupts.watchdog.pCallback_isr = pInterrupts->watchdog.pCallback_isr;
934        contextInterrupts.watchdog.pParam1 = pInterrupts->watchdog.pParam1;
935        contextInterrupts.watchdog.param2 = pInterrupts->watchdog.param2;
936        errCode = BDSP_Context_SetInterruptHandlers(handle->dspContext, &contextInterrupts);
937        if ( errCode )
938        {
939            return BERR_TRACE(errCode);
940        }
941    }
942
943    handle->interrupts = *pInterrupts;
944
945    return BERR_SUCCESS;
946}
947
948BERR_Code BAPE_ProcessWatchdogInterrupt(
949    BAPE_Handle handle
950    )
951{
952    BERR_Code errCode;
953    unsigned i;
954
955    BDBG_OBJECT_ASSERT(handle, BAPE_Device);
956
957    if ( handle->dspContext )
958    {
959        /* Stop all running decoders */
960        for ( i = 0; i < BAPE_CHIP_MAX_DECODERS; i++ )
961        {
962            if ( handle->decoders[i] )
963            {
964                handle->decoderWatchdogInfo[i].state = handle->decoders[i]->state;
965                if ( handle->decoderWatchdogInfo[i].state != BAPE_DecoderState_eStopped )
966                {
967                    handle->decoderWatchdogInfo[i].startSettings = handle->decoders[i]->startSettings;
968                    BAPE_Decoder_Stop(handle->decoders[i]);
969                }
970            }
971            else
972            {
973                handle->decoderWatchdogInfo[i].state = BAPE_DecoderState_eMax;
974            }
975        }
976
977        /* Reboot the DSP */
978        errCode = BDSP_Context_ProcessWatchdogInterrupt(handle->dspContext);
979        if ( errCode )
980        {
981            return BERR_TRACE(errCode);
982        }
983
984        /* Reset all decoder state */
985        for ( i = 0; i < BAPE_CHIP_MAX_DECODERS; i++ )
986        {
987            if ( handle->decoders[i] )
988            {
989                if ( handle->decoderWatchdogInfo[i].state != BAPE_DecoderState_eStopped )
990                {
991                    /* Restart Decoder */
992                    errCode = BAPE_Decoder_Start(handle->decoders[i], &handle->decoderWatchdogInfo[i].startSettings);
993                    if ( errCode )
994                    {
995                        BDBG_ERR(("Error restarting decoder %d", i));
996                        errCode = BERR_TRACE(errCode);
997                    }
998
999                    if ( handle->decoderWatchdogInfo[i].state == BAPE_DecoderState_ePaused )
1000                    {
1001                        errCode = BAPE_Decoder_Pause(handle->decoders[i]);
1002                        if ( errCode )
1003                        {
1004                            BDBG_ERR(("Error re-pausing decoder %d", i));
1005                            errCode = BERR_TRACE(errCode);
1006                        }
1007                    }
1008                }
1009            }
1010        }
1011    }
1012
1013    return BERR_SUCCESS;
1014}
1015
1016void BAPE_GetDecoderPathDelay(
1017    BAPE_Handle handle,
1018    unsigned *pDelay    /* [out] in ms */
1019    )
1020{
1021    BDBG_OBJECT_ASSERT(handle, BAPE_Device);
1022    BDBG_ASSERT(NULL != pDelay);
1023    *pDelay = BAPE_CHIP_MAX_PATH_DELAY;
1024}
1025
1026
1027#ifdef BCHP_PWR_SUPPORT
1028static BERR_Code BAPE_P_StandbyFmmHw(BAPE_Handle handle)
1029{
1030    BERR_Code errCode;
1031
1032    BDBG_OBJECT_ASSERT(handle, BAPE_Device);
1033
1034    /* Since all channels are stopped, we can relese the unused "path resources"
1035     * and that should release everything... That way, when we resume from standby,
1036     * then all of the resources will be reallocated (causing the corresponding
1037     * hardware to be reconfigured to its proper state).
1038     */
1039    BAPE_P_ReleaseUnusedPathResources(handle);
1040
1041    /* Disable and destroy the global APE interrupts... We'll recreate them at resume time. */
1042    BAPE_P_UninitInterrupts(handle);
1043
1044    /* Now tell a few more things to get ready to power down into standby mode. */
1045    errCode = BAPE_SpdifInput_P_PrepareForStandby(handle);
1046    if ( errCode ) return BERR_TRACE(errCode);
1047
1048    errCode = BAPE_MaiInput_P_PrepareForStandby(handle);
1049    if ( errCode ) return BERR_TRACE(errCode);
1050
1051    return BERR_SUCCESS;
1052}
1053#endif /* BCHP_PWR_SUPPORT*/
1054
1055
1056#ifdef BCHP_PWR_SUPPORT
1057static BERR_Code BAPE_P_ResumeFmmHw(BAPE_Handle handle)
1058{
1059    BERR_Code errCode;
1060
1061    BDBG_OBJECT_ASSERT(handle, BAPE_Device);
1062
1063    errCode = BAPE_Nco_P_ResumeFromStandby(handle);
1064    if ( errCode ) return BERR_TRACE(errCode);
1065
1066    errCode = BAPE_Pll_P_ResumeFromStandby(handle);
1067    if ( errCode ) return BERR_TRACE(errCode);
1068
1069    errCode = BAPE_LoopbackGroup_P_ResumeFromStandby(handle);
1070    if ( errCode ) return BERR_TRACE(errCode);
1071
1072    errCode = BAPE_DummysinkGroup_P_ResumeFromStandby(handle);
1073    if ( errCode ) return BERR_TRACE(errCode);
1074
1075    errCode = BAPE_AudioReturnChannel_P_ResumeFromStandby(handle);
1076    if ( errCode ) return BERR_TRACE(errCode);
1077
1078    errCode = BAPE_Dac_P_ResumeFromStandby(handle);
1079    if ( errCode ) return BERR_TRACE(errCode);
1080
1081    errCode = BAPE_DummyOutput_P_ResumeFromStandby(handle);
1082    if ( errCode ) return BERR_TRACE(errCode);
1083
1084    errCode = BAPE_I2sMultiOutput_P_ResumeFromStandby(handle);
1085    if ( errCode ) return BERR_TRACE(errCode);
1086
1087    errCode = BAPE_I2sOutput_P_ResumeFromStandby(handle);
1088    if ( errCode ) return BERR_TRACE(errCode);
1089
1090    errCode = BAPE_MaiOutput_P_ResumeFromStandby(handle);
1091    if ( errCode ) return BERR_TRACE(errCode);
1092
1093    errCode = BAPE_RfMod_P_ResumeFromStandby(handle);
1094    if ( errCode ) return BERR_TRACE(errCode);
1095
1096    errCode = BAPE_SpdifOutput_P_ResumeFromStandby(handle);
1097    if ( errCode ) return BERR_TRACE(errCode);
1098
1099    errCode = BAPE_SpdifInput_P_ResumeFromStandby(handle);
1100    if ( errCode ) return BERR_TRACE(errCode);
1101
1102    errCode = BAPE_MaiInput_P_ResumeFromStandby(handle);
1103    if ( errCode ) return BERR_TRACE(errCode);
1104
1105    return BERR_SUCCESS;
1106}
1107#endif /* BCHP_PWR_SUPPORT*/
1108
1109
1110BERR_Code BAPE_Standby(
1111    BAPE_Handle handle,                 /* [in] AP device handle */
1112    BAPE_StandbySettings *pSettings     /* [in] standby settings */
1113)
1114{
1115#ifdef BCHP_PWR_SUPPORT
1116    unsigned i;
1117#endif
1118
1119    BDBG_OBJECT_ASSERT(handle, BAPE_Device);
1120   
1121    BSTD_UNUSED(pSettings);
1122
1123#ifdef BCHP_PWR_SUPPORT
1124    /* check that all channels have been stopped */
1125#if BAPE_CHIP_MAX_DECODERS > 0
1126    for ( i = 0; i < BAPE_CHIP_MAX_DECODERS; i++ )
1127    {
1128        if ( handle->decoders[i] && handle->decoders[i]->state != BAPE_DecoderState_eStopped )
1129        {
1130            BDBG_ERR(("Decoder %p (%d) is not stopped", handle->decoders[i], i));
1131            return BERR_UNKNOWN;
1132        }
1133    }
1134#endif
1135#if BAPE_CHIP_MAX_INPUT_CAPTURES > 0
1136    for ( i = 0; i < BAPE_CHIP_MAX_INPUT_CAPTURES; i++ )
1137    {
1138        if ( handle->inputCaptures[i] && handle->inputCaptures[i]->running == true )
1139        {
1140            BDBG_ERR(("Input capture %p (%d) is not stopped", handle->inputCaptures[i], i));
1141            return BERR_UNKNOWN;
1142        }
1143    }
1144#endif
1145#if BAPE_CHIP_MAX_PLAYBACKS > 0
1146    for ( i = 0; i < BAPE_CHIP_MAX_PLAYBACKS; i++ )
1147    {
1148        if ( handle->playbacks[i] && handle->playbacks[i]->running == true)
1149        {
1150            BDBG_ERR(("Playback %p (%d) is not stopped", handle->playbacks[i], i)); 
1151            return BERR_UNKNOWN;
1152        }
1153    }
1154#endif       
1155
1156    /* if we reach here, then no channels are active. we can power down */
1157    if (!handle->bStandby)
1158    {
1159        BERR_Code   errCode;
1160
1161        handle->bStandby = true;
1162
1163        /* Prepare to go into standby. */
1164        errCode = BAPE_P_StandbyFmmHw(handle);
1165        if ( errCode ) return BERR_TRACE(errCode);
1166
1167#ifdef BCHP_PWR_RESOURCE_AUD_PLL0
1168        BCHP_PWR_ReleaseResource(handle->chpHandle, BCHP_PWR_RESOURCE_AUD_PLL0);
1169#endif
1170#ifdef BCHP_PWR_RESOURCE_AUD_PLL1
1171        BCHP_PWR_ReleaseResource(handle->chpHandle, BCHP_PWR_RESOURCE_AUD_PLL1);
1172#endif
1173#ifdef BCHP_PWR_RESOURCE_AUD_PLL2
1174        BCHP_PWR_ReleaseResource(handle->chpHandle, BCHP_PWR_RESOURCE_AUD_PLL2);
1175#endif
1176#ifdef BCHP_PWR_RESOURCE_AUD_AIO
1177        BCHP_PWR_ReleaseResource(handle->chpHandle, BCHP_PWR_RESOURCE_AUD_AIO);
1178#endif
1179    }
1180#endif
1181
1182    return BERR_SUCCESS;   
1183}
1184
1185BERR_Code BAPE_Resume(
1186    BAPE_Handle handle  /* [in] APE device handle */
1187)
1188{
1189    BDBG_OBJECT_ASSERT(handle, BAPE_Device);
1190
1191#ifdef BCHP_PWR_SUPPORT
1192    if (handle->bStandby) {
1193        handle->bStandby = false;
1194#ifdef BCHP_PWR_RESOURCE_AUD_AIO
1195        BCHP_PWR_AcquireResource(handle->chpHandle, BCHP_PWR_RESOURCE_AUD_AIO);
1196#endif
1197#ifdef BCHP_PWR_RESOURCE_AUD_PLL0
1198        BCHP_PWR_AcquireResource(handle->chpHandle, BCHP_PWR_RESOURCE_AUD_PLL0);
1199#endif
1200#ifdef BCHP_PWR_RESOURCE_AUD_PLL1
1201        BCHP_PWR_AcquireResource(handle->chpHandle, BCHP_PWR_RESOURCE_AUD_PLL1);
1202#endif   
1203#ifdef BCHP_PWR_RESOURCE_AUD_PLL2
1204        BCHP_PWR_AcquireResource(handle->chpHandle, BCHP_PWR_RESOURCE_AUD_PLL2);
1205#endif     
1206        {
1207            BERR_Code   errCode;
1208
1209            /* Put the FMM hardware into the "initial" state... the state that
1210             * BAPE_Open() leaves things in.
1211             */
1212            errCode = BAPE_P_InitFmmHw(handle);
1213            if ( errCode ) return BERR_TRACE(errCode);
1214
1215            /* Recreate and enable the APE global interrupts. */
1216            errCode = BAPE_P_InitInterrupts(handle);
1217            if ( errCode ) return BERR_TRACE(errCode);
1218       
1219            /* Now bring inputs and outputs into their "open" (but "unstarted") state. */
1220            errCode = BAPE_P_ResumeFmmHw(handle);
1221            if ( errCode ) return BERR_TRACE(errCode);
1222        }
1223    }
1224#endif
1225
1226    return BERR_SUCCESS;
1227}
Note: See TracBrowser for help on using the repository browser.