source: svn/newcon3bcm2_21bu/magnum/portinginterface/ape/7552/bape_mai_output.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: 64.9 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_mai_output.c $
11 * $brcm_Revision: Hydra_Software_Devel/19 $
12 * $brcm_Date: 3/6/12 2:59p $
13 *
14 * Module Description: Audio Decoder Interface
15 *
16 * Revision History:
17 *
18 * $brcm_Log: /magnum/portinginterface/ape/7422/bape_mai_output.c $
19 *
20 * Hydra_Software_Devel/19   3/6/12 2:59p gskerl
21 * SW7425-2570: Renamed OutputPortObject substruct from connector to
22 * outputPort.
23 *
24 * Hydra_Software_Devel/18   2/16/12 2:59p jgarrett
25 * SW7552-188: Refactoring MAI channel status handling based on
26 * recommendations from BD platforms
27 *
28 * Hydra_Software_Devel/17   12/1/11 5:20p jgarrett
29 * SW7429-18: Disabling multichannel output grouping for now on 7429
30 *
31 * Hydra_Software_Devel/16   11/14/11 3:35p gskerl
32 * SW7429-18: Merging 7429 changes back to main branch.
33 *
34 * Hydra_Software_Devel/SW7429-18/3   11/4/11 4:42p jgarrett
35 * SW7429-18: Adding SPDIF Output for 7429
36 *
37 * Hydra_Software_Devel/SW7429-18/2   10/27/11 3:21p jgarrett
38 * SW7429-18: Adding I2S Output for 7429
39 *
40 * Hydra_Software_Devel/SW7429-18/1   10/25/11 5:34p jgarrett
41 * SW7429-18: Adding HDMI output support for 7429
42 *
43 * Hydra_Software_Devel/15   10/5/11 12:38p gskerl
44 * SW7231-129: Added support for recovering hardware state after power
45 * standby/resume.
46 *
47 * Hydra_Software_Devel/14   8/19/11 1:41p jgarrett
48 * SW7344-170: Handling MS FREQ_EXT changes
49 *
50 * Hydra_Software_Devel/13   7/8/11 4:25p gskerl
51 * SW7552-72: Added support for NCO/Mclkgen audio clock sources
52 *
53 * Hydra_Software_Devel/12   7/7/11 10:53a jgarrett
54 * SW7552-69: Added stereoMode setting
55 *
56 * Hydra_Software_Devel/11   6/27/11 5:41p jgarrett
57 * SW7231-97: Refactoring SPDIF/HDMI enable mechanisms to handle older
58 * Onkyo receiver DTS->PCM switching requirements
59 *
60 * Hydra_Software_Devel/10   5/20/11 5:16p jgarrett
61 * SW7425-402: Adding error code to handle output enable callback failing.
62 *
63 * Hydra_Software_Devel/9   5/3/11 10:46a gskerl
64 * SW7422-354: Added index and type args to APE_P_InitOutputPort macro
65 *
66 * Hydra_Software_Devel/8   4/16/11 12:15p jgarrett
67 * SW7425-371: Removing tab characters
68 *
69 * Hydra_Software_Devel/7   4/12/11 5:34p jgarrett
70 * SW7425-292: Fixing input mute and preserving output mute across
71 * start/stop
72 *
73 * Hydra_Software_Devel/6   4/6/11 1:23a jgarrett
74 * SW35330-35: Merge to main branch
75 *
76 * Hydra_Software_Devel/SW35330-35/2   4/5/11 7:13p jgarrett
77 * SW35330-35: PCM Playback working on 35230
78 *
79 * Hydra_Software_Devel/SW35330-35/1   4/5/11 12:49p jgarrett
80 * SW35330-35: FMM Abstraction refactoring to support DTV
81 *
82 * Hydra_Software_Devel/5   3/22/11 2:56p gskerl
83 * SW7422-146: Changed audio output connector callbacks to take the output
84 * connector as an argument
85 *
86 * Hydra_Software_Devel/4   2/22/11 5:43p jgarrett
87 * SW7422-146: Implemented type renaming based on filter graph review
88 * comments
89 *
90 * Hydra_Software_Devel/3   2/16/11 4:51p jgarrett
91 * SW7422-146: Coverity CID 251
92 *
93 * Hydra_Software_Devel/2   2/10/11 5:45p gskerl
94 * SW7422-146: Changed calling sequence for the audio output setMclk_isr
95 * callbacks
96 *
97 * Hydra_Software_Devel/1   12/16/10 4:05p jgarrett
98 * SW7422-146: Initial compilable APE for 7422
99 *
100 ***************************************************************************/
101
102#include "bape.h"
103#include "bape_priv.h"
104
105BDBG_MODULE(bape_mai_output);
106
107
108#if BAPE_CHIP_MAX_MAI_OUTPUTS > 0   /* If no MAI outputs, then skip all of this and just put in stub funcs at bottom of file. */
109
110BDBG_OBJECT_ID(BAPE_MaiOutput);
111
112typedef struct BAPE_MaiOutput
113{
114    BDBG_OBJECT(BAPE_MaiOutput)
115    BAPE_Handle deviceHandle;
116    BAPE_MaiOutputSettings settings;
117    unsigned index;
118    BAPE_OutputPortObject outputPort;
119    uint32_t offset;
120    unsigned sampleRate;
121    struct
122    {
123        BAPE_MclkSource mclkSource;
124        unsigned pllChannel;    /* only applies if mclkSource refers to a PLL */
125        unsigned mclkFreqToFsRatio;
126    } mclkInfo;
127    bool enabled;
128    char name[7];   /* MAI %d */
129    BAPE_MaiOutputInterruptHandlers interrupts;
130} BAPE_MaiOutput;
131
132/* Currently all chips support only one -- TODO: HBR? */
133#define GET_MAI_DATA_STREAM_ID(idx, chPair) ((chPair)+3)
134#define GET_MAI_CBIT_STREAM_ID(idx) (1)
135
136/* Static function prototypes */
137static void      BAPE_MaiOutput_P_SetCbits_isr(BAPE_MaiOutputHandle handle);
138static uint32_t  BAPE_MaiOutput_P_SampleRateToMaiFormat(unsigned sampleRate);
139static BERR_Code BAPE_MaiOutput_P_OpenHw(BAPE_MaiOutputHandle handle);
140static void      BAPE_MaiOutput_P_CloseHw(BAPE_MaiOutputHandle handle);
141static BERR_Code BAPE_MaiOutput_P_ApplySettings(BAPE_MaiOutputHandle handle, const BAPE_MaiOutputSettings *pSettings, bool force );
142static uint32_t  BAPE_MaiOutput_P_SampleRateToMaiFormat(unsigned sampleRate);
143
144/* Output port callbacks */
145static void      BAPE_MaiOutput_P_SetTimingParams_isr(BAPE_OutputPort output, unsigned sampleRate, BAVC_Timebase timebase);
146static BERR_Code BAPE_MaiOutput_P_Enable(BAPE_OutputPort output);
147static void      BAPE_MaiOutput_P_Disable(BAPE_OutputPort output);
148static void      BAPE_MaiOutput_P_SetMclk_isr(BAPE_OutputPort output, BAPE_MclkSource mclkSource, unsigned pllChannel, unsigned mclkFreqToFsRatio);
149
150/* Implementations for Legacy vs. New [7429] Hardware */
151#ifdef BCHP_AUD_FMM_IOP_OUT_MAI_0_REG_START
152#include "bchp_aud_fmm_iop_out_mai_0.h"
153static void      BAPE_MaiOutput_P_SetCbits_IopOut_isr(BAPE_MaiOutputHandle handle);
154static BERR_Code BAPE_MaiOutput_P_Enable_IopOut(BAPE_OutputPort output);
155static void      BAPE_MaiOutput_P_Disable_IopOut(BAPE_OutputPort output);
156static void      BAPE_MaiOutput_P_SetMclk_IopOut_isr(BAPE_OutputPort output, BAPE_MclkSource mclkSource, unsigned pllChannel, unsigned mclkFreqToFsRatio);
157static BERR_Code BAPE_MaiOutput_P_OpenHw_IopOut(BAPE_MaiOutputHandle handle);
158static void      BAPE_MaiOutput_P_CloseHw_IopOut(BAPE_MaiOutputHandle handle);
159static void      BAPE_MaiOutput_P_SetCrossbar_IopOut(BAPE_MaiOutputHandle handle, BAPE_StereoMode stereoMode);
160#else
161static void      BAPE_MaiOutput_P_SetCbits_Legacy_isr(BAPE_MaiOutputHandle handle);
162static BERR_Code BAPE_MaiOutput_P_Enable_Legacy(BAPE_OutputPort output);
163static void      BAPE_MaiOutput_P_Disable_Legacy(BAPE_OutputPort output);
164static void      BAPE_MaiOutput_P_SetMclk_Legacy_isr(BAPE_OutputPort output, BAPE_MclkSource mclkSource, unsigned pllChannel, unsigned mclkFreqToFsRatio);
165static BERR_Code BAPE_MaiOutput_P_OpenHw_Legacy(BAPE_MaiOutputHandle handle);
166static void      BAPE_MaiOutput_P_CloseHw_Legacy(BAPE_MaiOutputHandle handle);
167static void      BAPE_MaiOutput_P_SetCrossbar_Legacy(BAPE_MaiOutputHandle handle, BAPE_StereoMode stereoMode);
168#endif
169
170/***************************************************************************
171        Public APIs: From bape_output.h
172***************************************************************************/
173
174void BAPE_MaiOutput_GetDefaultSettings(
175    BAPE_MaiOutputSettings *pSettings
176    )
177{
178    BDBG_ASSERT(NULL != pSettings);
179    BKNI_Memset(pSettings, 0, sizeof(*pSettings));
180
181    pSettings->stereoMode = BAPE_StereoMode_eLeftRight;
182    pSettings->ditherEnabled = true;
183    pSettings->underflowBurst = BAPE_SpdifBurstType_ePause;
184    pSettings->useRawChannelStatus = false;
185    /* channel status is initialized to zero for all fields */
186}
187
188/**************************************************************************/
189
190BERR_Code BAPE_MaiOutput_Open(
191    BAPE_Handle deviceHandle,
192    unsigned index,
193    const BAPE_MaiOutputSettings *pSettings,
194    BAPE_MaiOutputHandle *pHandle             /* [out] */
195    )
196{
197    BERR_Code errCode;
198    BAPE_MaiOutputHandle handle;
199    BAPE_MaiOutputSettings defaultSettings;
200
201    BDBG_OBJECT_ASSERT(deviceHandle, BAPE_Device);
202    BDBG_ASSERT(NULL != pHandle);
203   
204    BDBG_MSG(("%s: Opening MAI Output: %u", __FUNCTION__, index));
205
206    *pHandle = NULL;    /* Set up to return null handle in case of error. */
207
208    if ( index >= BAPE_CHIP_MAX_MAI_OUTPUTS )
209    {
210        BDBG_ERR(("Request to open MAI %d but chip only has %u MAI outputs", index, BAPE_CHIP_MAX_MAI_OUTPUTS));
211        return BERR_TRACE(BERR_INVALID_PARAMETER);
212    }
213
214    if ( deviceHandle->maiOutputs[index] )
215    {
216        BDBG_ERR(("MAI output %d already open", index));
217        return BERR_TRACE(BERR_INVALID_PARAMETER);
218    }
219
220    /* Allocate the device structure, then fill in all the fields. */
221    handle = BKNI_Malloc(sizeof(BAPE_MaiOutput));
222    if ( NULL == handle )
223    {
224        return BERR_TRACE(BERR_OUT_OF_SYSTEM_MEMORY);
225    }
226
227    BKNI_Memset(handle, 0, sizeof(BAPE_MaiOutput));
228    BDBG_OBJECT_SET(handle, BAPE_MaiOutput);
229    handle->deviceHandle = deviceHandle;
230    handle->index = index;
231    BAPE_P_InitOutputPort(&handle->outputPort, BAPE_OutputPortType_eMaiOutput, index, handle);
232    handle->outputPort.maxChannelPairs = 4;  /* MaiOutput is stero, compressed, 5.1, or 7.1 */
233    handle->outputPort.compressedSupported = true;
234    handle->outputPort.muteInMixer = true;
235    handle->outputPort.setTimingParams_isr = BAPE_MaiOutput_P_SetTimingParams_isr;
236    handle->outputPort.enable = BAPE_MaiOutput_P_Enable;
237    handle->outputPort.disable = BAPE_MaiOutput_P_Disable;
238    handle->outputPort.setMclk_isr = BAPE_MaiOutput_P_SetMclk_isr;
239    BKNI_Snprintf(handle->name, sizeof(handle->name), "MAI %u", index);
240    handle->outputPort.pName = handle->name;
241    /* Currently we only support one HDMI, this can be expanded later if we support more */
242    #if BAPE_CHIP_MAX_MAI_OUTPUTS > 1
243        #error "Need to support more MAI outputs"
244    #endif
245    handle->offset = 0;
246    handle->sampleRate = 48000;
247
248    BDBG_ASSERT(handle->offset == 0);
249
250    BKNI_EnterCriticalSection();
251    BAPE_MaiOutput_P_SetTimingParams_isr(&handle->outputPort, 48000, BAVC_Timebase_e0);
252    BKNI_LeaveCriticalSection();
253
254    /* Init to specified settings */
255    if ( NULL == pSettings )
256    {
257        BAPE_MaiOutput_GetDefaultSettings(&defaultSettings);
258        pSettings = &defaultSettings;
259    }
260
261    errCode = BAPE_MaiOutput_P_OpenHw(handle);
262    if ( errCode )
263    {
264        BAPE_MaiOutput_Close(handle);
265        return BERR_TRACE(errCode);
266    }
267
268    /* Initialize hardware before applying settings */
269    BKNI_EnterCriticalSection();
270    BAPE_MaiOutput_P_SetMclk_isr(&handle->outputPort, BAPE_MclkSource_ePll0, 0, BAPE_BASE_PLL_TO_FS_RATIO);
271    BKNI_LeaveCriticalSection();   
272
273    errCode = BAPE_MaiOutput_P_ApplySettings(handle, pSettings, true);   /* true => force update of HW */
274    if ( errCode )
275    {
276        BAPE_MaiOutput_Close(handle);
277        return BERR_TRACE(errCode);
278    }
279
280    *pHandle = handle;
281    handle->deviceHandle->maiOutputs[index] = handle;
282    return BERR_SUCCESS;
283}
284
285/**************************************************************************/
286
287void BAPE_MaiOutput_Close(
288    BAPE_MaiOutputHandle handle
289    )
290{
291    BDBG_OBJECT_ASSERT(handle, BAPE_MaiOutput);
292
293    /* Make sure we're not still connected to anything */
294    if ( handle->outputPort.mixer )
295    {
296        BDBG_ERR(("Cannot close MAI output %p (%d), still connected to mixer %p", handle, handle->index, handle->outputPort.mixer));
297        BDBG_ASSERT(NULL == handle->outputPort.mixer);
298        return;
299    }
300
301    BAPE_MaiOutput_P_CloseHw(handle);
302
303    BDBG_ASSERT(handle->index < BAPE_CHIP_MAX_MAI_OUTPUTS);
304    handle->deviceHandle->maiOutputs[handle->index] = NULL;
305    BDBG_OBJECT_DESTROY(handle, BAPE_MaiOutput);
306    BKNI_Free(handle);   
307}
308
309/**************************************************************************/
310
311void BAPE_MaiOutput_GetSettings(
312    BAPE_MaiOutputHandle handle,
313    BAPE_MaiOutputSettings *pSettings     /* [out] */
314    )
315{
316    BDBG_OBJECT_ASSERT(handle, BAPE_MaiOutput);
317    BDBG_ASSERT(NULL != pSettings);
318    *pSettings = handle->settings;
319}
320
321/**************************************************************************/
322
323BERR_Code BAPE_MaiOutput_SetSettings(
324    BAPE_MaiOutputHandle handle,
325    const BAPE_MaiOutputSettings *pSettings
326    )
327{
328    BERR_Code   errCode = BERR_SUCCESS;
329
330    BDBG_OBJECT_ASSERT(handle, BAPE_MaiOutput);
331    BDBG_ASSERT(NULL != pSettings);
332   
333    handle->settings = *pSettings;
334
335    errCode = BAPE_MaiOutput_P_ApplySettings(handle, pSettings, false); /* false => don't force (only update HW for changes) */
336    return errCode;
337}
338
339/**************************************************************************/
340
341void BAPE_MaiOutput_GetOutputPort(
342    BAPE_MaiOutputHandle handle,
343    BAPE_OutputPort *pOutputPort        /* [out] */
344    )
345{
346    BDBG_OBJECT_ASSERT(handle, BAPE_MaiOutput);
347    BDBG_ASSERT(NULL != pOutputPort);
348    *pOutputPort = &handle->outputPort;
349}
350
351/**************************************************************************/
352
353void BAPE_MaiOutput_GetInterruptHandlers(
354    BAPE_MaiOutputHandle handle,
355    BAPE_MaiOutputInterruptHandlers *pInterrupts    /* [out] */
356    )
357{
358    BDBG_OBJECT_ASSERT(handle, BAPE_MaiOutput);
359    BDBG_ASSERT(NULL != pInterrupts);
360    BKNI_EnterCriticalSection();
361    *pInterrupts = handle->interrupts;
362    BKNI_LeaveCriticalSection();
363}
364
365/**************************************************************************/
366
367BERR_Code BAPE_MaiOutput_SetInterruptHandlers(
368    BAPE_MaiOutputHandle handle,
369    const BAPE_MaiOutputInterruptHandlers *pInterrupts
370    )
371{
372    BDBG_OBJECT_ASSERT(handle, BAPE_MaiOutput);
373    BDBG_ASSERT(NULL != pInterrupts);
374    BKNI_EnterCriticalSection();
375    handle->interrupts = *pInterrupts;
376    BKNI_LeaveCriticalSection();
377    return BERR_SUCCESS;
378}
379
380/***************************************************************************
381        BAPE Internal APIs: From bape_fmm_priv.h
382***************************************************************************/
383
384BERR_Code BAPE_MaiOutput_P_ResumeFromStandby(BAPE_Handle bapeHandle)
385{
386    BERR_Code   errCode = BERR_SUCCESS;
387    unsigned    maiOutputIndex;
388
389    BDBG_OBJECT_ASSERT(bapeHandle, BAPE_Device);
390
391    /* For each opened MaiOutput, call the functions necessary to restore the hardware to it's appropriate state. */
392    for ( maiOutputIndex=0 ; maiOutputIndex<BAPE_CHIP_MAX_MAI_OUTPUTS ; maiOutputIndex++ )
393    {
394        if ( bapeHandle->maiOutputs[maiOutputIndex] )       /* If this MaiOutput is open... */
395        {
396            BAPE_MaiOutputHandle hMaiOutput = bapeHandle->maiOutputs[maiOutputIndex];
397
398            /* Put the HW into the generic open state. */
399            errCode = BAPE_MaiOutput_P_OpenHw(hMaiOutput);
400            if ( errCode ) return BERR_TRACE(errCode);
401           
402            /* Now apply changes for the settings struct. */
403            errCode = BAPE_MaiOutput_P_ApplySettings(hMaiOutput, &hMaiOutput->settings, true);   /* true => force update of HW */
404            if ( errCode ) return BERR_TRACE(errCode);
405
406            /* Now restore the dynamic stuff from the values saved in the device struct. */
407            BKNI_EnterCriticalSection();
408
409            BAPE_MaiOutput_P_SetTimingParams_isr(&hMaiOutput->outputPort, 
410                                                 hMaiOutput->sampleRate, 
411                                                 0);    /* timebase is unused, 0 is dummy value */
412
413            BAPE_MaiOutput_P_SetMclk_isr(&hMaiOutput->outputPort,
414                                         hMaiOutput->mclkInfo.mclkSource,
415                                         hMaiOutput->mclkInfo.pllChannel,
416                                         hMaiOutput->mclkInfo.mclkFreqToFsRatio );
417
418            BKNI_LeaveCriticalSection();
419        }
420    }
421    return errCode;
422}
423
424/***************************************************************************
425        Private callbacks: Protyped above
426***************************************************************************/
427
428static void BAPE_MaiOutput_P_SetTimingParams_isr(BAPE_OutputPort output, unsigned sampleRate, BAVC_Timebase timebase)
429{
430    BAPE_MaiOutputHandle handle;
431
432    BDBG_OBJECT_ASSERT(output, BAPE_OutputPort);
433
434    handle = output->pHandle;
435    BDBG_OBJECT_ASSERT(handle, BAPE_MaiOutput);
436    BSTD_UNUSED(timebase);  /* MAI doesn't care */
437
438    handle->sampleRate = sampleRate;
439
440    BAPE_MaiOutput_P_SetCbits_isr(handle);
441
442    if ( handle->interrupts.sampleRate.pCallback_isr )
443    {
444        BDBG_MSG(("Sending sample rate callback - new rate %u", sampleRate));
445        handle->interrupts.sampleRate.pCallback_isr(handle->interrupts.sampleRate.pParam1, handle->interrupts.sampleRate.param2, sampleRate);
446    }
447}
448
449/**************************************************************************/
450static BERR_Code BAPE_MaiOutput_P_Enable(BAPE_OutputPort output)
451{
452#ifdef BCHP_AUD_FMM_IOP_OUT_MAI_0_REG_START
453    return BAPE_MaiOutput_P_Enable_IopOut(output);
454#else
455    return BAPE_MaiOutput_P_Enable_Legacy(output);
456#endif
457}
458
459/**************************************************************************/
460
461static void BAPE_MaiOutput_P_Disable(BAPE_OutputPort output)
462{
463#ifdef BCHP_AUD_FMM_IOP_OUT_MAI_0_REG_START
464    BAPE_MaiOutput_P_Disable_IopOut(output);
465#else
466    BAPE_MaiOutput_P_Disable_Legacy(output);
467#endif
468}
469
470/**************************************************************************/
471
472static void BAPE_MaiOutput_P_SetMclk_isr(BAPE_OutputPort output, BAPE_MclkSource mclkSource, unsigned pllChannel, unsigned mclkFreqToFsRatio)
473{
474#ifdef BCHP_AUD_FMM_IOP_OUT_MAI_0_REG_START
475    BAPE_MaiOutput_P_SetMclk_IopOut_isr(output, mclkSource, pllChannel, mclkFreqToFsRatio);
476#else
477    BAPE_MaiOutput_P_SetMclk_Legacy_isr(output, mclkSource, pllChannel, mclkFreqToFsRatio);
478#endif
479}
480
481/***************************************************************************
482        Private functions: Protyped above
483***************************************************************************/
484
485static void BAPE_MaiOutput_P_SetCbits_isr(BAPE_MaiOutputHandle handle)
486{
487#ifdef BCHP_AUD_FMM_IOP_OUT_MAI_0_REG_START
488    BAPE_MaiOutput_P_SetCbits_IopOut_isr(handle);
489#else
490    BAPE_MaiOutput_P_SetCbits_Legacy_isr(handle);
491#endif
492}
493
494/**************************************************************************/
495
496static BERR_Code BAPE_MaiOutput_P_OpenHw(BAPE_MaiOutputHandle handle)
497{
498#ifdef BCHP_AUD_FMM_IOP_OUT_MAI_0_REG_START
499    return BAPE_MaiOutput_P_OpenHw_IopOut(handle);
500#else
501    return BAPE_MaiOutput_P_OpenHw_Legacy(handle);
502#endif
503}
504
505static void BAPE_MaiOutput_P_CloseHw(BAPE_MaiOutputHandle handle)
506{
507#ifdef BCHP_AUD_FMM_IOP_OUT_MAI_0_REG_START
508    BAPE_MaiOutput_P_CloseHw_IopOut(handle);
509#else
510    BAPE_MaiOutput_P_CloseHw_Legacy(handle);
511#endif
512}
513
514/**************************************************************************/
515
516static BERR_Code BAPE_MaiOutput_P_ApplySettings(
517    BAPE_MaiOutputHandle handle,
518    const BAPE_MaiOutputSettings *pSettings,
519    bool force
520    )
521{
522    BSTD_UNUSED(force); /* We don't need this because all settings are always written to HW. */
523
524    BDBG_OBJECT_ASSERT(handle, BAPE_MaiOutput);
525    BDBG_ASSERT(NULL != pSettings);
526
527    /* Remaining fields are handled by MS regs.  Must modify those in critical section. */   
528    BKNI_EnterCriticalSection();
529    BAPE_MaiOutput_P_SetCbits_isr(handle);
530    BKNI_LeaveCriticalSection();
531
532#ifdef BCHP_AUD_FMM_IOP_OUT_MAI_0_REG_START
533    BAPE_MaiOutput_P_SetCrossbar_IopOut(handle, handle->settings.stereoMode);
534#else
535    BAPE_MaiOutput_P_SetCrossbar_Legacy(handle, handle->settings.stereoMode);
536#endif
537    handle->settings = *pSettings;
538
539    return BERR_SUCCESS;
540}
541
542static uint32_t BAPE_MaiOutput_P_SampleRateToMaiFormat(unsigned sampleRate)
543{
544    switch ( sampleRate )
545    {
546    case 32000:    /* 32K Sample rate */
547        return 7;
548    case 44100:    /* 44.1K Sample rate */
549        return 8;
550    case 48000:      /* 48K Sample rate */
551        return 9;
552    case 96000:      /* 96K Sample rate */
553        return 12;
554    case 128000:     /* 128K Sample rate */
555        return 13;
556    case 176400:   /* 176.4K Sample rate */
557        return 14;
558    case 192000:     /* 192K Sample rate */
559        return 15;
560    default:
561        return 0;   /* Not Indicated */
562    }
563}
564
565#ifndef BCHP_AUD_FMM_IOP_OUT_MAI_0_REG_START
566static void BAPE_MaiOutput_P_SetCbits_Legacy_isr(BAPE_MaiOutputHandle handle)
567{
568    uint32_t regAddr, regVal;
569    bool compressed;
570    unsigned validity;
571    uint32_t ena;
572
573    BDBG_OBJECT_ASSERT(handle, BAPE_MaiOutput);
574
575    compressed = (handle->outputPort.mixer && handle->outputPort.mixer->compressed)?true:false;
576
577    BDBG_MSG(("Set MAI CBITS SR %u", handle->sampleRate));
578
579    /* Only set validity if we're outputting compressed */
580    if ( compressed )
581    {
582        validity = 1;
583    }
584    else
585    {
586        validity = 0;
587    }
588
589    /* Program MAI format correctly */
590    if ( handle->outputPort.mixer )
591    {
592        regVal = BREG_Read32_isr(handle->deviceHandle->regHandle, BCHP_AUD_FMM_OP_CTRL_MAI_FORMAT);
593        regVal &= ~(BCHP_MASK(AUD_FMM_OP_CTRL_MAI_FORMAT, AUDIO_FORMAT)|
594                    BCHP_MASK(AUD_FMM_OP_CTRL_MAI_FORMAT, SAMPLE_WIDTH)|
595                    BCHP_MASK(AUD_FMM_OP_CTRL_MAI_FORMAT, SAMPLE_RATE));
596        if ( handle->outputPort.mixer->compressed )
597        {
598            regVal |= BCHP_FIELD_ENUM(AUD_FMM_OP_CTRL_MAI_FORMAT, AUDIO_FORMAT, SPDIF_Comp_2_Channel);
599            regVal |= BCHP_FIELD_DATA(AUD_FMM_OP_CTRL_MAI_FORMAT, SAMPLE_WIDTH, 16);    /* TODO: */
600        }
601        else
602        {
603            switch ( handle->outputPort.mixer->numChannelPairs )
604            {
605            case 3:
606                regVal |= BCHP_FIELD_ENUM(AUD_FMM_OP_CTRL_MAI_FORMAT, AUDIO_FORMAT, SPDIF_PCM_6_Channel);
607                break;
608            case 4:
609                regVal |= BCHP_FIELD_ENUM(AUD_FMM_OP_CTRL_MAI_FORMAT, AUDIO_FORMAT, SPDIF_PCM_8_Channel);
610                break;
611            default:
612                regVal |= BCHP_FIELD_ENUM(AUD_FMM_OP_CTRL_MAI_FORMAT, AUDIO_FORMAT, SPDIF_PCM_2_Channel);
613                break;
614            }
615            regVal |= BCHP_FIELD_DATA(AUD_FMM_OP_CTRL_MAI_FORMAT, SAMPLE_WIDTH, 0); /* 32 bits per sample */
616        }
617        regVal |= BCHP_FIELD_DATA(AUD_FMM_OP_CTRL_MAI_FORMAT, SAMPLE_RATE, 
618                                  BAPE_MaiOutput_P_SampleRateToMaiFormat(handle->outputPort.mixer->sampleRate));
619        BDBG_MSG(("Set MAI format to 0x%x", regVal));
620        BREG_Write32_isr(handle->deviceHandle->regHandle, BCHP_AUD_FMM_OP_CTRL_MAI_FORMAT, regVal);
621    }
622
623    /* Tell the HW to hold the current CBITS and set dither correctly */
624    regAddr = BCHP_AUD_FMM_MS_CTRL_HW_SPDIF_CFG_1;
625    regVal = BREG_Read32_isr(handle->deviceHandle->regHandle, regAddr);
626    regVal &= ~(BCHP_MASK(AUD_FMM_MS_CTRL_HW_SPDIF_CFG_1, HOLD_CSTAT)|
627                BCHP_MASK(AUD_FMM_MS_CTRL_HW_SPDIF_CFG_1, DITHER_ENA)|
628                BCHP_MASK(AUD_FMM_MS_CTRL_HW_SPDIF_CFG_1, VALIDITY));
629    if ( handle->settings.ditherEnabled && !compressed )
630    {
631        regVal |= BCHP_FIELD_ENUM(AUD_FMM_MS_CTRL_HW_SPDIF_CFG_1, DITHER_ENA, Enable);
632    }
633    else
634    {
635        regVal |= BCHP_FIELD_ENUM(AUD_FMM_MS_CTRL_HW_SPDIF_CFG_1, DITHER_ENA, Disable);
636    }
637    regVal |= BCHP_FIELD_DATA(AUD_FMM_MS_CTRL_HW_SPDIF_CFG_1, VALIDITY, validity);
638    regVal |= BCHP_FIELD_ENUM(AUD_FMM_MS_CTRL_HW_SPDIF_CFG_1, HOLD_CSTAT, Hold);
639    BREG_Write32_isr(handle->deviceHandle->regHandle, regAddr, regVal);
640
641    /* Retrieve current enable status */
642    ena = BAPE_Reg_P_ReadField_isr(handle->deviceHandle, BCHP_AUD_FMM_MS_CTRL_STRM_ENA, AUD_FMM_MS_CTRL_STRM_ENA, STREAM1_ENA);
643
644    /* Disable formatter - this is counter-intuitive but ensures CBITS continue to flow during the transition */
645    BAPE_Reg_P_UpdateEnum_isr(handle->deviceHandle, BCHP_AUD_FMM_MS_CTRL_STRM_ENA, AUD_FMM_MS_CTRL_STRM_ENA, STREAM1_ENA, Disable);
646
647    /* Program channel status */
648    if ( handle->settings.useRawChannelStatus )
649    {
650        regVal = 
651            (uint32_t)handle->settings.rawChannelStatus[0] |
652            (((uint32_t)handle->settings.rawChannelStatus[1])<<8) |
653            (((uint32_t)handle->settings.rawChannelStatus[2])<<16) |
654            (((uint32_t)handle->settings.rawChannelStatus[3])<<24);
655        BREG_Write32_isr(handle->deviceHandle->regHandle, BCHP_AUD_FMM_MS_CTRL_HW_CHANSTAT_LO_1, regVal);
656        regVal = (uint32_t)handle->settings.rawChannelStatus[4];
657        BREG_Write32_isr(handle->deviceHandle->regHandle, BCHP_AUD_FMM_MS_CTRL_HW_CHANSTAT_HI_1, regVal);
658    }
659    else if ( handle->outputPort.mixer && handle->outputPort.mixer->compressed )
660    {
661        regVal = BREG_Read32_isr(handle->deviceHandle->regHandle, BCHP_AUD_FMM_MS_CTRL_HW_CHANSTAT_LO_1);
662        regVal &= ~(BCHP_MASK(AUD_FMM_MS_CTRL_HW_CHANSTAT_LO_1, Compressed_PRO_CONS)|
663                    BCHP_MASK(AUD_FMM_MS_CTRL_HW_CHANSTAT_LO_1, Compressed_COMP_LIN)|
664                    BCHP_MASK(AUD_FMM_MS_CTRL_HW_CHANSTAT_LO_1, Compressed_CP)|
665                    BCHP_MASK(AUD_FMM_MS_CTRL_HW_CHANSTAT_LO_1, Compressed_EMPH)|
666                    BCHP_MASK(AUD_FMM_MS_CTRL_HW_CHANSTAT_LO_1, Compressed_CMODE)|
667                    BCHP_MASK(AUD_FMM_MS_CTRL_HW_CHANSTAT_LO_1, Compressed_CATEGORY)|
668                    BCHP_MASK(AUD_FMM_MS_CTRL_HW_CHANSTAT_LO_1, Compressed_SOURCE)|
669                    BCHP_MASK(AUD_FMM_MS_CTRL_HW_CHANSTAT_LO_1, Compressed_FREQ)|
670                    BCHP_MASK(AUD_FMM_MS_CTRL_HW_CHANSTAT_LO_1, Compressed_ACCURACY)|
671#ifdef BCHP_AUD_FMM_MS_CTRL_HW_CHANSTAT_LO_1_Compressed_BITS_31_to_30_MASK         
672                    BCHP_MASK(AUD_FMM_MS_CTRL_HW_CHANSTAT_LO_1, Compressed_BITS_31_to_30)
673#else
674                    BCHP_MASK(AUD_FMM_MS_CTRL_HW_CHANSTAT_LO_1, Compressed_FREQ_EXTN)
675#endif                   
676                    );
677        regVal |= BCHP_FIELD_DATA(AUD_FMM_MS_CTRL_HW_CHANSTAT_LO_1, Compressed_PRO_CONS, handle->settings.channelStatus.professional);
678        regVal |= BCHP_FIELD_DATA(AUD_FMM_MS_CTRL_HW_CHANSTAT_LO_1, Compressed_COMP_LIN, 1);
679        regVal |= BCHP_FIELD_DATA(AUD_FMM_MS_CTRL_HW_CHANSTAT_LO_1, Compressed_CP, (handle->settings.channelStatus.copyright)?0:1);
680        regVal |= BCHP_FIELD_DATA(AUD_FMM_MS_CTRL_HW_CHANSTAT_LO_1, Compressed_CATEGORY, handle->settings.channelStatus.categoryCode);
681        regVal |= BCHP_FIELD_DATA(AUD_FMM_MS_CTRL_HW_CHANSTAT_LO_1, Compressed_SOURCE, handle->settings.channelStatus.sourceNumber);
682        regVal |= BCHP_FIELD_DATA(AUD_FMM_MS_CTRL_HW_CHANSTAT_LO_1, Compressed_FREQ, BAPE_P_GetSampleRateCstatCode(handle->sampleRate));
683        regVal |= BCHP_FIELD_DATA(AUD_FMM_MS_CTRL_HW_CHANSTAT_LO_1, Compressed_ACCURACY, handle->settings.channelStatus.clockAccuracy);
684        BREG_Write32(handle->deviceHandle->regHandle, BCHP_AUD_FMM_MS_CTRL_HW_CHANSTAT_LO_1, regVal);
685        BREG_Write32_isr(handle->deviceHandle->regHandle, BCHP_AUD_FMM_MS_CTRL_HW_CHANSTAT_HI_1, 0);
686    }
687    else
688    {   
689        regVal = BREG_Read32_isr(handle->deviceHandle->regHandle, BCHP_AUD_FMM_MS_CTRL_HW_CHANSTAT_LO_1);
690        regVal &= ~(BCHP_MASK(AUD_FMM_MS_CTRL_HW_CHANSTAT_LO_1, PCM_PRO_CONS)|
691                    BCHP_MASK(AUD_FMM_MS_CTRL_HW_CHANSTAT_LO_1, PCM_COMP_LIN)|
692                    BCHP_MASK(AUD_FMM_MS_CTRL_HW_CHANSTAT_LO_1, PCM_CP)|
693                    BCHP_MASK(AUD_FMM_MS_CTRL_HW_CHANSTAT_LO_1, PCM_EMPH)|
694                    BCHP_MASK(AUD_FMM_MS_CTRL_HW_CHANSTAT_LO_1, PCM_CMODE)|
695                    BCHP_MASK(AUD_FMM_MS_CTRL_HW_CHANSTAT_LO_1, PCM_CATEGORY)|
696                    BCHP_MASK(AUD_FMM_MS_CTRL_HW_CHANSTAT_LO_1, PCM_SOURCE)|
697                    BCHP_MASK(AUD_FMM_MS_CTRL_HW_CHANSTAT_LO_1, PCM_FREQ)|
698                    BCHP_MASK(AUD_FMM_MS_CTRL_HW_CHANSTAT_LO_1, PCM_ACCURACY)|
699#ifdef BCHP_AUD_FMM_MS_CTRL_HW_CHANSTAT_LO_1_Compressed_BITS_31_to_30_MASK         
700                    BCHP_MASK(AUD_FMM_MS_CTRL_HW_CHANSTAT_LO_1, PCM_BITS_31_to_30)
701#else
702                    BCHP_MASK(AUD_FMM_MS_CTRL_HW_CHANSTAT_LO_1, PCM_FREQ_EXTN)
703#endif                   
704                    );
705        regVal |= BCHP_FIELD_DATA(AUD_FMM_MS_CTRL_HW_CHANSTAT_LO_1, PCM_PRO_CONS, handle->settings.channelStatus.professional);
706        regVal |= BCHP_FIELD_DATA(AUD_FMM_MS_CTRL_HW_CHANSTAT_LO_1, PCM_CP, (handle->settings.channelStatus.copyright)?0:1);
707        regVal |= BCHP_FIELD_DATA(AUD_FMM_MS_CTRL_HW_CHANSTAT_LO_1, PCM_CATEGORY, handle->settings.channelStatus.categoryCode);
708        regVal |= BCHP_FIELD_DATA(AUD_FMM_MS_CTRL_HW_CHANSTAT_LO_1, PCM_SOURCE, handle->settings.channelStatus.sourceNumber);
709        regVal |= BCHP_FIELD_DATA(AUD_FMM_MS_CTRL_HW_CHANSTAT_LO_1, PCM_FREQ, BAPE_P_GetSampleRateCstatCode(handle->sampleRate));
710        regVal |= BCHP_FIELD_DATA(AUD_FMM_MS_CTRL_HW_CHANSTAT_LO_1, PCM_ACCURACY, handle->settings.channelStatus.clockAccuracy);
711        BREG_Write32_isr(handle->deviceHandle->regHandle, BCHP_AUD_FMM_MS_CTRL_HW_CHANSTAT_LO_1, regVal);       
712        regVal = BREG_Read32_isr(handle->deviceHandle->regHandle, BCHP_AUD_FMM_MS_CTRL_HW_CHANSTAT_HI_1);
713        regVal &= ~(BCHP_MASK(AUD_FMM_MS_CTRL_HW_CHANSTAT_HI_1, PCM_MAX_LEN)|
714                    BCHP_MASK(AUD_FMM_MS_CTRL_HW_CHANSTAT_HI_1, PCM_LENGTH)|
715                    BCHP_MASK(AUD_FMM_MS_CTRL_HW_CHANSTAT_HI_1, PCM_ORIG_FREQ));
716        regVal |= BCHP_FIELD_DATA(AUD_FMM_MS_CTRL_HW_CHANSTAT_HI_1, PCM_MAX_LEN, 1);    /* 24-bits */
717        #ifdef BCHP_AUD_FMM_MS_CTRL_HW_CHANSTAT_HI_1_PCM_CGMS_A_MASK
718        regVal &= ~(BCHP_MASK(AUD_FMM_MS_CTRL_HW_CHANSTAT_HI_1, PCM_CGMS_A));
719        regVal |= BCHP_FIELD_DATA(AUD_FMM_MS_CTRL_HW_CHANSTAT_HI_1, PCM_CGMS_A, handle->settings.channelStatus.cgmsA);
720        #endif
721        BREG_Write32_isr(handle->deviceHandle->regHandle, BCHP_AUD_FMM_MS_CTRL_HW_CHANSTAT_HI_1, regVal);
722    }
723
724    /* Restore previous enable status */
725    BAPE_Reg_P_UpdateField_isr(handle->deviceHandle, BCHP_AUD_FMM_MS_CTRL_STRM_ENA, AUD_FMM_MS_CTRL_STRM_ENA, STREAM1_ENA, ena);
726
727    /* Begin using new bits */
728    regAddr = BCHP_AUD_FMM_MS_CTRL_HW_SPDIF_CFG_1;
729    regVal = BREG_Read32_isr(handle->deviceHandle->regHandle, regAddr);
730    regVal &= ~BCHP_MASK(AUD_FMM_MS_CTRL_HW_SPDIF_CFG_1, HOLD_CSTAT);
731    regVal |= BCHP_FIELD_ENUM(AUD_FMM_MS_CTRL_HW_SPDIF_CFG_1, HOLD_CSTAT, Update);
732    BREG_Write32_isr(handle->deviceHandle->regHandle, regAddr, regVal);
733
734    return;
735}
736
737static void BAPE_MaiOutput_P_SetMclk_Legacy_isr(BAPE_OutputPort output, BAPE_MclkSource mclkSource, unsigned pllChannel, unsigned mclkFreqToFsRatio)
738{
739    uint32_t regVal, pllclksel=0;
740    uint32_t mclkRate;
741
742    BAPE_MaiOutputHandle handle;
743
744    BDBG_OBJECT_ASSERT(output, BAPE_OutputPort);
745
746    handle = output->pHandle;
747    BDBG_OBJECT_ASSERT(handle, BAPE_MaiOutput);
748    BDBG_ASSERT(handle->offset == 0);
749
750    /* Save the settings in case we need to re-apply them later. */
751    handle->mclkInfo.mclkSource         = mclkSource;
752    handle->mclkInfo.pllChannel         = pllChannel;
753    handle->mclkInfo.mclkFreqToFsRatio  = mclkFreqToFsRatio;
754
755    switch ( mclkSource )
756    {
757    /* PLL Timing */
758    #if BAPE_CHIP_MAX_PLLS > 0
759    case BAPE_MclkSource_ePll0:
760        pllclksel = BCHP_AUD_FMM_OP_CTRL_MCLK_CFG_MAI_MULTI_PLLCLKSEL_PLL0_ch1 + pllChannel;
761        break;
762    #endif
763    #if BAPE_CHIP_MAX_PLLS > 1
764    case BAPE_MclkSource_ePll1:
765        pllclksel = BCHP_AUD_FMM_OP_CTRL_MCLK_CFG_MAI_MULTI_PLLCLKSEL_PLL1_ch1 + pllChannel;
766        break;
767    #endif
768    #if BAPE_CHIP_MAX_PLLS > 2
769    case BAPE_MclkSource_ePll2:
770        pllclksel = BCHP_AUD_FMM_OP_CTRL_MCLK_CFG_MAI_MULTI_PLLCLKSEL_PLL2_ch1 + pllChannel;
771        break;
772    #endif
773
774    /* DAC Timing */
775    #if BAPE_CHIP_MAX_DACS > 0
776    case BAPE_MclkSource_eHifidac0:
777        pllclksel = BCHP_AUD_FMM_OP_CTRL_MCLK_CFG_MAI_MULTI_PLLCLKSEL_Hifidac0;
778        break;
779    #endif
780    #if BAPE_CHIP_MAX_DACS > 1
781    case BAPE_MclkSource_eHifidac1:
782        pllclksel = BCHP_AUD_FMM_OP_CTRL_MCLK_CFG_MAI_MULTI_PLLCLKSEL_Hifidac1;
783        break;
784    #endif
785    #if BAPE_CHIP_MAX_DACS > 2
786    case BAPE_MclkSource_eHifidac2:
787        pllclksel = BCHP_AUD_FMM_OP_CTRL_MCLK_CFG_MAI_MULTI_PLLCLKSEL_Hifidac2;
788        break;
789    #endif
790
791    /* NCO (Mclkgen) Timing */
792    #if BAPE_CHIP_MAX_NCOS > 0
793    case BAPE_MclkSource_eNco0:
794        pllclksel = BCHP_AUD_FMM_OP_CTRL_MCLK_CFG_MAI_MULTI_PLLCLKSEL_Mclk_gen0;
795        break;
796    #endif
797    #if BAPE_CHIP_MAX_NCOS > 1
798    case BAPE_MclkSource_eNco1:
799        pllclksel = BCHP_AUD_FMM_OP_CTRL_MCLK_CFG_MAI_MULTI_PLLCLKSEL_Mclk_gen1;
800        break;
801    #endif
802    #if BAPE_CHIP_MAX_NCOS > 2
803    case BAPE_MclkSource_eNco2:
804        pllclksel = BCHP_AUD_FMM_OP_CTRL_MCLK_CFG_MAI_MULTI_PLLCLKSEL_Mclk_gen2;
805        break;
806    #endif
807
808    /* Should never get here */
809    default:
810        BDBG_ERR(("mclkSource (%u) doesn't refer to a valid PLL DAC, or NCO", mclkSource));
811        BDBG_ASSERT(false);     /* something went wrong somewhere! */
812        return;
813    }
814
815    /* Tell the output formatter how fast our mclk is. */
816    mclkRate = mclkFreqToFsRatio / ( 2 * 64 );  /* MAI has sclk = 64Fs */
817
818    regVal = BREG_Read32_isr(handle->deviceHandle->regHandle, BCHP_AUD_FMM_OP_CTRL_MCLK_CFG_MAI_MULTI);
819    regVal &= ~(BCHP_MASK(AUD_FMM_OP_CTRL_MCLK_CFG_MAI_MULTI, PLLCLKSEL)|
820                BCHP_MASK(AUD_FMM_OP_CTRL_MCLK_CFG_MAI_MULTI, MCLK_RATE));
821    regVal |= BCHP_FIELD_DATA(AUD_FMM_OP_CTRL_MCLK_CFG_MAI_MULTI, MCLK_RATE, mclkRate);
822    regVal |= BCHP_FIELD_DATA(AUD_FMM_OP_CTRL_MCLK_CFG_MAI_MULTI, PLLCLKSEL, pllclksel);
823    BREG_Write32_isr(handle->deviceHandle->regHandle, BCHP_AUD_FMM_OP_CTRL_MCLK_CFG_MAI_MULTI, regVal);
824}
825
826static BERR_Code BAPE_MaiOutput_P_Enable_Legacy(BAPE_OutputPort output)
827{
828    BAPE_IopStreamSettings streamSettings;
829    BERR_Code errCode;
830    unsigned streamId;
831   
832    BAPE_MaiOutputHandle handle;
833    BAPE_MixerHandle mixer;
834    BREG_Handle regHandle;
835    uint32_t regVal, regAddr;
836    unsigned i;
837   
838    BDBG_OBJECT_ASSERT(output, BAPE_OutputPort);
839
840    handle = output->pHandle;
841    BDBG_OBJECT_ASSERT(handle, BAPE_MaiOutput);
842    BDBG_ASSERT(false == handle->enabled);
843    BDBG_ASSERT(NULL != output->mixer);
844
845    mixer = output->mixer;
846    regHandle = handle->deviceHandle->regHandle;
847
848    BDBG_MSG(("Enabling %s", handle->name));
849
850    BDBG_ASSERT(mixer->numChannelPairs <= 4);
851
852    /* Set MAI/I2S Multi Grouping based on number of channel pairs */
853    regAddr = BCHP_AUD_FMM_OP_CTRL_MAI_MULTI_GROUPING;
854    #if 0 /* This grouping does not seem to be stable in HW.  If programmed, once in a handful of tries the HW doesn't start */
855    /* We need to write 1's in the fields that are multichannel.  For all stereo, write 0 */
856    if ( mixer->numChannelPairs == 1 )
857    {
858        BREG_Write32(regHandle, regAddr, 0);
859    }
860    else
861    {
862        BREG_Write32(regHandle, regAddr, 0xf>>(4-mixer->numChannelPairs));
863    }
864    #else
865    BREG_Write32(regHandle, regAddr, 0);
866    #endif
867
868    for ( i = 0; i < mixer->numChannelPairs; i++ )
869    {
870        streamId = GET_MAI_DATA_STREAM_ID(handle->index, i);
871        BDBG_MSG(("MAI Multi Payload [stream %u] source FCI 0x%x", streamId, output->sourceMixerFci.ids[i]));
872       
873        /* Write source FCI to IOP */
874        BAPE_Iop_P_GetStreamSettings(handle->deviceHandle, streamId, &streamSettings);
875        streamSettings.resolution = 24;
876        streamSettings.input = output->sourceMixerFci.ids[i];   /* Take source FCI provided from mixer */
877        errCode = BAPE_Iop_P_SetStreamSettings(handle->deviceHandle, streamId, &streamSettings);
878        if ( errCode )
879        {
880            handle->enabled = true;
881            BAPE_MaiOutput_P_Disable(output);
882            return BERR_TRACE(errCode);
883        }
884        BDBG_ASSERT(BERR_SUCCESS == errCode);
885    }
886
887    /* Enable MAI/I2S Multi for the proper number of channels */
888    regVal = 0;
889    for ( i = 0; i < mixer->numChannelPairs; i++ )
890    {
891        streamId = GET_MAI_DATA_STREAM_ID(handle->index, i);
892        BDBG_MSG(("Writing %x to enable set", (BCHP_MASK(AUD_FMM_OP_CTRL_ENABLE_SET, STREAM0_ENA))<<(streamId)));
893        regVal |= (BCHP_MASK(AUD_FMM_OP_CTRL_ENABLE_SET, STREAM0_ENA))<<(streamId);
894    }
895
896    /* Enable the formatter using HW channel status */
897    BKNI_EnterCriticalSection();
898    BAPE_MaiOutput_P_SetCbits_isr(handle);
899    BKNI_LeaveCriticalSection();
900
901    /* Enable I2S/MAI Multi */
902    BREG_Write32(regHandle, BCHP_AUD_FMM_OP_CTRL_ENABLE_SET, regVal);
903
904    handle->enabled = true;
905    return BERR_SUCCESS;
906}
907
908static void BAPE_MaiOutput_P_Disable_Legacy(BAPE_OutputPort output)
909{
910    BAPE_MaiOutputHandle handle;
911    BAPE_MixerHandle mixer;
912    BREG_Handle regHandle;
913    uint32_t regVal;
914    unsigned i;
915
916    BAPE_IopStreamSettings streamSettings;
917    BERR_Code errCode;
918    unsigned streamId;
919   
920    BDBG_OBJECT_ASSERT(output, BAPE_OutputPort);
921
922    handle = output->pHandle;
923    BDBG_OBJECT_ASSERT(handle, BAPE_MaiOutput);
924    BDBG_ASSERT(NULL != output->mixer);
925
926    mixer = output->mixer;
927    regHandle = handle->deviceHandle->regHandle;
928
929    BDBG_MSG(("Disabling %s", handle->name));
930
931    /* Disable the MAI/I2S Multi streams */
932    regVal = 0;
933    for ( i = 0; i < mixer->numChannelPairs; i++ )
934    {
935        streamId = GET_MAI_DATA_STREAM_ID(handle->index, i);
936        regVal |= (BCHP_MASK(AUD_FMM_OP_CTRL_ENABLE_CLEAR, STREAM0_ENA))<<(streamId);
937    }
938    BREG_Write32(regHandle, BCHP_AUD_FMM_OP_CTRL_ENABLE_CLEAR, regVal);
939
940    /* Clear out FCI ID's */
941    for ( i = 0; i < mixer->numChannelPairs; i++ )
942    {
943        streamId = GET_MAI_DATA_STREAM_ID(handle->index, i);
944        /* Write source FCI to IOP */
945        BAPE_Iop_P_GetStreamSettings(handle->deviceHandle, streamId, &streamSettings);
946        streamSettings.input = BAPE_FCI_ID_INVALID;
947        errCode = BAPE_Iop_P_SetStreamSettings(handle->deviceHandle, streamId, &streamSettings);
948        BDBG_ASSERT(BERR_SUCCESS == errCode);
949    }
950
951    handle->enabled = false;
952}
953
954static BERR_Code BAPE_MaiOutput_P_OpenHw_Legacy(BAPE_MaiOutputHandle handle)
955{
956    BERR_Code       errCode = BERR_SUCCESS;
957    BAPE_Handle     deviceHandle;
958    uint32_t        streamId;
959
960    BAPE_Reg_P_FieldList regFieldList;
961    BAPE_IopStreamSettings streamSettings;
962
963    BDBG_OBJECT_ASSERT(handle, BAPE_MaiOutput);
964
965    deviceHandle = handle->deviceHandle;
966    BDBG_OBJECT_ASSERT(deviceHandle, BAPE_Device);
967
968    BDBG_ASSERT(handle->index == 0);
969
970    /* Always source MAI timing and data from I2S Multi or MAI Multi.  CSTAT comes from the second formatter.  */
971    BAPE_Reg_P_InitFieldList(handle->deviceHandle, &regFieldList);
972    BAPE_Reg_P_AddEnumToFieldList(&regFieldList, AUD_FMM_OP_CTRL_STREAM_ROUTE, STRM1_TMG_SRC_SEL, MAI_Multi);
973    BAPE_Reg_P_AddEnumToFieldList(&regFieldList, AUD_FMM_OP_CTRL_STREAM_ROUTE, MAI_PAYLOAD_SEL, MAI_Multi);
974    BAPE_Reg_P_AddEnumToFieldList(&regFieldList, AUD_FMM_OP_CTRL_STREAM_ROUTE, MAI_CSTAT_SEL, STRM1);
975    #ifdef BCHP_AUD_FMM_OP_CTRL_STREAM_ROUTE_HBR_ENABLE_MASK
976    BAPE_Reg_P_AddToFieldList(&regFieldList, AUD_FMM_OP_CTRL_STREAM_ROUTE, HBR_ENABLE, 0);
977    #endif
978    BAPE_Reg_P_ApplyFieldList(&regFieldList, BCHP_AUD_FMM_OP_CTRL_STREAM_ROUTE);
979
980    /* The data going to the MS doesn't matter.  Set it to an invalid FCI ID */
981    streamId = GET_MAI_CBIT_STREAM_ID(handle->index);
982    BDBG_MSG(("MAI Channel Status [stream %u] source FCI 0x%x", streamId, BAPE_FCI_ID_INVALID));
983
984    /* Write dummy source FCI to IOP */
985    BAPE_Iop_P_GetStreamSettings(handle->deviceHandle, streamId, &streamSettings);
986    streamSettings.resolution = 24;
987    streamSettings.input = BAPE_FCI_ID_INVALID;
988    errCode = BAPE_Iop_P_SetStreamSettings(handle->deviceHandle, streamId, &streamSettings);
989    if ( errCode )
990    {
991        return BERR_TRACE(errCode);
992    }
993
994    /* Enable MAI Cbit stream */
995    BAPE_Reg_P_UpdateField(handle->deviceHandle, BCHP_AUD_FMM_OP_CTRL_ENABLE_SET, AUD_FMM_OP_CTRL_ENABLE_SET, STREAM1_ENA, 1);
996
997    /* Setup Channel Status Formatter and enable always.  This solves a lot of receiver compatibility issues. */
998    BKNI_EnterCriticalSection();
999    {
1000        BAPE_MaiOutput_P_SetCbits_isr(handle);
1001
1002        /* Setup for HW cbit generation */
1003        BAPE_Reg_P_InitFieldList(handle->deviceHandle, &regFieldList);
1004        BAPE_Reg_P_AddEnumToFieldList_isr(&regFieldList, AUD_FMM_MS_CTRL_FW_STREAM_CTRL_1, OVERWRITE_DATA, Disable);
1005        BAPE_Reg_P_AddEnumToFieldList_isr(&regFieldList, AUD_FMM_MS_CTRL_FW_STREAM_CTRL_1, STREAM_ENA, Enable);
1006        BAPE_Reg_P_ApplyFieldList_isr(&regFieldList, BCHP_AUD_FMM_MS_CTRL_FW_STREAM_CTRL_1);
1007
1008        BAPE_Reg_P_UpdateEnum_isr(handle->deviceHandle, BCHP_AUD_FMM_MS_CTRL_USEQ_BYPASS, AUD_FMM_MS_CTRL_USEQ_BYPASS, STREAM1, Bypass);
1009
1010        /* Enable formatter */
1011        BAPE_Reg_P_UpdateEnum_isr(handle->deviceHandle, BCHP_AUD_FMM_MS_CTRL_HW_SPDIF_CFG_1, AUD_FMM_MS_CTRL_HW_SPDIF_CFG_1, ENABLE, Enable);
1012    }
1013    BKNI_LeaveCriticalSection();
1014   
1015    /* Enable MAI Bus */
1016    BAPE_Reg_P_InitFieldList(handle->deviceHandle, &regFieldList);
1017    BAPE_Reg_P_AddEnumToFieldList(&regFieldList, AUD_FMM_OP_CTRL_MAI_CFG, SPDIF_MODE, SPDIF_Format);
1018    BAPE_Reg_P_AddEnumToFieldList(&regFieldList, AUD_FMM_OP_CTRL_MAI_CFG, ENABLE_MAI, Enable);
1019    BAPE_Reg_P_ApplyFieldList(&regFieldList, BCHP_AUD_FMM_OP_CTRL_MAI_CFG);
1020
1021    return errCode;
1022}
1023
1024static void BAPE_MaiOutput_P_CloseHw_Legacy(BAPE_MaiOutputHandle handle)
1025{
1026    uint32_t        streamId;
1027
1028    /* Disable STREAM1/MAI */
1029    streamId = GET_MAI_CBIT_STREAM_ID(handle->index);
1030    BAPE_Reg_P_UpdateField(handle->deviceHandle, BCHP_AUD_FMM_OP_CTRL_ENABLE_CLEAR, AUD_FMM_OP_CTRL_ENABLE_CLEAR, STREAM1_ENA, 1);
1031
1032    /* Disable microsequencer */
1033    BKNI_EnterCriticalSection();
1034    {
1035        BAPE_Reg_P_UpdateEnum_isr(handle->deviceHandle, BCHP_AUD_FMM_MS_CTRL_STRM_ENA, AUD_FMM_MS_CTRL_STRM_ENA, STREAM1_ENA, Disable);
1036    }
1037    BKNI_LeaveCriticalSection();
1038}
1039
1040static void      BAPE_MaiOutput_P_SetCrossbar_Legacy(BAPE_MaiOutputHandle handle, BAPE_StereoMode stereoMode)
1041{
1042    uint32_t regVal;
1043
1044    BDBG_OBJECT_ASSERT(handle, BAPE_MaiOutput);
1045
1046    /* Setup the MAI output crossbar to properly assign the channel order for HDMI. */
1047    /* HDMI expects L R LFE C Ls Rs Lr Rr, we output L R Ls Rs C LFE Lr Rr */
1048    regVal = BREG_Read32(handle->deviceHandle->regHandle, BCHP_AUD_FMM_OP_CTRL_MAI_CROSSBAR);
1049    regVal &= ~(BCHP_MASK(AUD_FMM_OP_CTRL_MAI_CROSSBAR, OUT0)|
1050                BCHP_MASK(AUD_FMM_OP_CTRL_MAI_CROSSBAR, OUT1)|
1051                BCHP_MASK(AUD_FMM_OP_CTRL_MAI_CROSSBAR, OUT2)|
1052                BCHP_MASK(AUD_FMM_OP_CTRL_MAI_CROSSBAR, OUT3)|
1053                BCHP_MASK(AUD_FMM_OP_CTRL_MAI_CROSSBAR, OUT4)|
1054                BCHP_MASK(AUD_FMM_OP_CTRL_MAI_CROSSBAR, OUT5)|
1055                BCHP_MASK(AUD_FMM_OP_CTRL_MAI_CROSSBAR, OUT6)|
1056                BCHP_MASK(AUD_FMM_OP_CTRL_MAI_CROSSBAR, OUT7));
1057    switch ( stereoMode )
1058    {
1059    default:
1060    case BAPE_StereoMode_eLeftRight:
1061        regVal |= BCHP_FIELD_ENUM(AUD_FMM_OP_CTRL_MAI_CROSSBAR, OUT0, In0_l);
1062        regVal |= BCHP_FIELD_ENUM(AUD_FMM_OP_CTRL_MAI_CROSSBAR, OUT1, In0_r);
1063        regVal |= BCHP_FIELD_ENUM(AUD_FMM_OP_CTRL_MAI_CROSSBAR, OUT2, In1_l);
1064        regVal |= BCHP_FIELD_ENUM(AUD_FMM_OP_CTRL_MAI_CROSSBAR, OUT3, In1_r);
1065        regVal |= BCHP_FIELD_ENUM(AUD_FMM_OP_CTRL_MAI_CROSSBAR, OUT4, In2_l);
1066        regVal |= BCHP_FIELD_ENUM(AUD_FMM_OP_CTRL_MAI_CROSSBAR, OUT5, In2_r);
1067        regVal |= BCHP_FIELD_ENUM(AUD_FMM_OP_CTRL_MAI_CROSSBAR, OUT6, In3_l);
1068        regVal |= BCHP_FIELD_ENUM(AUD_FMM_OP_CTRL_MAI_CROSSBAR, OUT7, In3_r);
1069        break;
1070    case BAPE_StereoMode_eLeftLeft:
1071        regVal |= BCHP_FIELD_ENUM(AUD_FMM_OP_CTRL_MAI_CROSSBAR, OUT0, In0_l);
1072        regVal |= BCHP_FIELD_ENUM(AUD_FMM_OP_CTRL_MAI_CROSSBAR, OUT1, In0_l);
1073        regVal |= BCHP_FIELD_ENUM(AUD_FMM_OP_CTRL_MAI_CROSSBAR, OUT2, In1_l);
1074        regVal |= BCHP_FIELD_ENUM(AUD_FMM_OP_CTRL_MAI_CROSSBAR, OUT3, In1_l);
1075        regVal |= BCHP_FIELD_ENUM(AUD_FMM_OP_CTRL_MAI_CROSSBAR, OUT4, In2_l);
1076        regVal |= BCHP_FIELD_ENUM(AUD_FMM_OP_CTRL_MAI_CROSSBAR, OUT5, In2_l);
1077        regVal |= BCHP_FIELD_ENUM(AUD_FMM_OP_CTRL_MAI_CROSSBAR, OUT6, In3_l);
1078        regVal |= BCHP_FIELD_ENUM(AUD_FMM_OP_CTRL_MAI_CROSSBAR, OUT7, In3_l);
1079        break;
1080    case BAPE_StereoMode_eRightRight:
1081        regVal |= BCHP_FIELD_ENUM(AUD_FMM_OP_CTRL_MAI_CROSSBAR, OUT0, In0_r);
1082        regVal |= BCHP_FIELD_ENUM(AUD_FMM_OP_CTRL_MAI_CROSSBAR, OUT1, In0_r);
1083        regVal |= BCHP_FIELD_ENUM(AUD_FMM_OP_CTRL_MAI_CROSSBAR, OUT2, In1_r);
1084        regVal |= BCHP_FIELD_ENUM(AUD_FMM_OP_CTRL_MAI_CROSSBAR, OUT3, In1_r);
1085        regVal |= BCHP_FIELD_ENUM(AUD_FMM_OP_CTRL_MAI_CROSSBAR, OUT4, In2_r);
1086        regVal |= BCHP_FIELD_ENUM(AUD_FMM_OP_CTRL_MAI_CROSSBAR, OUT5, In2_r);
1087        regVal |= BCHP_FIELD_ENUM(AUD_FMM_OP_CTRL_MAI_CROSSBAR, OUT6, In3_r);
1088        regVal |= BCHP_FIELD_ENUM(AUD_FMM_OP_CTRL_MAI_CROSSBAR, OUT7, In3_r);
1089        break;
1090    case BAPE_StereoMode_eRightLeft:
1091        regVal |= BCHP_FIELD_ENUM(AUD_FMM_OP_CTRL_MAI_CROSSBAR, OUT0, In0_r);
1092        regVal |= BCHP_FIELD_ENUM(AUD_FMM_OP_CTRL_MAI_CROSSBAR, OUT1, In0_l);
1093        regVal |= BCHP_FIELD_ENUM(AUD_FMM_OP_CTRL_MAI_CROSSBAR, OUT2, In1_r);
1094        regVal |= BCHP_FIELD_ENUM(AUD_FMM_OP_CTRL_MAI_CROSSBAR, OUT3, In1_l);
1095        regVal |= BCHP_FIELD_ENUM(AUD_FMM_OP_CTRL_MAI_CROSSBAR, OUT4, In2_r);
1096        regVal |= BCHP_FIELD_ENUM(AUD_FMM_OP_CTRL_MAI_CROSSBAR, OUT5, In2_l);
1097        regVal |= BCHP_FIELD_ENUM(AUD_FMM_OP_CTRL_MAI_CROSSBAR, OUT6, In3_r);
1098        regVal |= BCHP_FIELD_ENUM(AUD_FMM_OP_CTRL_MAI_CROSSBAR, OUT7, In3_l);
1099        break;
1100    }
1101    BREG_Write32(handle->deviceHandle->regHandle, BCHP_AUD_FMM_OP_CTRL_MAI_CROSSBAR, regVal);
1102}
1103
1104#else
1105/* 7429 style RDB */
1106static void BAPE_MaiOutput_P_SetCbits_IopOut_isr(BAPE_MaiOutputHandle handle)
1107{
1108    BAPE_Reg_P_FieldList regFieldList;
1109    uint32_t regAddr, regVal;
1110    bool compressed;
1111    unsigned validity;
1112
1113    BDBG_OBJECT_ASSERT(handle, BAPE_MaiOutput);
1114
1115    compressed = (handle->outputPort.mixer && handle->outputPort.mixer->compressed)?true:false;
1116
1117    BDBG_MSG(("Set MAI CBITS SR %u", handle->sampleRate));
1118
1119    /* Only set validity if we're outputting compressed */
1120    if ( compressed )
1121    {
1122        validity = 1;
1123    }
1124    else
1125    {
1126        validity = 0;
1127    }
1128
1129    /* Program MAI format correctly */
1130    if ( handle->outputPort.mixer )
1131    {
1132        regAddr = BCHP_AUD_FMM_IOP_OUT_MAI_0_MAI_FORMAT_WORD;
1133        BAPE_Reg_P_InitFieldList_isr(handle->deviceHandle, &regFieldList);
1134        if ( handle->outputPort.mixer->compressed )
1135        {
1136            BAPE_Reg_P_AddEnumToFieldList_isr(&regFieldList, AUD_FMM_IOP_OUT_MAI_0_MAI_FORMAT_WORD, AUDIO_FORMAT, Compressed_audio_2_channel);
1137            BAPE_Reg_P_AddToFieldList_isr(&regFieldList, AUD_FMM_IOP_OUT_MAI_0_MAI_FORMAT_WORD, SAMPLE_WIDTH, 16);
1138        }
1139        else
1140        {
1141            switch ( handle->outputPort.mixer->numChannelPairs )
1142            {
1143            case 3:
1144                BAPE_Reg_P_AddEnumToFieldList_isr(&regFieldList, AUD_FMM_IOP_OUT_MAI_0_MAI_FORMAT_WORD, AUDIO_FORMAT, SPDIF_linearPCM_6_channel);
1145                break;
1146            case 4:
1147                BAPE_Reg_P_AddEnumToFieldList_isr(&regFieldList, AUD_FMM_IOP_OUT_MAI_0_MAI_FORMAT_WORD, AUDIO_FORMAT, SPDIF_linearPCM_8_channel);
1148                break;
1149            default:
1150                BAPE_Reg_P_AddEnumToFieldList_isr(&regFieldList, AUD_FMM_IOP_OUT_MAI_0_MAI_FORMAT_WORD, AUDIO_FORMAT, SPDIF_linearPCM_stereo);
1151                break;
1152            }
1153            BAPE_Reg_P_AddToFieldList_isr(&regFieldList, AUD_FMM_IOP_OUT_MAI_0_MAI_FORMAT_WORD, SAMPLE_WIDTH, 0); /* 32 bits per sample */
1154        }
1155        BAPE_Reg_P_AddToFieldList_isr(&regFieldList, AUD_FMM_IOP_OUT_MAI_0_MAI_FORMAT_WORD, 
1156                                      SAMPLE_RATE, BAPE_MaiOutput_P_SampleRateToMaiFormat(handle->outputPort.mixer->sampleRate)); /* 32 bits per sample */
1157        BAPE_Reg_P_ApplyFieldList_isr(&regFieldList, regAddr);
1158    }
1159
1160    /* Tell the HW to hold the current CBITS and set dither correctly */
1161    regAddr = BCHP_AUD_FMM_IOP_OUT_MAI_0_SPDIF_CTRL;
1162    BAPE_Reg_P_InitFieldList_isr(handle->deviceHandle, &regFieldList);
1163    if ( handle->settings.ditherEnabled && !compressed )
1164    {
1165        BAPE_Reg_P_AddEnumToFieldList_isr(&regFieldList, AUD_FMM_IOP_OUT_MAI_0_SPDIF_CTRL, DITHER_ENA, Enable);
1166    }
1167    else
1168    {
1169        BAPE_Reg_P_AddEnumToFieldList_isr(&regFieldList, AUD_FMM_IOP_OUT_MAI_0_SPDIF_CTRL, DITHER_ENA, Disable);
1170    }
1171    BAPE_Reg_P_AddToFieldList_isr(&regFieldList, AUD_FMM_IOP_OUT_MAI_0_SPDIF_CTRL, VALIDITY, validity);
1172    BAPE_Reg_P_AddEnumToFieldList_isr(&regFieldList, AUD_FMM_IOP_OUT_MAI_0_SPDIF_CTRL, HOLD_CSTAT, Hold);
1173    BAPE_Reg_P_ApplyFieldList_isr(&regFieldList, regAddr);
1174
1175    /* Program channel status */
1176    if ( handle->settings.useRawChannelStatus )
1177    {
1178        regVal = 
1179            (uint32_t)handle->settings.rawChannelStatus[0] |
1180            (((uint32_t)handle->settings.rawChannelStatus[1])<<8) |
1181            (((uint32_t)handle->settings.rawChannelStatus[2])<<16) |
1182            (((uint32_t)handle->settings.rawChannelStatus[3])<<24);
1183        BAPE_Reg_P_Write_isr(handle->deviceHandle, BCHP_AUD_FMM_IOP_OUT_MAI_0_SPDIF_CHANSTAT_0, regVal);
1184        regVal = (uint32_t)handle->settings.rawChannelStatus[4];
1185        BAPE_Reg_P_Write_isr(handle->deviceHandle, BCHP_AUD_FMM_IOP_OUT_MAI_0_SPDIF_CHANSTAT_1, regVal);
1186    }
1187    else 
1188    {
1189        BAPE_Spdif_P_ChannelStatusBits cbits;
1190
1191        BAPE_P_MapSpdifChannelStatusToBits_isr(&handle->outputPort, &handle->settings.channelStatus, &cbits);
1192        BAPE_Reg_P_Write_isr(handle->deviceHandle, BCHP_AUD_FMM_IOP_OUT_MAI_0_SPDIF_CHANSTAT_0, cbits.bits[0]);
1193        BAPE_Reg_P_Write_isr(handle->deviceHandle, BCHP_AUD_FMM_IOP_OUT_MAI_0_SPDIF_CHANSTAT_1, cbits.bits[1]);
1194    }
1195
1196    /* Reload the new channel status in HW */
1197    BAPE_Reg_P_UpdateEnum_isr(handle->deviceHandle, BCHP_AUD_FMM_IOP_OUT_MAI_0_SPDIF_CTRL, AUD_FMM_IOP_OUT_MAI_0_SPDIF_CTRL, HOLD_CSTAT, Update);
1198
1199    return;
1200}
1201
1202static void BAPE_MaiOutput_P_SetMclk_IopOut_isr(BAPE_OutputPort output, BAPE_MclkSource mclkSource, unsigned pllChannel, unsigned mclkFreqToFsRatio)
1203{
1204    BAPE_Reg_P_FieldList regFieldList;
1205
1206    BAPE_MaiOutputHandle handle;
1207
1208    BDBG_OBJECT_ASSERT(output, BAPE_OutputPort);
1209
1210    handle = output->pHandle;
1211    BDBG_OBJECT_ASSERT(handle, BAPE_MaiOutput);
1212    BDBG_ASSERT(handle->offset == 0);
1213
1214    /* Save the settings in case we need to re-apply them later. */
1215    handle->mclkInfo.mclkSource         = mclkSource;
1216    handle->mclkInfo.pllChannel         = pllChannel;
1217    handle->mclkInfo.mclkFreqToFsRatio  = mclkFreqToFsRatio;
1218
1219    BAPE_Reg_P_InitFieldList(handle->deviceHandle, &regFieldList);
1220
1221    switch ( mclkSource )
1222    {
1223#ifdef BCHP_AUD_FMM_IOP_OUT_MAI_0_MCLK_CFG_0_PLLCLKSEL_PLL0_ch1
1224    case BAPE_MclkSource_ePll0:
1225        switch ( pllChannel )
1226        {
1227        case 0: BAPE_Reg_P_AddEnumToFieldList(&regFieldList, AUD_FMM_IOP_OUT_MAI_0_MCLK_CFG_0, PLLCLKSEL, PLL0_ch1); break;
1228        case 1: BAPE_Reg_P_AddEnumToFieldList(&regFieldList, AUD_FMM_IOP_OUT_MAI_0_MCLK_CFG_0, PLLCLKSEL, PLL0_ch2); break;
1229        case 2: BAPE_Reg_P_AddEnumToFieldList(&regFieldList, AUD_FMM_IOP_OUT_MAI_0_MCLK_CFG_0, PLLCLKSEL, PLL0_ch3); break;               
1230        default: (void) BERR_TRACE(BERR_NOT_SUPPORTED); break;
1231        }
1232        break;
1233#endif
1234#ifdef BCHP_AUD_FMM_IOP_OUT_MAI_0_MCLK_CFG_0_PLLCLKSEL_PLL1_ch1
1235    case BAPE_MclkSource_ePll1:
1236        switch ( pllChannel )
1237        {
1238        case 0: BAPE_Reg_P_AddEnumToFieldList(&regFieldList, AUD_FMM_IOP_OUT_MAI_0_MCLK_CFG_0, PLLCLKSEL, PLL1_ch1); break;
1239        case 1: BAPE_Reg_P_AddEnumToFieldList(&regFieldList, AUD_FMM_IOP_OUT_MAI_0_MCLK_CFG_0, PLLCLKSEL, PLL1_ch2); break;
1240        case 2: BAPE_Reg_P_AddEnumToFieldList(&regFieldList, AUD_FMM_IOP_OUT_MAI_0_MCLK_CFG_0, PLLCLKSEL, PLL1_ch3); break;               
1241        default: (void) BERR_TRACE(BERR_NOT_SUPPORTED); break;
1242        }
1243        break;
1244#endif
1245#ifdef BCHP_AUD_FMM_IOP_OUT_MAI_0_MCLK_CFG_0_PLLCLKSEL_PLL2_ch1
1246    case BAPE_MclkSource_ePll2:
1247        switch ( pllChannel )
1248        {
1249        case 0: BAPE_Reg_P_AddEnumToFieldList(&regFieldList, AUD_FMM_IOP_OUT_MAI_0_MCLK_CFG_0, PLLCLKSEL, PLL2_ch1); break;
1250        case 1: BAPE_Reg_P_AddEnumToFieldList(&regFieldList, AUD_FMM_IOP_OUT_MAI_0_MCLK_CFG_0, PLLCLKSEL, PLL2_ch2); break;
1251        case 2: BAPE_Reg_P_AddEnumToFieldList(&regFieldList, AUD_FMM_IOP_OUT_MAI_0_MCLK_CFG_0, PLLCLKSEL, PLL2_ch3); break;               
1252        default: (void) BERR_TRACE(BERR_NOT_SUPPORTED); break;
1253        }
1254        break;
1255#endif
1256#ifdef BCHP_AUD_FMM_IOP_OUT_MAI_0_MCLK_CFG_0_PLLCLKSEL_Mclk_gen0
1257    case BAPE_MclkSource_eNco0:
1258        BAPE_Reg_P_AddEnumToFieldList(&regFieldList, AUD_FMM_IOP_OUT_MAI_0_MCLK_CFG_0, PLLCLKSEL, Mclk_gen0); 
1259        break;
1260#endif
1261#ifdef BCHP_AUD_FMM_IOP_OUT_MAI_0_MCLK_CFG_0_PLLCLKSEL_Mclk_gen1
1262    case BAPE_MclkSource_eNco1:
1263        BAPE_Reg_P_AddEnumToFieldList(&regFieldList, AUD_FMM_IOP_OUT_MAI_0_MCLK_CFG_0, PLLCLKSEL, Mclk_gen1); 
1264        break;
1265#endif
1266#ifdef BCHP_AUD_FMM_IOP_OUT_MAI_0_MCLK_CFG_0_PLLCLKSEL_Mclk_gen2
1267    case BAPE_MclkSource_eNco2:
1268        BAPE_Reg_P_AddEnumToFieldList(&regFieldList, AUD_FMM_IOP_OUT_MAI_0_MCLK_CFG_0, PLLCLKSEL, Mclk_gen2); 
1269        break;
1270#endif
1271    default:
1272        BDBG_ERR(("Unsupported clock source %u for MAI %u", mclkSource, handle->index));
1273        (void)BERR_TRACE(BERR_NOT_SUPPORTED);
1274    }
1275
1276    switch ( mclkFreqToFsRatio )
1277    {
1278    case 128: BAPE_Reg_P_AddEnumToFieldList(&regFieldList, AUD_FMM_IOP_OUT_MAI_0_MCLK_CFG_0, MCLK_RATE, MCLK_128fs_SCLK_64fs); break;
1279    case 256: BAPE_Reg_P_AddEnumToFieldList(&regFieldList, AUD_FMM_IOP_OUT_MAI_0_MCLK_CFG_0, MCLK_RATE, MCLK_256fs_SCLK_64fs); break;
1280    case 384: BAPE_Reg_P_AddEnumToFieldList(&regFieldList, AUD_FMM_IOP_OUT_MAI_0_MCLK_CFG_0, MCLK_RATE, MCLK_384fs_SCLK_64fs); break;
1281    case 512: BAPE_Reg_P_AddEnumToFieldList(&regFieldList, AUD_FMM_IOP_OUT_MAI_0_MCLK_CFG_0, MCLK_RATE, MCLK_512fs_SCLK_64fs); break;
1282    default:
1283        BDBG_ERR(("Unsupported MCLK Rate of %uFs", mclkFreqToFsRatio));
1284        (void)BERR_TRACE(BERR_NOT_SUPPORTED);
1285        break;
1286    }
1287    BAPE_Reg_P_ApplyFieldList(&regFieldList, BCHP_AUD_FMM_IOP_OUT_MAI_0_MCLK_CFG_0);
1288}
1289
1290static BERR_Code BAPE_MaiOutput_P_Enable_IopOut(BAPE_OutputPort output)
1291{
1292    BAPE_Reg_P_FieldList regFieldList;
1293    BAPE_MaiOutputHandle handle;
1294    BAPE_MixerHandle mixer;
1295    uint32_t regAddr;
1296    unsigned i;
1297   
1298    BDBG_OBJECT_ASSERT(output, BAPE_OutputPort);
1299
1300    handle = output->pHandle;
1301    BDBG_OBJECT_ASSERT(handle, BAPE_MaiOutput);
1302    BDBG_ASSERT(false == handle->enabled);
1303    BDBG_ASSERT(NULL != output->mixer);
1304
1305    mixer = output->mixer;
1306
1307    BDBG_MSG(("Enabling %s", handle->name));
1308
1309    BDBG_ASSERT(mixer->numChannelPairs <= 4);
1310
1311    for ( i = 0; i < mixer->numChannelPairs; i++ )
1312    {
1313        regAddr = BAPE_Reg_P_GetArrayAddress(AUD_FMM_IOP_OUT_MAI_0_STREAM_CFG_i, i);
1314        BAPE_Reg_P_InitFieldList(handle->deviceHandle, &regFieldList);
1315        #if 0   /* TODO: Same issue as older chips.  This does not appear to be stable. */
1316        BAPE_Reg_P_AddToFieldList(&regFieldList, AUD_FMM_IOP_OUT_MAI_0_STREAM_CFG_i, GROUP_ID, 0);
1317        BAPE_Reg_P_AddToFieldList(&regFieldList, AUD_FMM_IOP_OUT_MAI_0_STREAM_CFG_i, CHANNEL_GROUPING, 0xf>>(4-mixer->numChannelPairs));
1318        #else
1319        BAPE_Reg_P_AddToFieldList(&regFieldList, AUD_FMM_IOP_OUT_MAI_0_STREAM_CFG_i, GROUP_ID, i);
1320        BAPE_Reg_P_AddToFieldList(&regFieldList, AUD_FMM_IOP_OUT_MAI_0_STREAM_CFG_i, CHANNEL_GROUPING, 1);
1321        #endif
1322        BAPE_Reg_P_AddEnumToFieldList(&regFieldList, AUD_FMM_IOP_OUT_MAI_0_STREAM_CFG_i, STREAM_BIT_RESOLUTION, Res_24_Bit); 
1323        BAPE_Reg_P_AddToFieldList(&regFieldList, AUD_FMM_IOP_OUT_MAI_0_STREAM_CFG_i, FCI_ID, output->sourceMixerFci.ids[i]);
1324        BAPE_Reg_P_ApplyFieldList(&regFieldList, regAddr);       
1325    }
1326    for ( ; i <= BCHP_AUD_FMM_IOP_OUT_MAI_0_STREAM_CFG_i_ARRAY_END; i++ )
1327    {
1328        regAddr = BAPE_Reg_P_GetArrayAddress(AUD_FMM_IOP_OUT_MAI_0_STREAM_CFG_i, i);
1329        BAPE_Reg_P_InitFieldList(handle->deviceHandle, &regFieldList);
1330        BAPE_Reg_P_AddToFieldList(&regFieldList, AUD_FMM_IOP_OUT_MAI_0_STREAM_CFG_i, GROUP_ID, i);
1331        BAPE_Reg_P_AddToFieldList(&regFieldList, AUD_FMM_IOP_OUT_MAI_0_STREAM_CFG_i, CHANNEL_GROUPING, 1);
1332        BAPE_Reg_P_ApplyFieldList(&regFieldList, regAddr);       
1333    }
1334
1335    /* Update CBITS */
1336    BKNI_EnterCriticalSection();
1337    BAPE_MaiOutput_P_SetCbits_isr(handle);
1338    BKNI_LeaveCriticalSection();
1339
1340    /* Set source to MAI Multi always */
1341    regAddr = BCHP_AUD_FMM_IOP_OUT_MAI_0_MAI_FORMAT_CFG;
1342    BAPE_Reg_P_InitFieldList(handle->deviceHandle, &regFieldList);
1343    BAPE_Reg_P_AddEnumToFieldList(&regFieldList, AUD_FMM_IOP_OUT_MAI_0_MAI_FORMAT_CFG, SPDIF_MODE, SPDIF_Format);
1344    BAPE_Reg_P_AddEnumToFieldList(&regFieldList, AUD_FMM_IOP_OUT_MAI_0_MAI_FORMAT_CFG, MAI_PAYLOAD_SEL, MAI_Multi);
1345    BAPE_Reg_P_ApplyFieldList(&regFieldList, regAddr);
1346
1347    /* Enable the interface. */
1348    for ( i = 0; i < mixer->numChannelPairs; i++ )
1349    {
1350        regAddr = BAPE_Reg_P_GetArrayAddress(AUD_FMM_IOP_OUT_MAI_0_STREAM_CFG_i, i);
1351        BAPE_Reg_P_UpdateField(handle->deviceHandle, regAddr, AUD_FMM_IOP_OUT_MAI_0_STREAM_CFG_i, ENA, 1);
1352    }
1353
1354    /* Enable the MAI bus - This must be done last to make older Onkyo receivers happy switching from DTS->PCM */
1355    /* TBD: How is this handled on 7429? */
1356
1357    handle->enabled = true;
1358    return BERR_SUCCESS;
1359}
1360
1361static void BAPE_MaiOutput_P_Disable_IopOut(BAPE_OutputPort output)
1362{
1363    BAPE_MaiOutputHandle handle;
1364    BAPE_MixerHandle mixer;
1365    BAPE_Reg_P_FieldList regFieldList;
1366    uint32_t regAddr;
1367    unsigned i;
1368
1369    BDBG_OBJECT_ASSERT(output, BAPE_OutputPort);
1370
1371    handle = output->pHandle;
1372    BDBG_OBJECT_ASSERT(handle, BAPE_MaiOutput);
1373    BDBG_ASSERT(NULL != output->mixer);
1374
1375    mixer = output->mixer;
1376
1377    BDBG_MSG(("Disabling %s", handle->name));
1378
1379    /* TODO: Disable the MAI bus? */
1380
1381    /* Disable the MAI streams */
1382    for ( i = 0; i < mixer->numChannelPairs; i++ )
1383    {
1384        regAddr = BAPE_Reg_P_GetArrayAddress(AUD_FMM_IOP_OUT_MAI_0_STREAM_CFG_i, i);
1385        BAPE_Reg_P_UpdateField(handle->deviceHandle, regAddr, AUD_FMM_IOP_OUT_MAI_0_STREAM_CFG_i, ENA, 0);
1386    }
1387
1388    /* Clear out FCI ID's */
1389    for ( i = 0; i < mixer->numChannelPairs; i++ )
1390    {
1391        regAddr = BAPE_Reg_P_GetArrayAddress(AUD_FMM_IOP_OUT_MAI_0_STREAM_CFG_i, i);
1392        BAPE_Reg_P_UpdateField(handle->deviceHandle, regAddr, AUD_FMM_IOP_OUT_MAI_0_STREAM_CFG_i, FCI_ID, BAPE_FCI_ID_INVALID);
1393    }
1394
1395    /* Revert to stereo mode */
1396    BAPE_Reg_P_InitFieldList(handle->deviceHandle, &regFieldList);
1397    BAPE_Reg_P_AddEnumToFieldList(&regFieldList, AUD_FMM_IOP_OUT_MAI_0_MAI_FORMAT_CFG, SPDIF_MODE, SPDIF_Format);
1398    BAPE_Reg_P_AddEnumToFieldList(&regFieldList, AUD_FMM_IOP_OUT_MAI_0_MAI_FORMAT_CFG, MAI_PAYLOAD_SEL, Stereo);
1399    BAPE_Reg_P_ApplyFieldList(&regFieldList, BCHP_AUD_FMM_IOP_OUT_MAI_0_MAI_FORMAT_CFG);
1400
1401    handle->enabled = false;
1402}
1403
1404static BERR_Code BAPE_MaiOutput_P_OpenHw_IopOut(BAPE_MaiOutputHandle handle)
1405{
1406    BERR_Code       errCode = BERR_SUCCESS;
1407    BAPE_Handle     deviceHandle;
1408
1409    BDBG_OBJECT_ASSERT(handle, BAPE_MaiOutput);
1410
1411    deviceHandle = handle->deviceHandle;
1412    BDBG_OBJECT_ASSERT(deviceHandle, BAPE_Device);
1413
1414    BDBG_ASSERT(handle->index == 0);
1415
1416    /* Always source MAI timing from I2S Multi or MAI Multi.  */
1417    BAPE_Reg_P_UpdateEnum(handle->deviceHandle, BCHP_AUD_FMM_IOP_OUT_MAI_0_MAI_FORMAT_CFG, AUD_FMM_IOP_OUT_MAI_0_MAI_FORMAT_CFG, MAI_PAYLOAD_SEL, MAI_Multi);
1418
1419    return errCode;
1420}
1421
1422static void BAPE_MaiOutput_P_CloseHw_IopOut(BAPE_MaiOutputHandle handle)
1423{
1424    BSTD_UNUSED(handle);
1425    return;
1426}
1427
1428static void      BAPE_MaiOutput_P_SetCrossbar_IopOut(BAPE_MaiOutputHandle handle, BAPE_StereoMode stereoMode)
1429{
1430    BAPE_Reg_P_FieldList regFieldList;
1431
1432    BDBG_OBJECT_ASSERT(handle, BAPE_MaiOutput);
1433
1434    /* Setup the MAI output crossbar to properly assign the channel order for HDMI. */
1435    /* HDMI expects L R LFE C Ls Rs Lr Rr, we output L R Ls Rs C LFE Lr Rr */
1436    BAPE_Reg_P_InitFieldList(handle->deviceHandle, &regFieldList);
1437    switch ( stereoMode )
1438    {
1439    default:
1440    case BAPE_StereoMode_eLeftRight:
1441        BAPE_Reg_P_AddEnumToFieldList(&regFieldList, AUD_FMM_IOP_OUT_MAI_0_MAI_CROSSBAR, OUT0_L, In0_l);
1442        BAPE_Reg_P_AddEnumToFieldList(&regFieldList, AUD_FMM_IOP_OUT_MAI_0_MAI_CROSSBAR, OUT0_R, In0_r);
1443        BAPE_Reg_P_AddEnumToFieldList(&regFieldList, AUD_FMM_IOP_OUT_MAI_0_MAI_CROSSBAR, OUT1_L, In1_l);
1444        BAPE_Reg_P_AddEnumToFieldList(&regFieldList, AUD_FMM_IOP_OUT_MAI_0_MAI_CROSSBAR, OUT1_R, In1_r);
1445        BAPE_Reg_P_AddEnumToFieldList(&regFieldList, AUD_FMM_IOP_OUT_MAI_0_MAI_CROSSBAR, OUT2_L, In2_l);
1446        BAPE_Reg_P_AddEnumToFieldList(&regFieldList, AUD_FMM_IOP_OUT_MAI_0_MAI_CROSSBAR, OUT2_R, In2_r);
1447        BAPE_Reg_P_AddEnumToFieldList(&regFieldList, AUD_FMM_IOP_OUT_MAI_0_MAI_CROSSBAR, OUT3_L, In3_l);
1448        BAPE_Reg_P_AddEnumToFieldList(&regFieldList, AUD_FMM_IOP_OUT_MAI_0_MAI_CROSSBAR, OUT3_R, In3_r);
1449        break;
1450    case BAPE_StereoMode_eLeftLeft:
1451        BAPE_Reg_P_AddEnumToFieldList(&regFieldList, AUD_FMM_IOP_OUT_MAI_0_MAI_CROSSBAR, OUT0_L, In0_l);
1452        BAPE_Reg_P_AddEnumToFieldList(&regFieldList, AUD_FMM_IOP_OUT_MAI_0_MAI_CROSSBAR, OUT0_R, In0_l);
1453        BAPE_Reg_P_AddEnumToFieldList(&regFieldList, AUD_FMM_IOP_OUT_MAI_0_MAI_CROSSBAR, OUT1_L, In1_l);
1454        BAPE_Reg_P_AddEnumToFieldList(&regFieldList, AUD_FMM_IOP_OUT_MAI_0_MAI_CROSSBAR, OUT1_R, In1_l);
1455        BAPE_Reg_P_AddEnumToFieldList(&regFieldList, AUD_FMM_IOP_OUT_MAI_0_MAI_CROSSBAR, OUT2_L, In2_l);
1456        BAPE_Reg_P_AddEnumToFieldList(&regFieldList, AUD_FMM_IOP_OUT_MAI_0_MAI_CROSSBAR, OUT2_R, In2_l);
1457        BAPE_Reg_P_AddEnumToFieldList(&regFieldList, AUD_FMM_IOP_OUT_MAI_0_MAI_CROSSBAR, OUT3_L, In3_l);
1458        BAPE_Reg_P_AddEnumToFieldList(&regFieldList, AUD_FMM_IOP_OUT_MAI_0_MAI_CROSSBAR, OUT3_R, In3_l);
1459        break;
1460    case BAPE_StereoMode_eRightRight:
1461        BAPE_Reg_P_AddEnumToFieldList(&regFieldList, AUD_FMM_IOP_OUT_MAI_0_MAI_CROSSBAR, OUT0_L, In0_r);
1462        BAPE_Reg_P_AddEnumToFieldList(&regFieldList, AUD_FMM_IOP_OUT_MAI_0_MAI_CROSSBAR, OUT0_R, In0_r);
1463        BAPE_Reg_P_AddEnumToFieldList(&regFieldList, AUD_FMM_IOP_OUT_MAI_0_MAI_CROSSBAR, OUT1_L, In1_r);
1464        BAPE_Reg_P_AddEnumToFieldList(&regFieldList, AUD_FMM_IOP_OUT_MAI_0_MAI_CROSSBAR, OUT1_R, In1_r);
1465        BAPE_Reg_P_AddEnumToFieldList(&regFieldList, AUD_FMM_IOP_OUT_MAI_0_MAI_CROSSBAR, OUT2_L, In2_r);
1466        BAPE_Reg_P_AddEnumToFieldList(&regFieldList, AUD_FMM_IOP_OUT_MAI_0_MAI_CROSSBAR, OUT2_R, In2_r);
1467        BAPE_Reg_P_AddEnumToFieldList(&regFieldList, AUD_FMM_IOP_OUT_MAI_0_MAI_CROSSBAR, OUT3_L, In3_r);
1468        BAPE_Reg_P_AddEnumToFieldList(&regFieldList, AUD_FMM_IOP_OUT_MAI_0_MAI_CROSSBAR, OUT3_R, In3_r);
1469        break;
1470    case BAPE_StereoMode_eRightLeft:
1471        BAPE_Reg_P_AddEnumToFieldList(&regFieldList, AUD_FMM_IOP_OUT_MAI_0_MAI_CROSSBAR, OUT0_L, In0_r);
1472        BAPE_Reg_P_AddEnumToFieldList(&regFieldList, AUD_FMM_IOP_OUT_MAI_0_MAI_CROSSBAR, OUT0_R, In0_l);
1473        BAPE_Reg_P_AddEnumToFieldList(&regFieldList, AUD_FMM_IOP_OUT_MAI_0_MAI_CROSSBAR, OUT1_L, In1_r);
1474        BAPE_Reg_P_AddEnumToFieldList(&regFieldList, AUD_FMM_IOP_OUT_MAI_0_MAI_CROSSBAR, OUT1_R, In1_l);
1475        BAPE_Reg_P_AddEnumToFieldList(&regFieldList, AUD_FMM_IOP_OUT_MAI_0_MAI_CROSSBAR, OUT2_L, In2_r);
1476        BAPE_Reg_P_AddEnumToFieldList(&regFieldList, AUD_FMM_IOP_OUT_MAI_0_MAI_CROSSBAR, OUT2_R, In2_l);
1477        BAPE_Reg_P_AddEnumToFieldList(&regFieldList, AUD_FMM_IOP_OUT_MAI_0_MAI_CROSSBAR, OUT3_L, In3_r);
1478        BAPE_Reg_P_AddEnumToFieldList(&regFieldList, AUD_FMM_IOP_OUT_MAI_0_MAI_CROSSBAR, OUT3_R, In3_l);
1479        break;
1480    }
1481    BAPE_Reg_P_ApplyFieldList(&regFieldList, BCHP_AUD_FMM_IOP_OUT_MAI_0_MAI_CROSSBAR);
1482}
1483#endif
1484
1485/***************************************************************************
1486    Define stub functions for when there are no I2S outputs.
1487***************************************************************************/
1488#else
1489/* No MAI output interface.  Use Stubs. */
1490
1491/**************************************************************************/
1492
1493void BAPE_MaiOutput_GetDefaultSettings(
1494    BAPE_MaiOutputSettings *pSettings
1495    )
1496{
1497    BSTD_UNUSED(pSettings);
1498}
1499
1500/**************************************************************************/
1501
1502BERR_Code BAPE_MaiOutput_Open(
1503    BAPE_Handle deviceHandle,
1504    unsigned index,
1505    const BAPE_MaiOutputSettings *pSettings,
1506    BAPE_MaiOutputHandle *pHandle             /* [out] */
1507    )
1508{
1509    BSTD_UNUSED(deviceHandle);
1510    BSTD_UNUSED(index);
1511    BSTD_UNUSED(pSettings);
1512    BSTD_UNUSED(pHandle);
1513    return BERR_TRACE(BERR_NOT_SUPPORTED);
1514}
1515
1516/**************************************************************************/
1517
1518void BAPE_MaiOutput_Close(
1519    BAPE_MaiOutputHandle handle
1520    )
1521{
1522    BSTD_UNUSED(handle);
1523}
1524
1525/**************************************************************************/
1526
1527void BAPE_MaiOutput_GetSettings(
1528    BAPE_MaiOutputHandle handle,
1529    BAPE_MaiOutputSettings *pSettings     /* [out] */
1530    )
1531{
1532    BSTD_UNUSED(handle);
1533    BSTD_UNUSED(pSettings);
1534}
1535
1536/**************************************************************************/
1537
1538BERR_Code BAPE_MaiOutput_SetSettings(
1539    BAPE_MaiOutputHandle handle,
1540    const BAPE_MaiOutputSettings *pSettings
1541    )
1542{
1543    BSTD_UNUSED(handle);
1544    BSTD_UNUSED(pSettings);
1545    return BERR_TRACE(BERR_NOT_SUPPORTED);
1546}
1547
1548/**************************************************************************/
1549
1550void BAPE_MaiOutput_GetOutputPort(
1551    BAPE_MaiOutputHandle handle,
1552    BAPE_OutputPort *pOutputPort        /* [out] */
1553    )
1554{
1555    BSTD_UNUSED(handle);
1556    BSTD_UNUSED(pOutputPort);
1557}
1558
1559/**************************************************************************/
1560
1561void BAPE_MaiOutput_GetInterruptHandlers(
1562    BAPE_MaiOutputHandle handle,
1563    BAPE_MaiOutputInterruptHandlers *pInterrupts    /* [out] */
1564    )
1565{
1566    BSTD_UNUSED(handle);
1567    BSTD_UNUSED(pInterrupts);
1568}
1569
1570/**************************************************************************/
1571
1572BERR_Code BAPE_MaiOutput_SetInterruptHandlers(
1573    BAPE_MaiOutputHandle handle,
1574    const BAPE_MaiOutputInterruptHandlers *pInterrupts
1575    )
1576{
1577    BSTD_UNUSED(handle);
1578    BSTD_UNUSED(pInterrupts);
1579    return BERR_TRACE(BERR_NOT_SUPPORTED);
1580}
1581
1582/**************************************************************************/
1583
1584BERR_Code BAPE_MaiOutput_P_ResumeFromStandby(BAPE_Handle bapeHandle)
1585{
1586    BSTD_UNUSED(bapeHandle);
1587    return BERR_SUCCESS;
1588}
1589
1590#endif
Note: See TracBrowser for help on using the repository browser.