source: svn/newcon3bcm2_21bu/magnum/portinginterface/ape/7552/bape_bf_priv.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: 87.4 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_bf_priv.c $
11 * $brcm_Revision: Hydra_Software_Devel/17 $
12 * $brcm_Date: 3/2/12 3:03p $
13 *
14 * Module Description: Destination FIFO Interfaces
15 *
16 * Revision History:
17 *
18 * $brcm_Log: /magnum/portinginterface/ape/7422/bape_bf_priv.c $
19 *
20 * Hydra_Software_Devel/17   3/2/12 3:03p jgarrett
21 * SW7429-18: Clearing all rbuf registers on startup
22 *
23 * Hydra_Software_Devel/16   11/30/11 6:49p jgarrett
24 * SW7429-18: Fixing freemark re-arm for 7429
25 *
26 * Hydra_Software_Devel/15   11/14/11 3:42p gskerl
27 * SW7429-18: Merging 7429 changes back to main branch.
28 *
29 * Hydra_Software_Devel/SW7429-18/3   11/3/11 4:58p gskerl
30 * SW7429-18: Fixed typo... #if -> #ifdef
31 *
32 * Hydra_Software_Devel/SW7429-18/2   11/3/11 4:45p gskerl
33 * SW7429-18: Added conditional includes for bchp_aud_fmm_bf_esr1_h.h and
34 * bchp_aud_fmm_bf_esr2_h.h to fix compile errors on 7425
35 *
36 * Hydra_Software_Devel/SW7429-18/1   10/21/11 6:29p jgarrett
37 * SW7429-18: Initial compileable version for 7429
38 *
39 * Hydra_Software_Devel/14   11/10/11 3:48p jgarrett
40 * SW7346-537: Fixing wrap buffer size calculation when buffer is empty
41 *
42 * Hydra_Software_Devel/13   11/9/11 5:50p jgarrett
43 * SW7346-537: If buffers are empty, wrap buffer size was not populated
44 *
45 * Hydra_Software_Devel/12   10/11/11 6:53p gskerl
46 * SW7425-1479: Set a DFIFO's SOURCE_FIFO_ID to an invalid value (0x1F)
47 * when it is not used, in order to prevent conflict with other DFIFOs
48 *
49 * Hydra_Software_Devel/11   9/16/11 6:50p gskerl
50 * SW7231-129: Refactored to put hardware and software initialization into
51 * separate functions.
52 *
53 * Hydra_Software_Devel/10   8/31/11 8:53a jgarrett
54 * SW7425-1119: Correcting build error
55 *
56 * Hydra_Software_Devel/9   8/30/11 7:04p gskerl
57 * SW7425-1119: Corrected Playback buffer handling issue that happened
58 * when BAPE_Playback_CommitData() is called while Playback is not
59 * running.
60 *
61 * Hydra_Software_Devel/8   6/7/11 10:47a jgarrett
62 * SW7425-681: Setting WRCNT to 0 prior to Adaptive Rate Controller
63 * shutdown
64 *
65 * Hydra_Software_Devel/7   5/23/11 6:49p jgarrett
66 * SW7425-402: Adding multichannel capture support
67 *
68 * Hydra_Software_Devel/6   5/12/11 4:39p piyushg
69 * SW7425-401: Added PCM playback support for non-interleaved and
70 * multichannel data
71 *
72 * Hydra_Software_Devel/5   4/16/11 12:15p jgarrett
73 * SW7425-371: Removing tab characters
74 *
75 * Hydra_Software_Devel/4   4/12/11 10:04a jgarrett
76 * SWDTV-6305: Fixing SFIFO/DFIFO indexes
77 *
78 * Hydra_Software_Devel/3   4/6/11 1:24a jgarrett
79 * SW35330-35: Merge to main branch
80 *
81 * Hydra_Software_Devel/SW35330-35/2   4/5/11 7:14p jgarrett
82 * SW35330-35: PCM Playback working on 35230
83 *
84 * Hydra_Software_Devel/SW35330-35/1   4/5/11 12:50p jgarrett
85 * SW35330-35: FMM Abstraction refactoring to support DTV
86 *
87 * Hydra_Software_Devel/2   3/18/11 12:00p jgarrett
88 * SW7422-146: Fixing asserts and playfromcapture logic
89 *
90 * Hydra_Software_Devel/1   3/10/11 7:03p jgarrett
91 * SW7422-146: Refactored DFIFO code, added support for input capture from
92 * compressed/multichannel
93 *
94 ***************************************************************************/
95
96#include "bstd.h"
97#include "bkni.h"
98#include "bape.h"
99#include "bape_priv.h"
100#include "bchp_aud_fmm_bf_ctrl.h"
101#ifdef BCHP_AUD_FMM_BF_ESR_REG_START
102#include "bchp_aud_fmm_bf_esr.h"
103#endif
104
105#ifdef BCHP_AUD_FMM_BF_ESR1_H_REG_START
106#include "bchp_aud_fmm_bf_esr1_h.h"
107#endif
108
109#ifdef BCHP_AUD_FMM_BF_ESR2_H_REG_START
110#include "bchp_aud_fmm_bf_esr2_h.h"
111#endif
112
113BDBG_MODULE(bape_bf_priv);
114
115typedef struct BAPE_SfifoGroup
116{
117    bool allocated;
118    bool started;
119    bool ppmCorrection;
120    unsigned numChannelPairs;
121    unsigned sampleRate;
122    BAPE_Handle deviceHandle;
123    uint32_t sfifoIds[BAPE_ChannelPair_eMax];
124    uint32_t adaptRateIds[BAPE_ChannelPair_eMax];
125    BAPE_SfifoGroupSettings settings;
126} BAPE_SfifoGroup;
127
128typedef struct BAPE_DfifoGroup
129{
130    bool allocated;
131    bool started;
132    unsigned numChannelPairs;
133    BAPE_Handle deviceHandle;
134    uint32_t dfifoIds[BAPE_ChannelPair_eMax];
135    BAPE_DfifoGroupSettings settings;
136} BAPE_DfifoGroup;
137
138static BERR_Code BAPE_Sfifo_P_GetBuffer(BAPE_SfifoGroupHandle handle, BAPE_BufferDescriptor *pBuffers, unsigned chPair, unsigned bufferNum);
139static BERR_Code BAPE_Sfifo_P_CommitData (BAPE_SfifoGroupHandle handle, unsigned numBytes, unsigned chPair, unsigned bufferNum );
140static BERR_Code BAPE_Sfifo_P_GetQueuedBytes(BAPE_SfifoGroupHandle handle, unsigned *pQueuedBytes, unsigned chPair, unsigned bufferNum );
141
142void BAPE_SfifoGroup_P_GetDefaultCreateSettings(
143    BAPE_SfifoGroupCreateSettings *pSettings    /* [out] */
144    )
145{
146    BDBG_ASSERT(NULL != pSettings);
147    pSettings->numChannelPairs = 1;
148    pSettings->ppmCorrection = false;
149}
150
151static void BAPE_Sfifo_P_SetGroup(BAPE_Handle handle, uint32_t sfifoId, uint32_t groupId)
152{
153    uint32_t regAddr, regVal;
154
155    BDBG_OBJECT_ASSERT(handle, BAPE_Device);
156    BDBG_ASSERT(sfifoId < BAPE_CHIP_MAX_SFIFOS);
157    BDBG_ASSERT(groupId < BAPE_CHIP_MAX_SFIFOS);
158
159    regAddr = BCHP_AUD_FMM_BF_CTRL_SOURCECH_GRPi_ARRAY_BASE + (4*sfifoId);
160    regVal = BREG_Read32(handle->regHandle, regAddr);
161    regVal &= ~BCHP_MASK(AUD_FMM_BF_CTRL_SOURCECH_GRPi, GROUP_ID);
162    regVal |= BCHP_FIELD_DATA(AUD_FMM_BF_CTRL_SOURCECH_GRPi, GROUP_ID, groupId);
163    BREG_Write32(handle->regHandle, regAddr, regVal);
164}
165
166BERR_Code BAPE_SfifoGroup_P_Create(
167    BAPE_Handle deviceHandle,           
168    const BAPE_SfifoGroupCreateSettings *pSettings,
169    BAPE_SfifoGroupHandle *pHandle  /* [out] */
170    )
171{
172    unsigned i, sfifo, adaptrate=(unsigned)-1;
173    BERR_Code errCode;
174    BAPE_SfifoGroupHandle handle=NULL;
175
176    BDBG_OBJECT_ASSERT(deviceHandle, BAPE_Device);
177    BDBG_ASSERT(NULL != pSettings);
178    BDBG_ASSERT(NULL != pHandle);
179    BDBG_ASSERT(pSettings->numChannelPairs <= BAPE_ChannelPair_eMax);
180
181    /* Sanity Check */
182    if ( pSettings->numChannelPairs > 1 && pSettings->ppmCorrection )
183    {
184        BDBG_ERR(("PPM Correction is not supported for multichannel data"));
185        return BERR_TRACE(BERR_INVALID_PARAMETER);
186    }
187
188    /* Find an available group handle */
189    for ( i = 0; i < BAPE_CHIP_MAX_SFIFO_GROUPS; i++ )
190    {
191        BDBG_ASSERT(NULL != deviceHandle->sfifoGroups[i]);
192        if ( !deviceHandle->sfifoGroups[i]->allocated )
193        {
194            handle = deviceHandle->sfifoGroups[i];
195            break;
196        }
197    }
198
199    /* If none found, return error */
200    if ( NULL == handle )
201    {
202        return BERR_TRACE(BERR_NOT_SUPPORTED);
203    }
204
205    /* Now search for the correct number of resources */
206    errCode = BAPE_P_AllocateFmmResource(deviceHandle, BAPE_FmmResourceType_eSfifo, pSettings->numChannelPairs, &sfifo);
207    if ( errCode )
208    {
209        errCode = BERR_TRACE(errCode);
210        goto err_alloc_sfifo;
211    }
212    if ( pSettings->ppmCorrection )
213    {
214        errCode = BAPE_P_AllocateFmmResource(deviceHandle, BAPE_FmmResourceType_eAdaptiveRate, pSettings->numChannelPairs, &adaptrate);
215        if ( errCode )
216        {
217            errCode = BERR_TRACE(errCode);
218            goto err_alloc_adaptrate;
219        }
220    }
221
222    /* Successfully allocated resources.  Initialize Group */
223    handle->allocated = true;
224    handle->started = false;
225    handle->numChannelPairs = pSettings->numChannelPairs;
226    handle->ppmCorrection = pSettings->ppmCorrection;
227    handle->deviceHandle = deviceHandle;
228    handle->sampleRate = 0;
229    BKNI_Memset(&handle->settings, 0, sizeof(handle->settings));
230    handle->settings.stereoData = true;
231    handle->settings.signedData = true;
232    handle->settings.sampleRepeatEnabled = deviceHandle->settings.rampPcmSamples;
233    handle->settings.dataWidth = 32;
234    handle->settings.defaultSampleRate = 48000;
235    BKNI_Memset(handle->sfifoIds, 0xff, sizeof(handle->sfifoIds));
236    BKNI_Memset(handle->adaptRateIds, 0xff, sizeof(handle->adaptRateIds));
237    for ( i = 0; i < pSettings->numChannelPairs; i++ )
238    {
239        handle->sfifoIds[i] = sfifo + i;
240        BAPE_Sfifo_P_SetGroup(handle->deviceHandle, sfifo+i, sfifo);    /* Set HW Grouping */
241    }
242    if ( handle->ppmCorrection )
243    {
244        for ( i = 0; i < pSettings->numChannelPairs; i++ )
245        {
246            handle->adaptRateIds[i] = adaptrate + i;
247            /* Adapt Rate -> SFIFO linkage is done at start time */
248        }
249    }
250    *pHandle = handle;
251    return BERR_SUCCESS;
252
253    err_alloc_adaptrate:
254    BAPE_P_FreeFmmResource(deviceHandle, BAPE_FmmResourceType_eSfifo, pSettings->numChannelPairs, sfifo);
255    err_alloc_sfifo:
256    return errCode;
257}
258
259void BAPE_SfifoGroup_P_Destroy(
260    BAPE_SfifoGroupHandle handle
261    )
262{
263    unsigned i;
264
265    BDBG_ASSERT(NULL != handle);
266    BDBG_ASSERT(handle->allocated);
267    BDBG_ASSERT(!handle->started);
268    BDBG_OBJECT_ASSERT(handle->deviceHandle, BAPE_Device);
269
270    /* Release Resources */
271    if ( handle->ppmCorrection )
272    {
273        BAPE_P_FreeFmmResource(handle->deviceHandle, BAPE_FmmResourceType_eAdaptiveRate, handle->numChannelPairs, handle->adaptRateIds[0]);
274    }
275    /* Clear SFIFO Grouping */
276    for ( i = 0; i < handle->numChannelPairs; i++ )
277    {
278        BAPE_Sfifo_P_SetGroup(handle->deviceHandle, handle->sfifoIds[i], handle->sfifoIds[i]);
279    }
280    BAPE_P_FreeFmmResource(handle->deviceHandle, BAPE_FmmResourceType_eSfifo, handle->numChannelPairs, handle->sfifoIds[0]);
281    BKNI_Memset(handle->sfifoIds, 0xff, sizeof(handle->sfifoIds));
282    BKNI_Memset(handle->adaptRateIds, 0xff, sizeof(handle->adaptRateIds));
283    handle->allocated = false;
284}
285
286void BAPE_SfifoGroup_P_GetSettings(
287    BAPE_SfifoGroupHandle handle,
288    BAPE_SfifoGroupSettings *pSettings  /* [out] */
289    )
290{
291    BDBG_ASSERT(NULL != handle);
292    BDBG_ASSERT(handle->allocated);
293    *pSettings = handle->settings;
294}
295
296BERR_Code BAPE_SfifoGroup_P_SetSettings(
297    BAPE_SfifoGroupHandle handle,
298    const BAPE_SfifoGroupSettings *pSettings
299    )
300{
301    BDBG_ASSERT(NULL != handle);
302    BDBG_ASSERT(handle->allocated);
303
304    if ( handle->started )
305    {
306        return BERR_TRACE(BERR_NOT_SUPPORTED);
307    }
308    handle->settings = *pSettings;
309
310    return BERR_SUCCESS;
311}
312
313BERR_Code BAPE_SfifoGroup_P_Start(
314    BAPE_SfifoGroupHandle handle,
315    bool enableOnly                 /* If true, a separate call to BAPE_SfifoGroup_P_Run_isr is required to
316                                    start data flow.  If false, data flow will start immediately. */
317    )
318{
319    uint32_t regAddr, regVal;
320    unsigned i;
321    BAPE_Handle deviceHandle;
322
323    BDBG_ASSERT(NULL != handle);
324    BDBG_ASSERT(handle->allocated);
325    if ( handle->started )
326    {
327        return BERR_TRACE(BERR_NOT_SUPPORTED);
328    }
329    deviceHandle = handle->deviceHandle;
330    BDBG_OBJECT_ASSERT(deviceHandle, BAPE_Device);
331
332    /* Program each SFIFO */
333    for ( i = 0; i < handle->numChannelPairs; i++ )
334    {
335        uint32_t base, end, watermark, wrpoint, writeOffset;
336
337        regAddr = BCHP_AUD_FMM_BF_CTRL_SOURCECH_CFGi_ARRAY_BASE + (4*handle->sfifoIds[i]);
338        regVal = BREG_Read32(deviceHandle->regHandle, regAddr);
339        regVal &= ~(
340                   BCHP_MASK(AUD_FMM_BF_CTRL_SOURCECH_CFGi, PROCESS_SEQ_ID_VALID)|
341                   BCHP_MASK(AUD_FMM_BF_CTRL_SOURCECH_CFGi, PROCESS_ID_HIGH)|
342                   BCHP_MASK(AUD_FMM_BF_CTRL_SOURCECH_CFGi, REVERSE_ENDIAN)|
343                   BCHP_MASK(AUD_FMM_BF_CTRL_SOURCECH_CFGi, BIT_RESOLUTION)|
344                   BCHP_MASK(AUD_FMM_BF_CTRL_SOURCECH_CFGi, SHARED_SBUF_ID)|
345                   BCHP_MASK(AUD_FMM_BF_CTRL_SOURCECH_CFGi, SHARE_SBUF)|
346                   BCHP_MASK(AUD_FMM_BF_CTRL_SOURCECH_CFGi, SFIFO_START_HALFFULL)|
347                   BCHP_MASK(AUD_FMM_BF_CTRL_SOURCECH_CFGi, DMA_READ_DISABLE)|
348                   BCHP_MASK(AUD_FMM_BF_CTRL_SOURCECH_CFGi, SAMPLE_REPEAT_ENABLE)|
349                   BCHP_MASK(AUD_FMM_BF_CTRL_SOURCECH_CFGi, NOT_PAUSE_WHEN_EMPTY)|
350                   BCHP_MASK(AUD_FMM_BF_CTRL_SOURCECH_CFGi, START_SELECTION)|
351#ifdef BCHP_AUD_FMM_BF_CTRL_SOURCECH_CFGi_STCSYNC_ENABLE_MASK
352                   BCHP_MASK(AUD_FMM_BF_CTRL_SOURCECH_CFGi, STCSYNC_ENABLE)|
353#endif
354                   BCHP_MASK(AUD_FMM_BF_CTRL_SOURCECH_CFGi, SAMPLE_CH_MODE)|
355                   BCHP_MASK(AUD_FMM_BF_CTRL_SOURCECH_CFGi, SOURCEFIFO_SIZE_DOUBLE)|
356                   BCHP_MASK(AUD_FMM_BF_CTRL_SOURCECH_CFGi, BUFFER_PAIR_ENABLE)|
357                   BCHP_MASK(AUD_FMM_BF_CTRL_SOURCECH_CFGi, SOURCEFIFO_ENABLE)
358                   );
359        regVal |= BCHP_FIELD_DATA(AUD_FMM_BF_CTRL_SOURCECH_CFGi, PROCESS_SEQ_ID_VALID, 1);
360        regVal |= BCHP_FIELD_DATA(AUD_FMM_BF_CTRL_SOURCECH_CFGi, START_SELECTION, handle->settings.highPriority?1:0);
361        regVal |= BCHP_FIELD_DATA(AUD_FMM_BF_CTRL_SOURCECH_CFGi, BIT_RESOLUTION, handle->settings.dataWidth==32?0:handle->settings.dataWidth);
362        if ( handle->settings.master )
363        {
364            BDBG_ASSERT(handle->settings.master->allocated);
365            regVal |= BCHP_FIELD_DATA(AUD_FMM_BF_CTRL_SOURCECH_CFGi, SHARED_SBUF_ID, handle->settings.master->sfifoIds[i]);
366            regVal |= BCHP_FIELD_DATA(AUD_FMM_BF_CTRL_SOURCECH_CFGi, SHARE_SBUF, 1);
367        }
368        regVal |= BCHP_FIELD_DATA(AUD_FMM_BF_CTRL_SOURCECH_CFGi, SFIFO_START_HALFFULL, 1);
369        regVal |= BCHP_FIELD_DATA(AUD_FMM_BF_CTRL_SOURCECH_CFGi, DMA_READ_DISABLE, handle->settings.bypassMemory?1:0);
370        if ( handle->settings.sampleRepeatEnabled && deviceHandle->settings.rampPcmSamples )
371        {
372            regVal |= BCHP_FIELD_DATA(AUD_FMM_BF_CTRL_SOURCECH_CFGi, SAMPLE_REPEAT_ENABLE, 1);
373        }
374        regVal |= BCHP_FIELD_DATA(AUD_FMM_BF_CTRL_SOURCECH_CFGi, NOT_PAUSE_WHEN_EMPTY, handle->settings.loopAround?1:0);
375        regVal |= BCHP_FIELD_DATA(AUD_FMM_BF_CTRL_SOURCECH_CFGi, START_SELECTION, handle->settings.wrpointEnabled?1:0);
376        regVal |= BCHP_FIELD_DATA(AUD_FMM_BF_CTRL_SOURCECH_CFGi, SAMPLE_CH_MODE, handle->settings.stereoData?0:1);
377        if ( handle->settings.interleaveData )
378        {
379            regVal |= BCHP_FIELD_DATA(AUD_FMM_BF_CTRL_SOURCECH_CFGi, SOURCEFIFO_SIZE_DOUBLE, 1);
380        }
381        else
382        {
383            regVal |= BCHP_FIELD_DATA(AUD_FMM_BF_CTRL_SOURCECH_CFGi, BUFFER_PAIR_ENABLE, 1);           
384        }
385        BREG_Write32(deviceHandle->regHandle, regAddr, regVal);
386
387        /* Sign handling is in the GRP register */
388        regAddr = BCHP_AUD_FMM_BF_CTRL_SOURCECH_GRPi_ARRAY_BASE + (4*handle->sfifoIds[i]);
389        regVal = BREG_Read32(deviceHandle->regHandle, regAddr);
390        regVal &= ~BCHP_MASK(AUD_FMM_BF_CTRL_SOURCECH_GRPi, INVERT_MSB);
391        regVal |= BCHP_FIELD_DATA(AUD_FMM_BF_CTRL_SOURCECH_GRPi, INVERT_MSB, handle->settings.signedData?0:1);
392        BREG_Write32(deviceHandle->regHandle, regAddr, regVal);
393
394        /* Setup Ringbuffer Registers */
395        regAddr = BAPE_P_SFIFO_TO_RDADDR_REG(handle->sfifoIds[i]);
396        base = handle->settings.bufferInfo[2*i].base;
397        end = base + handle->settings.bufferInfo[2*i].length - 1;
398        watermark = handle->settings.bufferInfo[2*i].watermark;
399        wrpoint = handle->settings.bufferInfo[2*i].wrpoint;
400        writeOffset = handle->settings.bufferInfo[2*i].writeOffset;
401        BREG_Write32(deviceHandle->regHandle, regAddr, base);
402        regAddr += 4;   /* Write is next */
403        BREG_Write32(deviceHandle->regHandle, regAddr, base);  /* leave buf empty for now */
404        regAddr += 4;   /* Base is next */
405        BREG_Write32(deviceHandle->regHandle, regAddr, base);
406        regAddr += 4;   /* End is next */
407        BREG_Write32(deviceHandle->regHandle, regAddr, end);
408        regAddr += 4;   /* Freefull is next */
409        BREG_Write32(deviceHandle->regHandle, regAddr, watermark);
410        regAddr += 4;   /* WRPOINT is last */
411        BREG_Write32(deviceHandle->regHandle, regAddr, wrpoint);
412        BAPE_Sfifo_P_CommitData (handle,  writeOffset, i  , 0 ); /* now adjust write pointer for existing data */
413
414        if ( handle->settings.interleaveData )
415        {
416            base=end=watermark=wrpoint=writeOffset=0;
417        }
418        else
419        {
420            base = handle->settings.bufferInfo[(2*i)+1].base;
421            end = base + handle->settings.bufferInfo[(2*i)+1].length - 1;
422            watermark = handle->settings.bufferInfo[(2*i)+1].watermark;
423            wrpoint = handle->settings.bufferInfo[(2*i)+1].wrpoint;
424            writeOffset = handle->settings.bufferInfo[(2*i)+1].writeOffset;
425        }
426        regAddr += 4;   /* Next RDADDR */
427        BREG_Write32(deviceHandle->regHandle, regAddr, base);
428        regAddr += 4;   /* Write is next */
429        BREG_Write32(deviceHandle->regHandle, regAddr, base);  /* leave buf empty for now */
430        regAddr += 4;   /* Base is next */
431        BREG_Write32(deviceHandle->regHandle, regAddr, base);
432        regAddr += 4;   /* End is next */
433        BREG_Write32(deviceHandle->regHandle, regAddr, end);
434        regAddr += 4;   /* Freefull is next */
435        BREG_Write32(deviceHandle->regHandle, regAddr, watermark);
436        regAddr += 4;   /* WRPOINT is last */
437        BREG_Write32(deviceHandle->regHandle, regAddr, wrpoint);
438        BAPE_Sfifo_P_CommitData (handle,  writeOffset, i  , 1 ); /* now adjust write pointer for existing data */
439    }
440
441    /* Enable all SFIFO's first. */
442    for ( i = 0; i < handle->numChannelPairs; i++ )
443    {
444        BDBG_MSG(("Enabling SFIFO %u", handle->sfifoIds[i]));
445        regAddr = BCHP_AUD_FMM_BF_CTRL_SOURCECH_CFGi_ARRAY_BASE + (4*handle->sfifoIds[i]);
446        regVal = BREG_Read32(deviceHandle->regHandle, regAddr);
447        regVal |= BCHP_MASK(AUD_FMM_BF_CTRL_SOURCECH_CFGi, SOURCEFIFO_ENABLE);
448        BREG_Write32(deviceHandle->regHandle, regAddr, regVal);
449    }
450
451    if ( !enableOnly )
452    {
453        /* Run */
454        for ( i = 0; i < handle->numChannelPairs; i++ )
455        {
456            BDBG_MSG(("Enabling PLAY_RUN for SFIFO %u", handle->sfifoIds[i]));
457            regAddr = BCHP_AUD_FMM_BF_CTRL_SOURCECH_CTRLi_ARRAY_BASE + (4*handle->sfifoIds[i]);
458            BREG_Write32(deviceHandle->regHandle, regAddr, 1);
459        }
460    }
461
462    /* Enable Adaptive Rate Controllers if Required */
463    if ( handle->ppmCorrection )
464    {
465        for ( i = 0; i < handle->numChannelPairs; i++ )
466        {
467            BKNI_EnterCriticalSection();
468#ifdef BCHP_AUD_FMM_BF_CTRL_ADAPTRATE_0_CFG
469            regAddr = BCHP_AUD_FMM_BF_CTRL_ADAPTRATE_0_CFG + ((BCHP_AUD_FMM_BF_CTRL_ADAPTRATE_1_CFG - BCHP_AUD_FMM_BF_CTRL_ADAPTRATE_0_CFG)*handle->adaptRateIds[i]);
470            /* This register must be manipulated in critical section, it is programmed at sample rate changes as well */
471            regVal = BREG_Read32_isr(deviceHandle->regHandle, regAddr);
472
473            regVal &= ~(BCHP_MASK(AUD_FMM_BF_CTRL_ADAPTRATE_0_CFG, ADAPTIVE_SFIFO_SEL)|
474                        BCHP_MASK (AUD_FMM_BF_CTRL_ADAPTRATE_0_CFG, TRIWINDOW_WIDTH_SEL)|
475                        BCHP_MASK (AUD_FMM_BF_CTRL_ADAPTRATE_0_CFG, ADAPTIVE_RATE_ENABLE)|
476                        BCHP_MASK (AUD_FMM_BF_CTRL_ADAPTRATE_0_CFG, ADAPTIVE_RATE_MASTER_ENABLE));
477
478            regVal |= (BCHP_FIELD_DATA (AUD_FMM_BF_CTRL_ADAPTRATE_0_CFG, ADAPTIVE_SFIFO_SEL, handle->sfifoIds[i]));         
479            /* TODO: hardcoding window width field to 8 ie actual window width of 256. This has to be changed later
480               to be taken from application */
481            regVal |= (BCHP_FIELD_DATA (AUD_FMM_BF_CTRL_ADAPTRATE_0_CFG, TRIWINDOW_WIDTH_SEL, 8));
482            /* Earlier, for a decode channel FW was setting the enable flag.
483            Now we're doing AdaptRate control for PCM channels also. So let the
484            PI set this flag always */               
485            regVal |= (BCHP_FIELD_DATA (AUD_FMM_BF_CTRL_ADAPTRATE_0_CFG, ADAPTIVE_RATE_ENABLE, 1));
486            regVal |= (BCHP_FIELD_DATA (AUD_FMM_BF_CTRL_ADAPTRATE_0_CFG, ADAPTIVE_RATE_MASTER_ENABLE, 1));               
487#ifndef BCHP_AUD_FMM_BF_CTRL_ADAPTRATE_THRESHOLD_0
488            regVal &= ~BCHP_MASK(AUD_FMM_BF_CTRL_ADAPTRATE_0_CFG, ADAPTIVE_RATE_THRESHOLD);
489            regVal |= BCHP_FIELD_DATA(AUD_FMM_BF_CTRL_ADAPTRATE_0_CFG, ADAPTIVE_RATE_THRESHOLD, 0xffff);
490#endif
491            BREG_Write32_isr(deviceHandle->regHandle, regAddr, regVal);
492
493#ifdef BCHP_AUD_FMM_BF_CTRL_ADAPTRATE_THRESHOLD_0
494            regAddr = BCHP_AUD_FMM_BF_CTRL_ADAPTRATE_THRESHOLD_0 + 4*handle->adaptRateIds[i];
495            regVal = BREG_Read32_isr(deviceHandle->regHandle, regAddr);
496            regVal &= ~BCHP_MASK(AUD_FMM_BF_CTRL_ADAPTRATE_THRESHOLD_0, ADAPTIVE_RATE_THRESHOLD);
497            regVal |= BCHP_FIELD_DATA(AUD_FMM_BF_CTRL_ADAPTRATE_THRESHOLD_0, ADAPTIVE_RATE_THRESHOLD, 0xffff);
498            BREG_Write32_isr(deviceHandle->regHandle, regAddr, regVal);
499#endif
500            regAddr = BCHP_AUD_FMM_BF_CTRL_ADAPTRATE_REPEATDROP_WRCNT_0 + 4*handle->adaptRateIds[i];
501            BREG_Write32_isr(deviceHandle->regHandle, regAddr, 0);
502#else
503            regAddr = BCHP_AUD_FMM_BF_CTRL_ADAPTRATE_CFGi_ARRAY_BASE + ((BCHP_AUD_FMM_BF_CTRL_ADAPTRATE_CFGi_ARRAY_ELEMENT_SIZE/8)*handle->adaptRateIds[i]);
504            /* This register must be manipulated in critical section, it is programmed at sample rate changes as well */
505            regVal = BREG_Read32_isr(deviceHandle->regHandle, regAddr);
506
507            regVal &= ~(BCHP_MASK(AUD_FMM_BF_CTRL_ADAPTRATE_CFGi, ADAPTIVE_SFIFO_SEL)|
508                        BCHP_MASK (AUD_FMM_BF_CTRL_ADAPTRATE_CFGi, TRIWINDOW_WIDTH_SEL)|
509                        BCHP_MASK (AUD_FMM_BF_CTRL_ADAPTRATE_CFGi, AUTOMATIC_RATE_ENABLE)|
510                        BCHP_MASK (AUD_FMM_BF_CTRL_ADAPTRATE_CFGi, ADAPTIVE_RATE_MASTER_ENABLE));
511
512            regVal |= (BCHP_FIELD_DATA (AUD_FMM_BF_CTRL_ADAPTRATE_CFGi, ADAPTIVE_SFIFO_SEL, handle->sfifoIds[i]));         
513            /* TODO: hardcoding window width field to 8 ie actual window width of 256. This has to be changed later
514               to be taken from application */
515            regVal |= (BCHP_FIELD_DATA (AUD_FMM_BF_CTRL_ADAPTRATE_CFGi, TRIWINDOW_WIDTH_SEL, 8));
516            /* Earlier, for a decode channel FW was setting the enable flag.
517            Now we're doing AdaptRate control for PCM channels also. So let the
518            PI set this flag always */               
519            regVal |= (BCHP_FIELD_DATA (AUD_FMM_BF_CTRL_ADAPTRATE_CFGi, AUTOMATIC_RATE_ENABLE, 1));
520            regVal |= (BCHP_FIELD_DATA (AUD_FMM_BF_CTRL_ADAPTRATE_CFGi, ADAPTIVE_RATE_MASTER_ENABLE, 1));               
521            BREG_Write32_isr(deviceHandle->regHandle, regAddr, regVal);
522
523#ifdef BCHP_AUD_FMM_BF_CTRL_ADAPTRATE_THRESHOLDi_ARRAY_BASE
524            regAddr = BCHP_AUD_FMM_BF_CTRL_ADAPTRATE_THRESHOLDi_ARRAY_BASE + ((BCHP_AUD_FMM_BF_CTRL_ADAPTRATE_THRESHOLDi_ARRAY_ELEMENT_SIZE/8)*handle->adaptRateIds[i]);
525            regVal = BREG_Read32_isr(deviceHandle->regHandle, regAddr);
526            regVal &= ~BCHP_MASK(AUD_FMM_BF_CTRL_ADAPTRATE_THRESHOLDi, ADAPTIVE_RATE_THRESHOLD);
527            regVal |= BCHP_FIELD_DATA(AUD_FMM_BF_CTRL_ADAPTRATE_THRESHOLDi, ADAPTIVE_RATE_THRESHOLD, 0xffff);
528            BREG_Write32_isr(deviceHandle->regHandle, regAddr, regVal);
529#endif
530            regAddr = BCHP_AUD_FMM_BF_CTRL_ADAPTRATE_REPEATDROP_WRCNTi_ARRAY_BASE + ((BCHP_AUD_FMM_BF_CTRL_ADAPTRATE_REPEATDROP_WRCNTi_ARRAY_ELEMENT_SIZE/8)*handle->adaptRateIds[i]);
531            BREG_Write32_isr(deviceHandle->regHandle, regAddr, 0);           
532#endif
533
534            BAPE_SfifoGroup_P_SetSampleRate_isr(handle, handle->settings.defaultSampleRate);
535            BKNI_LeaveCriticalSection();
536        }
537    }
538
539    handle->started = true;
540    return BERR_SUCCESS;
541}
542
543void BAPE_SfifoGroup_P_Stop(
544    BAPE_SfifoGroupHandle handle
545    )
546{
547    uint32_t regAddr, regVal;
548    unsigned i;
549    BAPE_Handle deviceHandle;
550
551    BDBG_ASSERT(NULL != handle);
552    BDBG_ASSERT(handle->allocated);
553    if ( !handle->started )
554    {
555        return;
556    }
557    deviceHandle = handle->deviceHandle;
558    BDBG_OBJECT_ASSERT(deviceHandle, BAPE_Device);
559
560    if ( handle->ppmCorrection )
561    {
562#ifdef BCHP_AUD_FMM_BF_CTRL_ADAPTRATE_0_CFG
563        /* Workaround for HWAIO-20 (SW7425-681) - Program WRCNT to 0 prior to clearing master enable bit. */
564        for ( i = 0; i < handle->numChannelPairs; i++ )
565        {           
566            regAddr = BCHP_AUD_FMM_BF_CTRL_ADAPTRATE_REPEATDROP_WRCNT_0 + ((BCHP_AUD_FMM_BF_CTRL_ADAPTRATE_REPEATDROP_WRCNT_1 - BCHP_AUD_FMM_BF_CTRL_ADAPTRATE_REPEATDROP_WRCNT_0)*handle->adaptRateIds[i]);
567            BREG_Write32(deviceHandle->regHandle, regAddr, 0);
568        }
569        for ( i = 0; i < handle->numChannelPairs; i++ )
570        {
571            regAddr = BCHP_AUD_FMM_BF_CTRL_ADAPTRATE_0_CFG + ((BCHP_AUD_FMM_BF_CTRL_ADAPTRATE_1_CFG - BCHP_AUD_FMM_BF_CTRL_ADAPTRATE_0_CFG)*handle->adaptRateIds[i]);
572            /* This register must be manipulated in critical section, it is programmed at sample rate changes as well */
573            BKNI_EnterCriticalSection();
574            regVal = BREG_Read32_isr(deviceHandle->regHandle, regAddr);
575            regVal &= ~(BCHP_MASK (AUD_FMM_BF_CTRL_ADAPTRATE_0_CFG, ADAPTIVE_RATE_ENABLE)|
576                        BCHP_MASK (AUD_FMM_BF_CTRL_ADAPTRATE_0_CFG, ADAPTIVE_RATE_MASTER_ENABLE));
577            BREG_Write32_isr(deviceHandle->regHandle, regAddr, regVal);
578            BKNI_LeaveCriticalSection();
579        }
580#else
581        /* Workaround for HWAIO-20 (SW7425-681) - Program WRCNT to 0 prior to clearing master enable bit. */
582        for ( i = 0; i < handle->numChannelPairs; i++ )
583        {           
584            regAddr = BCHP_AUD_FMM_BF_CTRL_ADAPTRATE_REPEATDROP_WRCNTi_ARRAY_BASE + ((BCHP_AUD_FMM_BF_CTRL_ADAPTRATE_REPEATDROP_WRCNTi_ARRAY_ELEMENT_SIZE/8)*handle->adaptRateIds[i]);
585            BREG_Write32(deviceHandle->regHandle, regAddr, 0);
586        }
587        for ( i = 0; i < handle->numChannelPairs; i++ )
588        {
589            regAddr = BCHP_AUD_FMM_BF_CTRL_ADAPTRATE_CFGi_ARRAY_BASE + ((BCHP_AUD_FMM_BF_CTRL_ADAPTRATE_CFGi_ARRAY_ELEMENT_SIZE/8)*handle->adaptRateIds[i]);
590            /* This register must be manipulated in critical section, it is programmed at sample rate changes as well */
591            BKNI_EnterCriticalSection();
592            regVal = BREG_Read32_isr(deviceHandle->regHandle, regAddr);
593            regVal &= ~(BCHP_MASK (AUD_FMM_BF_CTRL_ADAPTRATE_CFGi, AUTOMATIC_RATE_ENABLE)|
594                        BCHP_MASK (AUD_FMM_BF_CTRL_ADAPTRATE_CFGi, ADAPTIVE_RATE_MASTER_ENABLE));
595            BREG_Write32_isr(deviceHandle->regHandle, regAddr, regVal);
596            BKNI_LeaveCriticalSection();
597        }       
598#endif
599    }
600    for ( i = 0; i < handle->numChannelPairs; i++ )
601    {
602        uint32_t sfifo;
603        unsigned timeout;
604
605        sfifo = handle->sfifoIds[i];
606
607        BDBG_MSG(("Disabling PLAY_RUN for SFIFO %u", sfifo));
608        regAddr = BCHP_AUD_FMM_BF_CTRL_SOURCECH_CTRLi_ARRAY_BASE + (4*sfifo);
609        BREG_Write32(deviceHandle->regHandle, regAddr, 0);
610
611        /* Wait for group flow to stop */
612        for ( timeout = 1000; timeout > 0; timeout-- )
613        {
614            regVal = BREG_Read32(deviceHandle->regHandle, BCHP_AUD_FMM_BF_CTRL_SOURCECH_GROUP_FLOWON);
615            if ( 0 == (regVal & (1<<sfifo)) )
616            {
617                break;
618            }
619            BKNI_Sleep(1);
620        }
621        if ( 0 == timeout )
622        {
623            regVal = BREG_Read32(deviceHandle->regHandle, BCHP_AUD_FMM_BF_CTRL_SOURCECH_GROUP_FLOWON);
624            BDBG_WRN(("Timeout waiting for SFIFO %u flow to stop [0x%08x]", sfifo, regVal));
625        }
626
627        /* Disable Source Channels */
628        BDBG_MSG(("Disabling SFIFO %u", sfifo));
629        regAddr = BCHP_AUD_FMM_BF_CTRL_SOURCECH_CFGi_ARRAY_BASE + (4*sfifo);
630        regVal = BREG_Read32(deviceHandle->regHandle, regAddr);
631        regVal &= ~BCHP_MASK(AUD_FMM_BF_CTRL_SOURCECH_CFGi, SOURCEFIFO_ENABLE);
632        BREG_Write32(deviceHandle->regHandle, regAddr, regVal);
633
634        /* Wait for the source channel to stop */           
635        for ( timeout = 1000; timeout > 0; timeout-- )
636        {
637            regVal = BREG_Read32(deviceHandle->regHandle, BCHP_AUD_FMM_BF_CTRL_SOURCECH_GROUP_ENABLE);
638            if ( 0 == (regVal & (1<<sfifo)) )
639            {
640                break;
641            }
642            BKNI_Sleep(1);
643        }
644        if ( 0 == timeout )
645        {
646            regVal = BREG_Read32(deviceHandle->regHandle, BCHP_AUD_FMM_BF_CTRL_SOURCECH_GROUP_ENABLE);
647            BDBG_WRN(("Timeout waiting for SFIFO %u enable status to clear [0x%08x]", sfifo, regVal));
648        }
649    }
650
651    /* Reset Ringbuffers */
652    for ( i = 0; i < handle->numChannelPairs; i++ )
653    {
654        regAddr = BAPE_P_SFIFO_TO_RDADDR_REG(handle->sfifoIds[i]);
655        BREG_Write32(deviceHandle->regHandle, regAddr, 0);
656        regAddr += 4;   /* Write is next */
657        BREG_Write32(deviceHandle->regHandle, regAddr, 0);
658        regAddr += 4;   /* Base is next */
659        BREG_Write32(deviceHandle->regHandle, regAddr, 0);
660        regAddr += 4;   /* End is next */
661        BREG_Write32(deviceHandle->regHandle, regAddr, 0);
662        regAddr += 4;   /* Freefull is next */
663        BREG_Write32(deviceHandle->regHandle, regAddr, 0);
664        regAddr += 4;   /* WRPOINT is last */
665        BREG_Write32(deviceHandle->regHandle, regAddr, 0);
666        regAddr += 4;   /* Next RDADDR */
667        BREG_Write32(deviceHandle->regHandle, regAddr, 0);
668        regAddr += 4;   /* Write is next */
669        BREG_Write32(deviceHandle->regHandle, regAddr, 0);
670        regAddr += 4;   /* Base is next */
671        BREG_Write32(deviceHandle->regHandle, regAddr, 0);
672        regAddr += 4;   /* End is next */
673        BREG_Write32(deviceHandle->regHandle, regAddr, 0);
674        regAddr += 4;   /* Freefull is next */
675        BREG_Write32(deviceHandle->regHandle, regAddr, 0);
676        regAddr += 4;   /* WRPOINT is last */
677        BREG_Write32(deviceHandle->regHandle, regAddr, 0);
678    }
679
680    handle->started = false;
681}
682
683void BAPE_SfifoGroup_P_Run_isr(
684    BAPE_SfifoGroupHandle handle
685    )
686{
687    uint32_t regAddr;
688    unsigned i;
689    BAPE_Handle deviceHandle;
690
691    BDBG_ASSERT(NULL != handle);
692    BDBG_ASSERT(handle->allocated);
693    if ( !handle->started )
694    {
695        BDBG_ERR(("SFIFO Group %#x is not started, can not run.", handle));
696        return;
697    }
698    deviceHandle = handle->deviceHandle;
699    BDBG_OBJECT_ASSERT(deviceHandle, BAPE_Device);
700    for ( i = 0; i < handle->numChannelPairs; i++ )
701    {
702        BDBG_MSG(("Enabling PLAY_RUN for SFIFO %u", handle->sfifoIds[i]));
703        regAddr = BCHP_AUD_FMM_BF_CTRL_SOURCECH_CTRLi_ARRAY_BASE + (4*handle->sfifoIds[i]);
704        BREG_Write32(deviceHandle->regHandle, regAddr, 1);
705    }
706}
707
708void BAPE_SfifoGroup_P_Halt_isr(
709    BAPE_SfifoGroupHandle handle
710    )
711{
712    uint32_t regAddr;
713    unsigned i;
714    BAPE_Handle deviceHandle;
715
716    BDBG_ASSERT(NULL != handle);
717    BDBG_ASSERT(handle->allocated);
718    if ( !handle->started )
719    {
720        BDBG_ERR(("SFIFO Group %#x is not started, can not halt.", handle));
721        return;
722    }
723    deviceHandle = handle->deviceHandle;
724    BDBG_OBJECT_ASSERT(deviceHandle, BAPE_Device);
725    for ( i = 0; i < handle->numChannelPairs; i++ )
726    {
727        BDBG_MSG(("Disabling PLAY_RUN for SFIFO %u", handle->sfifoIds[i]));
728        regAddr = BCHP_AUD_FMM_BF_CTRL_SOURCECH_CTRLi_ARRAY_BASE + (4*handle->sfifoIds[i]);
729        BREG_Write32(deviceHandle->regHandle, regAddr, 0);
730    }
731}
732
733void BAPE_SfifoGroup_P_SetSampleRate_isr(
734    BAPE_SfifoGroupHandle handle,
735    unsigned sampleRate
736    )
737{
738    uint32_t regAddr, regVal;
739    unsigned i;
740    BAPE_Handle deviceHandle;
741
742    BDBG_ASSERT(NULL != handle);
743    BDBG_ASSERT(handle->allocated);
744    deviceHandle = handle->deviceHandle;
745    BDBG_OBJECT_ASSERT(deviceHandle, BAPE_Device);
746    BKNI_ASSERT_ISR_CONTEXT();
747
748    if ( !handle->ppmCorrection )
749    {
750        return;
751    }
752
753    for ( i = 0; i < handle->numChannelPairs; i++ )
754    {
755#ifdef BCHP_AUD_FMM_BF_CTRL_ADAPTRATE_0_CFG
756        regAddr = BCHP_AUD_FMM_BF_CTRL_ADAPTRATE_0_CFG + 4*handle->adaptRateIds[i];
757
758        regVal = BREG_Read32_isr(deviceHandle->regHandle, regAddr);
759        regVal &= ~(BCHP_MASK(AUD_FMM_BF_CTRL_ADAPTRATE_0_CFG, ADAPT_SAMPLINGRATE));
760        switch ( sampleRate )
761        {
762        case 32000:
763            regVal |= BCHP_FIELD_DATA(AUD_FMM_BF_CTRL_ADAPTRATE_0_CFG, ADAPT_SAMPLINGRATE, 0);
764            break;
765        default:
766        case 48000:
767            regVal |= BCHP_FIELD_DATA(AUD_FMM_BF_CTRL_ADAPTRATE_0_CFG, ADAPT_SAMPLINGRATE, 1);
768            break;
769        case 96000:
770            regVal |= BCHP_FIELD_DATA(AUD_FMM_BF_CTRL_ADAPTRATE_0_CFG, ADAPT_SAMPLINGRATE, 2);
771            break;
772        case 192000:
773            regVal |= BCHP_FIELD_DATA(AUD_FMM_BF_CTRL_ADAPTRATE_0_CFG, ADAPT_SAMPLINGRATE, 3);
774            break;
775        case 44100:
776            regVal |= BCHP_FIELD_DATA(AUD_FMM_BF_CTRL_ADAPTRATE_0_CFG, ADAPT_SAMPLINGRATE, 4);
777            break;
778        case 88200:
779            regVal |= BCHP_FIELD_DATA(AUD_FMM_BF_CTRL_ADAPTRATE_0_CFG, ADAPT_SAMPLINGRATE, 5);
780            break;
781        case 176400:
782            regVal |= BCHP_FIELD_DATA(AUD_FMM_BF_CTRL_ADAPTRATE_0_CFG, ADAPT_SAMPLINGRATE, 6);
783            break;
784        }
785#else
786        regAddr = BCHP_AUD_FMM_BF_CTRL_ADAPTRATE_CFGi_ARRAY_BASE + ((BCHP_AUD_FMM_BF_CTRL_ADAPTRATE_CFGi_ARRAY_ELEMENT_SIZE/8)*handle->adaptRateIds[i]);
787
788        regVal = BREG_Read32_isr(deviceHandle->regHandle, regAddr);
789        regVal &= ~(BCHP_MASK(AUD_FMM_BF_CTRL_ADAPTRATE_CFGi, ADAPT_SAMPLINGRATE));
790        switch ( sampleRate )
791        {
792        case 32000:
793            regVal |= BCHP_FIELD_DATA(AUD_FMM_BF_CTRL_ADAPTRATE_CFGi, ADAPT_SAMPLINGRATE, 0);
794            break;
795        default:
796        case 48000:
797            regVal |= BCHP_FIELD_DATA(AUD_FMM_BF_CTRL_ADAPTRATE_CFGi, ADAPT_SAMPLINGRATE, 1);
798            break;
799        case 96000:
800            regVal |= BCHP_FIELD_DATA(AUD_FMM_BF_CTRL_ADAPTRATE_CFGi, ADAPT_SAMPLINGRATE, 2);
801            break;
802        case 192000:
803            regVal |= BCHP_FIELD_DATA(AUD_FMM_BF_CTRL_ADAPTRATE_CFGi, ADAPT_SAMPLINGRATE, 3);
804            break;
805        case 44100:
806            regVal |= BCHP_FIELD_DATA(AUD_FMM_BF_CTRL_ADAPTRATE_CFGi, ADAPT_SAMPLINGRATE, 4);
807            break;
808        case 88200:
809            regVal |= BCHP_FIELD_DATA(AUD_FMM_BF_CTRL_ADAPTRATE_CFGi, ADAPT_SAMPLINGRATE, 5);
810            break;
811        case 176400:
812            regVal |= BCHP_FIELD_DATA(AUD_FMM_BF_CTRL_ADAPTRATE_CFGi, ADAPT_SAMPLINGRATE, 6);
813            break;
814        }
815#endif
816        BREG_Write32_isr(deviceHandle->regHandle, regAddr, regVal);
817    }
818}
819
820void BAPE_SfifoGroup_P_GetOutputFciIds(
821    BAPE_SfifoGroupHandle handle,
822    BAPE_FciIdGroup *pFciGroup      /* [out] */
823    )
824{
825    unsigned i;
826    BDBG_ASSERT(NULL != handle);
827    BDBG_ASSERT(handle->allocated);
828    BDBG_ASSERT(NULL != pFciGroup);
829    BAPE_FciIdGroup_Init(pFciGroup);
830    for ( i = 0; i < handle->numChannelPairs; i++ )
831    {
832        pFciGroup->ids[i] = handle->sfifoIds[i];    /* SFIFO FCI ID Base is 0x000*/
833    }
834}
835
836BERR_Code BAPE_SfifoGroup_P_GetBuffer(
837    BAPE_SfifoGroupHandle handle,
838    BAPE_BufferDescriptor *pBuffers      /* [out] */
839    )
840{
841    BERR_Code errCode;
842    unsigned chPair;
843
844    BDBG_ASSERT(NULL != handle);
845    BDBG_ASSERT(handle->allocated);
846    BDBG_ASSERT(NULL != pBuffers);
847
848    BKNI_Memset(pBuffers, 0, sizeof(BAPE_BufferDescriptor));
849
850    /* TODO: Handle non-interleaved and multichannel */
851    pBuffers->interleaved = handle->settings.interleaveData;
852    if (pBuffers->interleaved) 
853    {
854        pBuffers->numBuffers = handle->numChannelPairs;
855    }
856    else
857    {
858        pBuffers->numBuffers = handle->numChannelPairs * 2;
859    }
860
861    for (chPair = 0; chPair < handle->numChannelPairs; chPair++) 
862    {
863        if (pBuffers->interleaved)
864        {
865            errCode = BAPE_Sfifo_P_GetBuffer(handle, pBuffers, chPair, 0);
866            if ( errCode )
867            {
868                errCode = BERR_TRACE(errCode);
869            }
870        }
871        else
872        {
873            errCode = BAPE_Sfifo_P_GetBuffer(handle, pBuffers, chPair, 0);
874            if ( errCode )
875            {
876                errCode = BERR_TRACE(errCode);
877            }
878
879            errCode = BAPE_Sfifo_P_GetBuffer(handle, pBuffers, chPair, 1);
880            if ( errCode )
881            {
882                errCode = BERR_TRACE(errCode);
883            }
884        }
885
886    }
887
888    return BERR_SUCCESS;
889}
890
891static BERR_Code BAPE_Sfifo_P_GetBuffer(
892    BAPE_SfifoGroupHandle handle,   
893    BAPE_BufferDescriptor *pBuffers,
894    unsigned chPair,                /*0,1,2,3*/
895    unsigned bufferNum              /*0,1*/
896    )
897{
898    BERR_Code errCode;
899
900    uint32_t rd,wr,base,sfifoId,rdaddr,wraddr;
901    unsigned bufferSize, padding=1024;
902
903    sfifoId = handle->sfifoIds[chPair];
904    bufferSize = handle->settings.bufferInfo[chPair*2 + bufferNum].length;
905    rd = BREG_Read32(handle->deviceHandle->regHandle, BAPE_P_SFIFO_TO_RDADDR_REG(sfifoId) + (bufferNum * BAPE_P_RINGBUFFER_STRIDE));
906    wr = BREG_Read32(handle->deviceHandle->regHandle, BAPE_P_SFIFO_TO_WRADDR_REG(sfifoId) + (bufferNum * BAPE_P_RINGBUFFER_STRIDE));
907    base = BREG_Read32(handle->deviceHandle->regHandle, BAPE_P_SFIFO_TO_BASEADDR_REG(sfifoId) + (bufferNum * BAPE_P_RINGBUFFER_STRIDE));
908
909    BDBG_MSG(("PB GetBuffer: RDADDR 0x%x WRADDR 0x%x BASEADDR 0x%x Size %d ", rd, wr, base, bufferSize));
910
911#ifdef BCHP_AUD_FMM_BF_CTRL_RINGBUF_0_RDADDR
912    rdaddr = BCHP_GET_FIELD_DATA(rd, AUD_FMM_BF_CTRL_RINGBUF_0_RDADDR, RINGBUF_RDADDR);
913    wraddr = BCHP_GET_FIELD_DATA(wr, AUD_FMM_BF_CTRL_RINGBUF_0_WRADDR, RINGBUF_WRADDR);
914#else
915    rdaddr = BCHP_GET_FIELD_DATA(rd, AUD_FMM_BF_CTRL_SOURCECH_RINGBUF_0_RDADDR, RINGBUF_RDADDR);
916    wraddr = BCHP_GET_FIELD_DATA(wr, AUD_FMM_BF_CTRL_SOURCECH_RINGBUF_0_WRADDR, RINGBUF_WRADDR);
917#endif
918
919    if (bufferNum == 0) 
920    {
921        errCode = BMEM_ConvertOffsetToAddress(handle->deviceHandle->memHandle, wraddr, &pBuffers->buffers[BAPE_Channel_eLeft].pBuffer);
922        if ( errCode )
923        {
924            errCode = BERR_TRACE(errCode);
925        }
926        errCode = BMEM_ConvertOffsetToAddress(handle->deviceHandle->memHandle, base, &pBuffers->buffers[BAPE_Channel_eLeft].pWrapBuffer);
927        if ( errCode )
928        {
929            errCode = BERR_TRACE(errCode);
930        }
931    }
932    else if (bufferNum == 1) 
933    {
934        errCode = BMEM_ConvertOffsetToAddress(handle->deviceHandle->memHandle, wraddr, &pBuffers->buffers[BAPE_Channel_eRight].pBuffer);
935        if ( errCode )
936        {
937            errCode = BERR_TRACE(errCode);
938        }
939        errCode = BMEM_ConvertOffsetToAddress(handle->deviceHandle->memHandle, base, &pBuffers->buffers[BAPE_Channel_eRight].pWrapBuffer);
940        if ( errCode )
941        {
942            errCode = BERR_TRACE(errCode);
943        }
944    }
945
946    if ( wraddr > rdaddr )
947    {
948        pBuffers->bufferSize = bufferSize - (wraddr-base);
949        pBuffers->wrapBufferSize = rdaddr-base;
950    }
951    else if ( wraddr < rdaddr )
952    {
953        pBuffers->bufferSize = rdaddr-wraddr;
954    }
955    else    /* equal */
956    {
957        if ( 
958#ifdef BCHP_AUD_FMM_BF_CTRL_RINGBUF_0_RDADDR
959             BCHP_GET_FIELD_DATA(rd, AUD_FMM_BF_CTRL_RINGBUF_0_RDADDR, RINGBUF_RDADDR_WRAP) ==
960             BCHP_GET_FIELD_DATA(wr, AUD_FMM_BF_CTRL_RINGBUF_0_WRADDR, RINGBUF_WRADDR_WRAP) 
961#else
962             BCHP_GET_FIELD_DATA(rd, AUD_FMM_BF_CTRL_SOURCECH_RINGBUF_0_RDADDR, RINGBUF_RDADDR_WRAP) ==
963             BCHP_GET_FIELD_DATA(wr, AUD_FMM_BF_CTRL_SOURCECH_RINGBUF_0_WRADDR, RINGBUF_WRADDR_WRAP) 
964#endif
965           )
966        {
967            /* Toggle bits are equal, buffer is empty. */
968            pBuffers->bufferSize = bufferSize - (wraddr-base);
969            pBuffers->wrapBufferSize = bufferSize - pBuffers->bufferSize;
970        }
971        else
972        {
973            /* Toggle bit mismatch, buffer is full. */
974            pBuffers->bufferSize = 0;
975        }
976    }
977
978    /* Don't allow entire buffer to be filled, need gap between rd/wr for master/slave setups */
979    if ( pBuffers->wrapBufferSize > padding )
980    {
981        pBuffers->wrapBufferSize -= padding;
982        padding = 0;
983    }
984    else
985    {
986        padding -= pBuffers->wrapBufferSize;
987        pBuffers->wrapBufferSize = 0;
988    }
989    if ( pBuffers->bufferSize > padding )
990    {
991        pBuffers->bufferSize -= padding;
992        padding = 0;
993    }
994    else
995    {
996        pBuffers->bufferSize = 0;
997    }
998
999    /* Make sure wrap pointers are NULL if we have no data */
1000    if (pBuffers->interleaved)
1001    {
1002        if ( pBuffers->wrapBufferSize == 0 )
1003        {
1004            pBuffers->buffers[bufferNum*2].pWrapBuffer = NULL;
1005        }
1006        if ( pBuffers->bufferSize == 0 )
1007        {
1008            pBuffers->buffers[bufferNum*2].pBuffer = NULL;
1009        }
1010    }
1011    else
1012    {
1013        if ( pBuffers->wrapBufferSize == 0 )
1014        {
1015            pBuffers->buffers[bufferNum].pWrapBuffer = NULL;
1016        }
1017        if ( pBuffers->bufferSize == 0 )
1018        {
1019            pBuffers->buffers[bufferNum].pBuffer = NULL;
1020        }
1021    }
1022    return BERR_SUCCESS;
1023}
1024
1025
1026
1027BERR_Code BAPE_SfifoGroup_P_CommitData(
1028    BAPE_SfifoGroupHandle handle,
1029    unsigned numBytes                   /* Number of bytes written into the buffer */
1030    )
1031{
1032    BERR_Code errCode;
1033    unsigned chPair;
1034
1035    BDBG_ASSERT(NULL != handle);
1036    BDBG_ASSERT(handle->allocated);
1037
1038    /* TODO: Handle multichannel and non-interleaved */
1039    for (chPair = 0; chPair < handle->numChannelPairs; chPair++) 
1040    {
1041        if (handle->settings.interleaveData)
1042        {
1043            errCode = BAPE_Sfifo_P_CommitData(handle, numBytes, chPair, 0);
1044            if ( errCode )
1045            {
1046                errCode = BERR_TRACE(errCode);
1047            }
1048        }
1049        else
1050        {
1051            errCode = BAPE_Sfifo_P_CommitData(handle, numBytes, chPair, 0);
1052            if ( errCode )
1053            {
1054                errCode = BERR_TRACE(errCode);
1055            }
1056            errCode = BAPE_Sfifo_P_CommitData(handle, numBytes, chPair, 1);
1057            if ( errCode )
1058            {
1059                errCode = BERR_TRACE(errCode);
1060            }
1061        }
1062    }
1063
1064    return BERR_SUCCESS;
1065}
1066
1067static BERR_Code BAPE_Sfifo_P_CommitData (BAPE_SfifoGroupHandle handle,                                                   
1068    unsigned numBytes,                   /* Number of bytes written into the buffer */
1069    unsigned chPair,                     /*0,1,2,3*/
1070    unsigned bufferNum                   /*0,1*/
1071    )                                                                               
1072{
1073
1074    uint32_t rd,wr,base,sfifoId,rdaddr,wraddr;
1075    unsigned bufferSize;
1076
1077    sfifoId = handle->sfifoIds[chPair];
1078    bufferSize = handle->settings.bufferInfo[chPair*2 + bufferNum].length;
1079    rd = BREG_Read32(handle->deviceHandle->regHandle, BAPE_P_SFIFO_TO_RDADDR_REG(sfifoId) + (bufferNum * BAPE_P_RINGBUFFER_STRIDE));
1080    wr = BREG_Read32(handle->deviceHandle->regHandle, BAPE_P_SFIFO_TO_WRADDR_REG(sfifoId) + (bufferNum * BAPE_P_RINGBUFFER_STRIDE));
1081    base = BREG_Read32(handle->deviceHandle->regHandle, BAPE_P_SFIFO_TO_BASEADDR_REG(sfifoId) + (bufferNum * BAPE_P_RINGBUFFER_STRIDE));
1082
1083    BDBG_MSG(("PB Commit: RDADDR 0x%x WRADDR 0x%x BASEADDR 0x%x Size %d ", rd, wr, base, bufferSize));
1084
1085#ifdef BCHP_AUD_FMM_BF_CTRL_RINGBUF_0_RDADDR
1086    rdaddr = BCHP_GET_FIELD_DATA(rd, AUD_FMM_BF_CTRL_RINGBUF_0_RDADDR, RINGBUF_RDADDR);
1087    wraddr = BCHP_GET_FIELD_DATA(wr, AUD_FMM_BF_CTRL_RINGBUF_0_WRADDR, RINGBUF_WRADDR);
1088#else
1089    rdaddr = BCHP_GET_FIELD_DATA(rd, AUD_FMM_BF_CTRL_SOURCECH_RINGBUF_0_RDADDR, RINGBUF_RDADDR);
1090    wraddr = BCHP_GET_FIELD_DATA(wr, AUD_FMM_BF_CTRL_SOURCECH_RINGBUF_0_WRADDR, RINGBUF_WRADDR);
1091#endif
1092
1093    /* Make sure the write pointer doesn't try and pass read */
1094    if ( rdaddr > wraddr )
1095    {
1096        if ( wraddr + numBytes > rdaddr )
1097        {
1098            BDBG_ERR(("Playback: Attempt to write more data than available in the buffer."));
1099            return BERR_TRACE(BERR_INVALID_PARAMETER);
1100        }
1101        else if ( wraddr + numBytes == rdaddr )
1102        {
1103            if ( 
1104#ifdef BCHP_AUD_FMM_BF_CTRL_RINGBUF_0_RDADDR
1105                 BCHP_GET_FIELD_DATA(rd, AUD_FMM_BF_CTRL_RINGBUF_0_RDADDR, RINGBUF_RDADDR_WRAP) ==
1106                 BCHP_GET_FIELD_DATA(wr, AUD_FMM_BF_CTRL_RINGBUF_0_WRADDR, RINGBUF_WRADDR_WRAP) 
1107#else
1108                 BCHP_GET_FIELD_DATA(rd, AUD_FMM_BF_CTRL_SOURCECH_RINGBUF_0_RDADDR, RINGBUF_RDADDR_WRAP) ==
1109                 BCHP_GET_FIELD_DATA(wr, AUD_FMM_BF_CTRL_SOURCECH_RINGBUF_0_WRADDR, RINGBUF_WRADDR_WRAP) 
1110#endif
1111                )
1112            {
1113                /* If the toggle bit is the same we will overflow. */
1114                BDBG_ERR(("Playback: Attempt to write more data than available in the buffer."));
1115                return BERR_TRACE(BERR_INVALID_PARAMETER);
1116            }
1117        }
1118    }
1119    else    /* rdaddr <= wraddr */
1120    {
1121        if ( wraddr + numBytes > (base + bufferSize) )
1122        {
1123            BDBG_ERR(("Playback: Attempt to write more data than available in the buffer."));
1124            return BERR_TRACE(BERR_INVALID_PARAMETER);
1125        }
1126    }
1127
1128    /* The request is legal.  Update the write pointer. */
1129    wraddr += numBytes;
1130#ifdef BCHP_AUD_FMM_BF_CTRL_RINGBUF_0_RDADDR
1131    wr &= ~BCHP_MASK(AUD_FMM_BF_CTRL_RINGBUF_0_WRADDR, RINGBUF_WRADDR);
1132    if ( wraddr == bufferSize + base )
1133    {
1134        BDBG_MSG(("Inverting toggle bit - was 0x%x now 0x%x", wr, wr ^ BCHP_FIELD_DATA(AUD_FMM_BF_CTRL_RINGBUF_0_WRADDR, RINGBUF_WRADDR_WRAP, 1)));
1135        wr ^= BCHP_FIELD_DATA(AUD_FMM_BF_CTRL_RINGBUF_0_WRADDR, RINGBUF_WRADDR_WRAP, 1);   /* flip the toggle bit */
1136        wraddr = base;
1137    }
1138    wr |= BCHP_FIELD_DATA(AUD_FMM_BF_CTRL_RINGBUF_0_WRADDR, RINGBUF_WRADDR, wraddr);
1139#else
1140    wr &= ~BCHP_MASK(AUD_FMM_BF_CTRL_SOURCECH_RINGBUF_0_WRADDR, RINGBUF_WRADDR);
1141    if ( wraddr == bufferSize + base )
1142    {
1143        BDBG_MSG(("Inverting toggle bit - was 0x%x now 0x%x", wr, wr ^ BCHP_FIELD_DATA(AUD_FMM_BF_CTRL_SOURCECH_RINGBUF_0_WRADDR, RINGBUF_WRADDR_WRAP, 1)));
1144        wr ^= BCHP_FIELD_DATA(AUD_FMM_BF_CTRL_SOURCECH_RINGBUF_0_WRADDR, RINGBUF_WRADDR_WRAP, 1);   /* flip the toggle bit */
1145        wraddr = base;
1146    }
1147    wr |= BCHP_FIELD_DATA(AUD_FMM_BF_CTRL_SOURCECH_RINGBUF_0_WRADDR, RINGBUF_WRADDR, wraddr);
1148#endif
1149    BREG_Write32(handle->deviceHandle->regHandle, BAPE_P_SFIFO_TO_WRADDR_REG(sfifoId) + (bufferNum * BAPE_P_RINGBUFFER_STRIDE), wr);
1150
1151    return BERR_SUCCESS;
1152}
1153
1154
1155
1156BERR_Code BAPE_SfifoGroup_P_Flush(
1157    BAPE_SfifoGroupHandle handle
1158    )
1159{   
1160    unsigned bufferNum;
1161
1162    BDBG_ASSERT(NULL != handle);
1163    BDBG_ASSERT(handle->allocated);
1164
1165    /* TODO: Handle multichannel */
1166
1167    /* Flush by making write pointer equal to read pointer */
1168    if (handle->settings.interleaveData) 
1169    {
1170        for (bufferNum = 0; bufferNum < handle->numChannelPairs; bufferNum++) 
1171        {
1172            BREG_Write32(handle->deviceHandle->regHandle,
1173                         BAPE_P_SFIFO_TO_WRADDR_REG(handle->sfifoIds[bufferNum]),
1174                         BREG_Read32(handle->deviceHandle->regHandle,
1175                                     BAPE_P_SFIFO_TO_RDADDR_REG(handle->sfifoIds[bufferNum])));
1176        }
1177    }
1178    else
1179    {
1180        for (bufferNum = 0; bufferNum < handle->numChannelPairs; bufferNum++) 
1181        {
1182            BREG_Write32(handle->deviceHandle->regHandle,
1183                         BAPE_P_SFIFO_TO_WRADDR_REG(handle->sfifoIds[bufferNum]),
1184                         BREG_Read32(handle->deviceHandle->regHandle,
1185                                     BAPE_P_SFIFO_TO_RDADDR_REG(handle->sfifoIds[bufferNum])));
1186
1187            BREG_Write32(handle->deviceHandle->regHandle,
1188                         BAPE_P_SFIFO_TO_WRADDR_REG(handle->sfifoIds[bufferNum]) + BAPE_P_RINGBUFFER_STRIDE,
1189                         BREG_Read32(handle->deviceHandle->regHandle,
1190                                     BAPE_P_SFIFO_TO_RDADDR_REG(handle->sfifoIds[bufferNum] + BAPE_P_RINGBUFFER_STRIDE)));
1191        }
1192    }
1193
1194    return BERR_SUCCESS;
1195}
1196
1197BERR_Code BAPE_SfifoGroup_P_GetQueuedBytes(
1198    BAPE_SfifoGroupHandle handle,
1199    unsigned *pQueuedBytes
1200    )
1201{
1202    BERR_Code errCode;
1203    uint32_t chPair;
1204
1205    BDBG_ASSERT(NULL != handle);
1206    BDBG_ASSERT(handle->allocated);
1207    BDBG_ASSERT(NULL != pQueuedBytes);
1208
1209    /* TODO: Handle non-interleaved and multichannel */
1210    for (chPair = 0; chPair < handle->numChannelPairs; chPair++) 
1211    {
1212        if (handle->settings.interleaveData)
1213        {
1214            errCode = BAPE_Sfifo_P_GetQueuedBytes(handle, pQueuedBytes, chPair, 0 );
1215            if ( errCode )
1216            {
1217                errCode = BERR_TRACE(errCode);
1218            }
1219        }
1220        else
1221        {
1222            errCode = BAPE_Sfifo_P_GetQueuedBytes(handle, pQueuedBytes, chPair, 0);
1223            if ( errCode )
1224            {
1225                errCode = BERR_TRACE(errCode);
1226            }
1227            errCode = BAPE_Sfifo_P_GetQueuedBytes(handle, pQueuedBytes, chPair, 1);
1228            if ( errCode )
1229            {
1230                errCode = BERR_TRACE(errCode);
1231            }
1232        }
1233
1234    }
1235
1236    return BERR_SUCCESS;
1237}
1238
1239static BERR_Code BAPE_Sfifo_P_GetQueuedBytes(
1240    BAPE_SfifoGroupHandle handle, 
1241    unsigned *pQueuedBytes,
1242    unsigned chPair,       /*0,1,2,3*/
1243    unsigned bufferNum     /*0,1*/
1244    )
1245{
1246    uint32_t rd,wr,base,sfifoId,rdaddr,wraddr;
1247    unsigned bufferSize, queuedBytes;
1248
1249    sfifoId = handle->sfifoIds[chPair];
1250    bufferSize = handle->settings.bufferInfo[chPair*2 + bufferNum].length;
1251    rd = BREG_Read32(handle->deviceHandle->regHandle, BAPE_P_SFIFO_TO_RDADDR_REG(sfifoId) + (bufferNum * BAPE_P_RINGBUFFER_STRIDE));
1252    wr = BREG_Read32(handle->deviceHandle->regHandle, BAPE_P_SFIFO_TO_WRADDR_REG(sfifoId) + (bufferNum * BAPE_P_RINGBUFFER_STRIDE));
1253    base = BREG_Read32(handle->deviceHandle->regHandle, BAPE_P_SFIFO_TO_BASEADDR_REG(sfifoId) + (bufferNum * BAPE_P_RINGBUFFER_STRIDE));
1254
1255#ifdef BCHP_AUD_FMM_BF_CTRL_RINGBUF_0_RDADDR
1256    rdaddr = BCHP_GET_FIELD_DATA(rd, AUD_FMM_BF_CTRL_RINGBUF_0_RDADDR, RINGBUF_RDADDR);
1257    wraddr = BCHP_GET_FIELD_DATA(wr, AUD_FMM_BF_CTRL_RINGBUF_0_WRADDR, RINGBUF_WRADDR);
1258#else
1259    rdaddr = BCHP_GET_FIELD_DATA(rd, AUD_FMM_BF_CTRL_SOURCECH_RINGBUF_0_RDADDR, RINGBUF_RDADDR);
1260    wraddr = BCHP_GET_FIELD_DATA(wr, AUD_FMM_BF_CTRL_SOURCECH_RINGBUF_0_WRADDR, RINGBUF_WRADDR);
1261#endif
1262
1263    if ( wraddr > rdaddr )
1264    {
1265        queuedBytes = wraddr-rdaddr;
1266    }
1267    else if ( wraddr < rdaddr )
1268    {
1269        queuedBytes = (wraddr-base)+(bufferSize-(rdaddr-base));
1270    }
1271    else    /* equal */
1272    {
1273        if ( 
1274#ifdef BCHP_AUD_FMM_BF_CTRL_RINGBUF_0_RDADDR
1275             BCHP_GET_FIELD_DATA(rd, AUD_FMM_BF_CTRL_RINGBUF_0_RDADDR, RINGBUF_RDADDR_WRAP) ==
1276             BCHP_GET_FIELD_DATA(wr, AUD_FMM_BF_CTRL_RINGBUF_0_WRADDR, RINGBUF_WRADDR_WRAP) 
1277#else
1278             BCHP_GET_FIELD_DATA(rd, AUD_FMM_BF_CTRL_SOURCECH_RINGBUF_0_RDADDR, RINGBUF_RDADDR_WRAP) ==
1279             BCHP_GET_FIELD_DATA(wr, AUD_FMM_BF_CTRL_SOURCECH_RINGBUF_0_WRADDR, RINGBUF_WRADDR_WRAP) 
1280#endif
1281            )
1282        {
1283            /* Toggle bits are equal, buffer is empty. */
1284            queuedBytes = 0;
1285        }
1286        else
1287        {
1288            /* Toggle bit mismatch, buffer is full. */
1289            queuedBytes = bufferSize;
1290        }
1291    }
1292    *pQueuedBytes = queuedBytes;
1293
1294    return BERR_SUCCESS;
1295}
1296
1297
1298BERR_Code BAPE_SfifoGroup_P_SetFreemarkInterrupt(
1299    BAPE_SfifoGroupHandle handle,
1300    BINT_CallbackFunc callback_isr,
1301    void *pParam1,
1302    int param2
1303    )
1304{
1305    BDBG_ASSERT(NULL != handle);
1306    BDBG_ASSERT(handle->allocated);
1307
1308    return BAPE_P_SetSourceChannelFreemarkInterrupt(handle->deviceHandle, handle->sfifoIds[0], callback_isr, pParam1, param2);
1309}
1310
1311void BAPE_SfifoGroup_P_RearmFreemarkInterrupt(
1312    BAPE_SfifoGroupHandle handle
1313    )
1314{
1315    uint32_t regVal;
1316    BDBG_ASSERT(NULL != handle);
1317    BDBG_ASSERT(handle->allocated);
1318
1319    regVal = 1<<handle->sfifoIds[0];
1320#ifdef BCHP_AUD_FMM_BF_CTRL_REARM_FREEFULL_MARK
1321    BREG_Write32(handle->deviceHandle->regHandle, BCHP_AUD_FMM_BF_CTRL_REARM_FREEFULL_MARK, regVal);
1322#else
1323    BREG_Write32(handle->deviceHandle->regHandle, BCHP_AUD_FMM_BF_CTRL_REARM_FREE_MARK, regVal);
1324#endif
1325}
1326
1327uint32_t BAPE_SfifoGroup_P_GetHwIndex(
1328    BAPE_SfifoGroupHandle handle,
1329    BAPE_ChannelPair channelPair
1330    )
1331{
1332    BDBG_ASSERT(NULL != handle);
1333    BDBG_ASSERT(handle->allocated);
1334
1335    if ( channelPair >= handle->numChannelPairs )
1336    {
1337        return 0xFFFFFFFF;
1338    }
1339    else
1340    {
1341        return handle->sfifoIds[channelPair];
1342    }
1343}
1344
1345uint32_t BAPE_SfifoGroup_P_GetAdaptRateHwIndex(
1346    BAPE_SfifoGroupHandle handle,
1347    BAPE_ChannelPair channelPair
1348    )
1349{
1350    BDBG_ASSERT(NULL != handle);
1351    BDBG_ASSERT(handle->allocated);
1352
1353    if ( channelPair >= handle->numChannelPairs )
1354    {
1355        return 0xFFFFFFFF;
1356    }
1357    else
1358    {
1359        return handle->adaptRateIds[channelPair];
1360    }
1361}
1362
1363void BAPE_DfifoGroup_P_GetDefaultCreateSettings(
1364    BAPE_DfifoGroupCreateSettings *pSettings    /* [out] */
1365    )
1366{
1367    BDBG_ASSERT(NULL != pSettings);
1368    pSettings->numChannelPairs = 1;
1369}
1370
1371BERR_Code BAPE_DfifoGroup_P_Create(
1372    BAPE_Handle deviceHandle,
1373    const BAPE_DfifoGroupCreateSettings *pSettings,
1374    BAPE_DfifoGroupHandle *pHandle  /* [out] */
1375    )
1376{
1377    unsigned i, dfifo;
1378    BERR_Code errCode;
1379    BAPE_DfifoGroupHandle handle=NULL;
1380
1381    BDBG_OBJECT_ASSERT(deviceHandle, BAPE_Device);
1382    BDBG_ASSERT(NULL != pSettings);
1383    BDBG_ASSERT(NULL != pHandle);
1384    BDBG_ASSERT(pSettings->numChannelPairs <= BAPE_ChannelPair_eMax);
1385
1386    /* Find an available group handle */
1387    for ( i = 0; i < BAPE_CHIP_MAX_DFIFO_GROUPS; i++ )
1388    {
1389        BDBG_ASSERT(NULL != deviceHandle->dfifoGroups[i]);
1390        if ( !deviceHandle->dfifoGroups[i]->allocated )
1391        {
1392            handle = deviceHandle->dfifoGroups[i];
1393            break;
1394        }
1395    }
1396
1397    /* If none found, return error */
1398    if ( NULL == handle )
1399    {
1400        return BERR_TRACE(BERR_NOT_SUPPORTED);
1401    }
1402
1403    /* Now search for the correct number of resources */
1404    /* TODO: DFIFO's technically don't group so they could be allocated individually
1405       rather than as a group if that helps optimize resource usage */
1406    errCode = BAPE_P_AllocateFmmResource(deviceHandle, BAPE_FmmResourceType_eDfifo, pSettings->numChannelPairs, &dfifo);
1407    if ( errCode )
1408    {
1409        errCode = BERR_TRACE(errCode);
1410        goto err_alloc_dfifo;
1411    }
1412
1413    /* Successfully allocated resources.  Initialize Group */
1414    handle->allocated = true;
1415    handle->started = false;
1416    handle->numChannelPairs = pSettings->numChannelPairs;
1417    handle->deviceHandle = deviceHandle;
1418    BKNI_Memset(&handle->settings, 0, sizeof(handle->settings));
1419    BAPE_FciIdGroup_Init(&handle->settings.input);
1420    handle->settings.dataWidth = 32;
1421    BKNI_Memset(handle->dfifoIds, 0xff, sizeof(handle->dfifoIds));
1422    for ( i = 0; i < pSettings->numChannelPairs; i++ )
1423    {
1424        handle->dfifoIds[i] = dfifo + i;
1425        /* DFIFO's don't support grouping, rather the inputs are grouped */
1426    }
1427    *pHandle = handle;
1428    return BERR_SUCCESS;
1429
1430    err_alloc_dfifo:
1431    return errCode;
1432}
1433
1434void BAPE_DfifoGroup_P_Destroy(
1435    BAPE_DfifoGroupHandle handle
1436    )
1437{
1438    BDBG_ASSERT(NULL != handle);
1439    BDBG_ASSERT(handle->allocated);
1440    BDBG_ASSERT(!handle->started);
1441    BDBG_OBJECT_ASSERT(handle->deviceHandle, BAPE_Device);
1442
1443    /* Release Resources */
1444    BAPE_P_FreeFmmResource(handle->deviceHandle, BAPE_FmmResourceType_eDfifo, handle->numChannelPairs, handle->dfifoIds[0]);
1445    BKNI_Memset(handle->dfifoIds, 0xff, sizeof(handle->dfifoIds));
1446    handle->allocated = false;
1447}
1448
1449void BAPE_DfifoGroup_P_GetSettings(
1450    BAPE_DfifoGroupHandle handle,
1451    BAPE_DfifoGroupSettings *pSettings  /* [out] */
1452    )
1453{
1454    BDBG_ASSERT(NULL != handle);
1455    BDBG_ASSERT(handle->allocated);
1456    *pSettings = handle->settings;
1457}
1458
1459BERR_Code BAPE_DfifoGroup_P_SetSettings(
1460    BAPE_DfifoGroupHandle handle,
1461    const BAPE_DfifoGroupSettings *pSettings
1462    )
1463{
1464    BDBG_ASSERT(NULL != handle);
1465    BDBG_ASSERT(handle->allocated);
1466
1467    if ( handle->started )
1468    {
1469        return BERR_TRACE(BERR_NOT_SUPPORTED);
1470    }
1471
1472    switch ( pSettings->dataWidth )
1473    {
1474    case 0:
1475    case 32:
1476#if BAPE_CHIP_DFIFO_SUPPORTS_16BIT_CAPTURE
1477    case 16:
1478#endif
1479        /* Supported */
1480        break;
1481    default:
1482        BDBG_ERR(("This chip does not support %u-bit DFIFO Capture", pSettings->dataWidth));
1483        return BERR_TRACE(BERR_NOT_SUPPORTED);
1484    }
1485
1486    handle->settings = *pSettings;
1487
1488    return BERR_SUCCESS;
1489}
1490
1491static void BAPE_DfifoGroup_P_ApplySettings(
1492    BAPE_DfifoGroupHandle handle
1493    )
1494{
1495    uint32_t regAddr, regVal, regMask, regData;
1496    unsigned i;
1497    bool playFromCapture, captureToSfifo;
1498    BREG_Handle regHandle;
1499
1500    regHandle = handle->deviceHandle->regHandle;
1501
1502    if ( NULL == handle->settings.linkedSfifo )
1503    {
1504        /* No SFIFO was provided.  This should capture to memory only. */
1505        BDBG_ASSERT(handle->settings.bypassMemory == false);
1506        playFromCapture = false;
1507        captureToSfifo = false;
1508    }
1509    else
1510    {
1511        /* SFIFO provided.  Determine if we are bypassing memory (CAPTURE_TO_SOURCEFIFO) or capturing to the SFIFO ringbuffers (PLAY_FROM_CAPTURE). */
1512        captureToSfifo = handle->settings.bypassMemory;
1513        playFromCapture = !captureToSfifo;
1514    }
1515
1516    for ( i = 0; i < handle->numChannelPairs; i++ )
1517    {
1518        uint32_t sfifoId = (handle->settings.linkedSfifo) ? handle->settings.linkedSfifo->sfifoIds[i] : 0x1f;   /* Use an invalid SFIFO ID if one is not provided otherwise the DFIFOs may conflict */
1519        uint32_t fciId = handle->settings.input.ids[i];
1520        uint32_t base, end, watermark;
1521#ifdef BCHP_AUD_FMM_BF_CTRL_DESTCH_CFG0
1522        regAddr = BCHP_AUD_FMM_BF_CTRL_DESTCH_CFG0;
1523        regMask = 
1524        BCHP_MASK(AUD_FMM_BF_CTRL_DESTCH_CFG0, CAPTURE_ENABLE)|
1525        BCHP_MASK(AUD_FMM_BF_CTRL_DESTCH_CFG0, BUFFER_PAIR_ENABLE)|
1526        BCHP_MASK(AUD_FMM_BF_CTRL_DESTCH_CFG0, DESTFIFO_SIZE_DOUBLE)|
1527        BCHP_MASK(AUD_FMM_BF_CTRL_DESTCH_CFG0, PLAY_FROM_CAPTURE)|
1528        BCHP_MASK(AUD_FMM_BF_CTRL_DESTCH_CFG0, CAPTURE_TO_SOURCEFIFO)|
1529        BCHP_MASK(AUD_FMM_BF_CTRL_DESTCH_CFG0, PLAY_FROM_CAPTURE)|
1530        BCHP_MASK(AUD_FMM_BF_CTRL_DESTCH_CFG0, SOURCE_FIFO_ID)|
1531        BCHP_MASK(AUD_FMM_BF_CTRL_DESTCH_CFG0, NOT_PAUSE_WHEN_FULL)|
1532        BCHP_MASK(AUD_FMM_BF_CTRL_DESTCH_CFG0, FCI_CAP_ID)|
1533        BCHP_MASK(AUD_FMM_BF_CTRL_DESTCH_CFG0, PROCESS_ID_HIGH)|
1534        BCHP_MASK(AUD_FMM_BF_CTRL_DESTCH_CFG0, PROCESS_SEQ_ID_VALID);
1535        regData = 
1536        BCHP_FIELD_DATA(AUD_FMM_BF_CTRL_DESTCH_CFG0, BUFFER_PAIR_ENABLE, (handle->settings.interleaveData)?0:1) |
1537        BCHP_FIELD_DATA(AUD_FMM_BF_CTRL_DESTCH_CFG0, DESTFIFO_SIZE_DOUBLE, (handle->settings.interleaveData)?1:0) |
1538        BCHP_FIELD_DATA(AUD_FMM_BF_CTRL_DESTCH_CFG0, CAPTURE_TO_SOURCEFIFO, (captureToSfifo)?1:0) |
1539        BCHP_FIELD_DATA(AUD_FMM_BF_CTRL_DESTCH_CFG0, PLAY_FROM_CAPTURE, (playFromCapture)?1:0) |
1540        BCHP_FIELD_DATA(AUD_FMM_BF_CTRL_DESTCH_CFG0, SOURCE_FIFO_ID, sfifoId) |
1541        BCHP_FIELD_DATA(AUD_FMM_BF_CTRL_DESTCH_CFG0, FCI_CAP_ID, fciId) |
1542        BCHP_FIELD_DATA(AUD_FMM_BF_CTRL_DESTCH_CFG0, PROCESS_ID_HIGH, (handle->settings.highPriority)?1:0) |
1543        BCHP_FIELD_DATA(AUD_FMM_BF_CTRL_DESTCH_CFG0, PROCESS_SEQ_ID_VALID, 1);
1544#if BAPE_CHIP_DFIFO_SUPPORTS_16BIT_CAPTURE
1545        regMask |= BCHP_MASK(AUD_FMM_BF_CTRL_DESTCH_CFGi, CAPTURE_MODE);
1546        if ( handle->settings.dataWidth == 16 )
1547        {
1548            regData |= BCHP_FIELD_ENUM(AUD_FMM_BF_CTRL_DESTCH_CFG0, CAPTURE_MODE, Compressed);
1549        }
1550        else
1551        {
1552            regData |= BCHP_FIELD_ENUM(AUD_FMM_BF_CTRL_DESTCH_CFG0, CAPTURE_MODE, PCM);
1553        }
1554#endif
1555#else
1556        regAddr = BCHP_AUD_FMM_BF_CTRL_DESTCH_CFGi_ARRAY_BASE;
1557        regAddr += handle->dfifoIds[i]*(BCHP_AUD_FMM_BF_CTRL_DESTCH_CFGi_ARRAY_ELEMENT_SIZE/8);
1558        regMask = 
1559        BCHP_MASK(AUD_FMM_BF_CTRL_DESTCH_CFGi, CAPTURE_ENABLE)|
1560        BCHP_MASK(AUD_FMM_BF_CTRL_DESTCH_CFGi, BUFFER_PAIR_ENABLE)|
1561        BCHP_MASK(AUD_FMM_BF_CTRL_DESTCH_CFGi, DESTFIFO_SIZE_DOUBLE)|
1562        BCHP_MASK(AUD_FMM_BF_CTRL_DESTCH_CFGi, PLAY_FROM_CAPTURE)|
1563        BCHP_MASK(AUD_FMM_BF_CTRL_DESTCH_CFGi, CAPTURE_TO_SOURCEFIFO)|
1564        BCHP_MASK(AUD_FMM_BF_CTRL_DESTCH_CFGi, PLAY_FROM_CAPTURE)|
1565        BCHP_MASK(AUD_FMM_BF_CTRL_DESTCH_CFGi, SOURCE_FIFO_ID)|
1566        BCHP_MASK(AUD_FMM_BF_CTRL_DESTCH_CFGi, NOT_PAUSE_WHEN_FULL)|
1567        BCHP_MASK(AUD_FMM_BF_CTRL_DESTCH_CFGi, FCI_CAP_ID)|
1568        BCHP_MASK(AUD_FMM_BF_CTRL_DESTCH_CFGi, PROCESS_ID_HIGH)|
1569        BCHP_MASK(AUD_FMM_BF_CTRL_DESTCH_CFGi, PROCESS_SEQ_ID_VALID);
1570        regData = 
1571        BCHP_FIELD_DATA(AUD_FMM_BF_CTRL_DESTCH_CFGi, BUFFER_PAIR_ENABLE, (handle->settings.interleaveData)?0:1) |
1572        BCHP_FIELD_DATA(AUD_FMM_BF_CTRL_DESTCH_CFGi, DESTFIFO_SIZE_DOUBLE, (handle->settings.interleaveData)?1:0) |
1573        BCHP_FIELD_DATA(AUD_FMM_BF_CTRL_DESTCH_CFGi, CAPTURE_TO_SOURCEFIFO, (captureToSfifo)?1:0) |
1574        BCHP_FIELD_DATA(AUD_FMM_BF_CTRL_DESTCH_CFGi, PLAY_FROM_CAPTURE, (playFromCapture)?1:0) |
1575        BCHP_FIELD_DATA(AUD_FMM_BF_CTRL_DESTCH_CFGi, SOURCE_FIFO_ID, sfifoId) |
1576        BCHP_FIELD_DATA(AUD_FMM_BF_CTRL_DESTCH_CFGi, FCI_CAP_ID, fciId) |
1577        BCHP_FIELD_DATA(AUD_FMM_BF_CTRL_DESTCH_CFGi, PROCESS_ID_HIGH, (handle->settings.highPriority)?1:0) |
1578        BCHP_FIELD_DATA(AUD_FMM_BF_CTRL_DESTCH_CFGi, PROCESS_SEQ_ID_VALID, 1);   
1579#if BAPE_CHIP_DFIFO_SUPPORTS_16BIT_CAPTURE
1580        regMask |= BCHP_MASK(AUD_FMM_BF_CTRL_DESTCH_CFGi, CAPTURE_MODE);
1581        if ( handle->settings.dataWidth == 16 )
1582        {
1583            regData |= BCHP_FIELD_ENUM(AUD_FMM_BF_CTRL_DESTCH_CFGi, CAPTURE_MODE, Compressed);
1584        }
1585        else
1586        {
1587            regData |= BCHP_FIELD_ENUM(AUD_FMM_BF_CTRL_DESTCH_CFGi, CAPTURE_MODE, PCM);
1588        }
1589#endif
1590#endif
1591
1592        /* configure channel based on above settings */   
1593        regVal = BREG_Read32(regHandle, regAddr);
1594        regVal = (regVal & ~regMask) | regData;
1595        BREG_Write32(regHandle, regAddr, regVal);
1596
1597        /* program ringbuffer addresses */
1598        /* Setup Ringbuffer Registers */
1599        regAddr = BAPE_P_DFIFO_TO_RDADDR_REG(handle->dfifoIds[i]);
1600        base = handle->settings.bufferInfo[2*i].base;
1601        end = base + handle->settings.bufferInfo[2*i].length - 1;
1602        watermark = handle->settings.bufferInfo[2*i].watermark;
1603        BREG_Write32(regHandle, regAddr, base);
1604        regAddr += 4;   /* Write is next */
1605        BREG_Write32(regHandle, regAddr, base);
1606        regAddr += 4;   /* Base is next */
1607        BREG_Write32(regHandle, regAddr, base);
1608        regAddr += 4;   /* End is next */
1609        BREG_Write32(regHandle, regAddr, end);
1610        regAddr += 4;   /* Freefull is next */
1611        BREG_Write32(regHandle, regAddr, watermark);
1612        regAddr += 4;   /* WRPOINT is last */
1613        BREG_Write32(regHandle, regAddr, 0);
1614        if ( handle->settings.interleaveData )
1615        {
1616            base=end=watermark=0;
1617        }
1618        else
1619        {
1620            base = handle->settings.bufferInfo[(2*i)+1].base;
1621            end = base + handle->settings.bufferInfo[(2*i)+1].length - 1;
1622            watermark = handle->settings.bufferInfo[(2*i)+1].watermark;
1623        }
1624        regAddr += 4;   /* Next RDADDR */
1625        BREG_Write32(regHandle, regAddr, base);
1626        regAddr += 4;   /* Write is next */
1627        BREG_Write32(regHandle, regAddr, base);
1628        regAddr += 4;   /* Base is next */
1629        BREG_Write32(regHandle, regAddr, base);
1630        regAddr += 4;   /* End is next */
1631        BREG_Write32(regHandle, regAddr, end);
1632        regAddr += 4;   /* Freefull is next */
1633        BREG_Write32(regHandle, regAddr, watermark);
1634        regAddr += 4;   /* WRPOINT is last */
1635        BREG_Write32(regHandle, regAddr, 0);
1636    }
1637}
1638
1639static void BAPE_DfifoGroup_P_SetCaptureEnable(
1640    BAPE_DfifoGroupHandle handle,
1641    uint32_t value
1642    )
1643{
1644    uint32_t baseAddr, stride, mask, data, regVal, regAddr;
1645    unsigned i;
1646    BAPE_Handle deviceHandle;
1647
1648    deviceHandle = handle->deviceHandle;
1649    BDBG_OBJECT_ASSERT(deviceHandle, BAPE_Device);
1650
1651#ifdef BCHP_AUD_FMM_BF_CTRL_DESTCH_CFG0
1652    baseAddr = BCHP_AUD_FMM_BF_CTRL_DESTCH_CFG0;
1653    stride = 0;
1654    mask = 
1655    BCHP_MASK(AUD_FMM_BF_CTRL_DESTCH_CFG0, CAPTURE_ENABLE)|
1656    BCHP_MASK(AUD_FMM_BF_CTRL_DESTCH_CFG0, PROCESS_SEQ_ID_VALID);
1657    data = 
1658    BCHP_FIELD_DATA(AUD_FMM_BF_CTRL_DESTCH_CFG0, CAPTURE_ENABLE, value)|
1659    BCHP_FIELD_DATA(AUD_FMM_BF_CTRL_DESTCH_CFG0, PROCESS_SEQ_ID_VALID, value);
1660#else
1661    baseAddr = BCHP_AUD_FMM_BF_CTRL_DESTCH_CFGi_ARRAY_BASE;
1662    stride = BCHP_AUD_FMM_BF_CTRL_DESTCH_CFGi_ARRAY_ELEMENT_SIZE/8;
1663    mask = 
1664    BCHP_MASK(AUD_FMM_BF_CTRL_DESTCH_CFGi, CAPTURE_ENABLE)|
1665    BCHP_MASK(AUD_FMM_BF_CTRL_DESTCH_CFGi, PROCESS_SEQ_ID_VALID);
1666    data = 
1667    BCHP_FIELD_DATA(AUD_FMM_BF_CTRL_DESTCH_CFGi, CAPTURE_ENABLE, value)|
1668    BCHP_FIELD_DATA(AUD_FMM_BF_CTRL_DESTCH_CFGi, PROCESS_SEQ_ID_VALID, value);
1669#endif   
1670
1671    for ( i = 0; i < handle->numChannelPairs; i++ )
1672    {
1673        regAddr = baseAddr + (handle->dfifoIds[i]*stride);
1674        regVal = BREG_Read32(deviceHandle->regHandle, regAddr);
1675        regVal = (regVal & ~mask) | data;
1676        BREG_Write32(deviceHandle->regHandle, regAddr, regVal);
1677    }
1678}
1679
1680#define BAPE_DfifoGroup_P_SetCaptureRun_isr(h, val) do { BKNI_ASSERT_ISR_CONTEXT(); BAPE_DfifoGroup_P_SetCaptureRun((h), (val)); } while (0)
1681static void BAPE_DfifoGroup_P_SetCaptureRun(
1682    BAPE_DfifoGroupHandle handle,
1683    uint32_t value
1684    )
1685{
1686    uint32_t baseAddr, stride;
1687    unsigned i;
1688
1689    /* These registers are not read/modify/write and thus are safe from either task or interrupt context */
1690
1691    BDBG_OBJECT_ASSERT(handle->deviceHandle, BAPE_Device);
1692
1693#ifdef BCHP_AUD_FMM_BF_CTRL_DESTCH_CTRL0
1694    baseAddr = BCHP_AUD_FMM_BF_CTRL_DESTCH_CTRL0;
1695    stride = 0;
1696#else
1697    baseAddr = BCHP_AUD_FMM_BF_CTRL_DESTCH_CTRLi_ARRAY_BASE;
1698    stride = BCHP_AUD_FMM_BF_CTRL_DESTCH_CTRLi_ARRAY_ELEMENT_SIZE/8;
1699#endif   
1700
1701    for ( i = 0; i < handle->numChannelPairs; i++ )
1702    {
1703        BREG_Write32(handle->deviceHandle->regHandle, baseAddr + (handle->dfifoIds[i])*stride, value);
1704    }
1705}
1706
1707BERR_Code BAPE_DfifoGroup_P_Start(
1708    BAPE_DfifoGroupHandle handle,
1709    bool enableOnly                 /* If true, a separate call to BAPE_DfifoGroup_P_Run_isr is required to
1710                                    start data flow.  If false, data flow will start immediately. */
1711    )
1712{
1713    BDBG_ASSERT(NULL != handle);
1714    BDBG_ASSERT(handle->allocated);
1715
1716    BAPE_DfifoGroup_P_ApplySettings(handle);
1717
1718    /* Enable */
1719    BAPE_DfifoGroup_P_SetCaptureEnable(handle, 1);
1720
1721    handle->started = true;
1722
1723    if ( !enableOnly )
1724    {
1725        /* Run */
1726        BAPE_DfifoGroup_P_SetCaptureRun(handle, 1);
1727    }
1728
1729    return BERR_SUCCESS;
1730}
1731
1732void BAPE_DfifoGroup_P_Stop(
1733    BAPE_DfifoGroupHandle handle
1734    )
1735{
1736    BDBG_ASSERT(NULL != handle);
1737    BDBG_ASSERT(handle->allocated);
1738
1739    /* Halt */
1740    BAPE_DfifoGroup_P_SetCaptureRun(handle, 0);
1741
1742    /* Enable */
1743    BAPE_DfifoGroup_P_SetCaptureEnable(handle, 0);
1744
1745    /* Reset Ringbuffer Registers to 0 */
1746
1747    handle->started = false;
1748}
1749
1750void BAPE_DfifoGroup_P_Run_isr(
1751    BAPE_DfifoGroupHandle handle
1752    )
1753{
1754    BKNI_ASSERT_ISR_CONTEXT();
1755    BDBG_ASSERT(NULL != handle);
1756    BDBG_ASSERT(handle->allocated);
1757    if ( !handle->started )
1758    {
1759        BDBG_ERR(("DFIFO Group %#x is not started, can not run.", handle));
1760        return;
1761    }
1762
1763    BAPE_DfifoGroup_P_SetCaptureRun_isr(handle, 1);
1764}
1765
1766void BAPE_DfifoGroup_P_Halt_isr(
1767    BAPE_DfifoGroupHandle handle
1768    )
1769{
1770    BKNI_ASSERT_ISR_CONTEXT();
1771    BDBG_ASSERT(NULL != handle);
1772    BDBG_ASSERT(handle->allocated);
1773    if ( !handle->started )
1774    {
1775        BDBG_ERR(("DFIFO Group %#x is not started, can not halt.", handle));
1776        return;
1777    }
1778    BAPE_DfifoGroup_P_SetCaptureRun_isr(handle, 0);
1779}
1780
1781BERR_Code BAPE_DfifoGroup_P_GetBuffer_isr(
1782    BAPE_DfifoGroupHandle handle,
1783    BAPE_BufferDescriptor *pBuffers      /* [out] */
1784    )
1785{
1786    uint32_t rd, wr, base, wrap;
1787    unsigned bufferSize, fifoSize, i, minBufferSize=0x7fffffff;
1788    BERR_Code errCode;
1789
1790    BDBG_ASSERT(NULL != handle);
1791    BDBG_ASSERT(handle->allocated);
1792    BDBG_ASSERT(NULL != pBuffers);
1793    BKNI_ASSERT_ISR_CONTEXT();
1794
1795    BKNI_Memset(pBuffers, 0, sizeof(*pBuffers));
1796
1797    if ( handle->settings.interleaveData )
1798    {
1799        pBuffers->numBuffers = handle->numChannelPairs;
1800        pBuffers->interleaved = true;
1801    }
1802    else
1803    {
1804        pBuffers->numBuffers = 2*handle->numChannelPairs;
1805        pBuffers->interleaved = false;
1806    }
1807    fifoSize = handle->settings.bufferInfo[0].length;
1808    if ( !handle->started )
1809    {
1810        return BERR_SUCCESS;
1811    }
1812
1813    for ( i = 0; i < handle->numChannelPairs; i++ )
1814    {
1815        /* Read registers */
1816        rd = BREG_Read32_isr(handle->deviceHandle->regHandle, BAPE_P_DFIFO_TO_RDADDR_REG(handle->dfifoIds[i]));
1817        wr = BREG_Read32_isr(handle->deviceHandle->regHandle, BAPE_P_DFIFO_TO_WRADDR_REG(handle->dfifoIds[i]));
1818        base = BREG_Read32_isr(handle->deviceHandle->regHandle, BAPE_P_DFIFO_TO_BASEADDR_REG(handle->dfifoIds[i]));
1819   
1820        /* Same toggle bit means no wrap.  Opposite toggle bits means wrap. */   
1821#ifdef BCHP_AUD_FMM_BF_CTRL_RINGBUF_0_RDADDR
1822        wrap = BCHP_GET_FIELD_DATA(rd, AUD_FMM_BF_CTRL_RINGBUF_0_RDADDR, RINGBUF_RDADDR_WRAP) ^ 
1823               BCHP_GET_FIELD_DATA(wr, AUD_FMM_BF_CTRL_RINGBUF_0_WRADDR, RINGBUF_WRADDR_WRAP);
1824
1825        /* Mask off toggle bits */
1826        rd = BCHP_GET_FIELD_DATA(rd, AUD_FMM_BF_CTRL_RINGBUF_0_RDADDR, RINGBUF_RDADDR);
1827        wr = BCHP_GET_FIELD_DATA(wr, AUD_FMM_BF_CTRL_RINGBUF_0_WRADDR, RINGBUF_WRADDR);
1828#else
1829        wrap = BCHP_GET_FIELD_DATA(rd, AUD_FMM_BF_CTRL_SOURCECH_RINGBUF_0_RDADDR, RINGBUF_RDADDR_WRAP) ^ 
1830               BCHP_GET_FIELD_DATA(wr, AUD_FMM_BF_CTRL_SOURCECH_RINGBUF_0_WRADDR, RINGBUF_WRADDR_WRAP);
1831
1832        /* Mask off toggle bits */
1833        rd = BCHP_GET_FIELD_DATA(rd, AUD_FMM_BF_CTRL_SOURCECH_RINGBUF_0_RDADDR, RINGBUF_RDADDR);
1834        wr = BCHP_GET_FIELD_DATA(wr, AUD_FMM_BF_CTRL_SOURCECH_RINGBUF_0_WRADDR, RINGBUF_WRADDR);
1835#endif
1836   
1837        /* Get base address to read from */
1838        errCode = BMEM_Heap_ConvertOffsetToAddress(handle->deviceHandle->memHandle, rd, &pBuffers->buffers[2*i].pBuffer);
1839        if ( errCode )
1840        {
1841            return BERR_TRACE(errCode);
1842        }
1843   
1844        /* Compute size of contiguous space */
1845        if ( wrap )
1846        {
1847            bufferSize = fifoSize - (rd-base);
1848        }
1849        else
1850        {
1851            bufferSize = (wr - rd);
1852        }
1853       
1854        if ( bufferSize < minBufferSize )
1855        {
1856            minBufferSize = bufferSize;
1857        }
1858
1859        if ( handle->settings.interleaveData == false )
1860        {
1861            /* Read registers */
1862            rd = BREG_Read32_isr(handle->deviceHandle->regHandle, BAPE_P_DFIFO_TO_RDADDR_REG(handle->dfifoIds[i])+BAPE_P_RINGBUFFER_STRIDE);
1863            wr = BREG_Read32_isr(handle->deviceHandle->regHandle, BAPE_P_DFIFO_TO_WRADDR_REG(handle->dfifoIds[i])+BAPE_P_RINGBUFFER_STRIDE);
1864            base = BREG_Read32_isr(handle->deviceHandle->regHandle, BAPE_P_DFIFO_TO_BASEADDR_REG(handle->dfifoIds[i])+BAPE_P_RINGBUFFER_STRIDE);
1865   
1866#ifdef BCHP_AUD_FMM_BF_CTRL_RINGBUF_0_RDADDR
1867            /* Same toggle bit means no wrap.  Opposite toggle bits means wrap. */   
1868            wrap = BCHP_GET_FIELD_DATA(rd, AUD_FMM_BF_CTRL_RINGBUF_0_RDADDR, RINGBUF_RDADDR_WRAP) ^ 
1869                   BCHP_GET_FIELD_DATA(wr, AUD_FMM_BF_CTRL_RINGBUF_0_WRADDR, RINGBUF_WRADDR_WRAP);
1870   
1871            /* Mask off toggle bits */
1872            rd = BCHP_GET_FIELD_DATA(rd, AUD_FMM_BF_CTRL_RINGBUF_0_RDADDR, RINGBUF_RDADDR);
1873            wr = BCHP_GET_FIELD_DATA(wr, AUD_FMM_BF_CTRL_RINGBUF_0_WRADDR, RINGBUF_WRADDR);
1874#else
1875            /* Same toggle bit means no wrap.  Opposite toggle bits means wrap. */   
1876            wrap = BCHP_GET_FIELD_DATA(rd, AUD_FMM_BF_CTRL_SOURCECH_RINGBUF_0_RDADDR, RINGBUF_RDADDR_WRAP) ^ 
1877                   BCHP_GET_FIELD_DATA(wr, AUD_FMM_BF_CTRL_SOURCECH_RINGBUF_0_WRADDR, RINGBUF_WRADDR_WRAP);
1878
1879            /* Mask off toggle bits */
1880            rd = BCHP_GET_FIELD_DATA(rd, AUD_FMM_BF_CTRL_SOURCECH_RINGBUF_0_RDADDR, RINGBUF_RDADDR);
1881            wr = BCHP_GET_FIELD_DATA(wr, AUD_FMM_BF_CTRL_SOURCECH_RINGBUF_0_WRADDR, RINGBUF_WRADDR);
1882#endif
1883   
1884            /* Get base address to read from */
1885            errCode = BMEM_Heap_ConvertOffsetToAddress(handle->deviceHandle->memHandle, rd, &pBuffers->buffers[(2*i)+1].pBuffer);
1886            if ( errCode )
1887            {
1888                return BERR_TRACE(errCode);
1889            }
1890   
1891            /* Compute size of contiguous space */
1892            if ( wrap )
1893            {
1894                bufferSize = fifoSize - (rd-base);
1895            }
1896            else
1897            {
1898                bufferSize = (wr - rd);
1899            }
1900   
1901            if ( bufferSize < minBufferSize )
1902            {
1903                minBufferSize = bufferSize;
1904            }
1905        }
1906    }
1907   
1908    pBuffers->bufferSize = minBufferSize;
1909
1910    return BERR_SUCCESS;
1911}
1912
1913BERR_Code BAPE_DfifoGroup_P_CommitData_isr(
1914    BAPE_DfifoGroupHandle handle,
1915    unsigned numBytes                   /* Number of bytes written into the buffer */
1916    )
1917{
1918    uint32_t rd, wr, base, wrap, rdaddr, wraddr, wrapBit;
1919    unsigned fifoSize, i;
1920    uint32_t rdaddrRegs[BAPE_Channel_eMax];
1921
1922    BDBG_ASSERT(NULL != handle);
1923    BDBG_ASSERT(handle->allocated);
1924    BKNI_ASSERT_ISR_CONTEXT();
1925
1926    if ( !handle->started )
1927    {
1928        return BERR_SUCCESS;
1929    }
1930
1931    fifoSize = handle->settings.bufferInfo[0].length;
1932    for ( i = 0; i < handle->numChannelPairs; i++ )
1933    {
1934        /* Read registers */
1935        rd = BREG_Read32_isr(handle->deviceHandle->regHandle, BAPE_P_DFIFO_TO_RDADDR_REG(handle->dfifoIds[i]));
1936        wr = BREG_Read32_isr(handle->deviceHandle->regHandle, BAPE_P_DFIFO_TO_WRADDR_REG(handle->dfifoIds[i]));
1937        base = BREG_Read32_isr(handle->deviceHandle->regHandle, BAPE_P_DFIFO_TO_BASEADDR_REG(handle->dfifoIds[i]));
1938   
1939#ifdef BCHP_AUD_FMM_BF_CTRL_RINGBUF_0_RDADDR
1940        /* Same toggle bit means no wrap.  Opposite toggle bits means wrap. */   
1941        wrap = BCHP_GET_FIELD_DATA(rd, AUD_FMM_BF_CTRL_RINGBUF_0_RDADDR, RINGBUF_RDADDR_WRAP) ^ 
1942               BCHP_GET_FIELD_DATA(wr, AUD_FMM_BF_CTRL_RINGBUF_0_WRADDR, RINGBUF_WRADDR_WRAP);
1943   
1944        /* Mask off toggle bits */
1945        rdaddr = BCHP_GET_FIELD_DATA(rd, AUD_FMM_BF_CTRL_RINGBUF_0_RDADDR, RINGBUF_RDADDR);
1946        wraddr = BCHP_GET_FIELD_DATA(wr, AUD_FMM_BF_CTRL_RINGBUF_0_WRADDR, RINGBUF_WRADDR);
1947#else
1948        /* Same toggle bit means no wrap.  Opposite toggle bits means wrap. */   
1949        wrap = BCHP_GET_FIELD_DATA(rd, AUD_FMM_BF_CTRL_SOURCECH_RINGBUF_0_RDADDR, RINGBUF_RDADDR_WRAP) ^ 
1950               BCHP_GET_FIELD_DATA(wr, AUD_FMM_BF_CTRL_SOURCECH_RINGBUF_0_WRADDR, RINGBUF_WRADDR_WRAP);
1951
1952        /* Mask off toggle bits */
1953        rdaddr = BCHP_GET_FIELD_DATA(rd, AUD_FMM_BF_CTRL_SOURCECH_RINGBUF_0_RDADDR, RINGBUF_RDADDR);
1954        wraddr = BCHP_GET_FIELD_DATA(wr, AUD_FMM_BF_CTRL_SOURCECH_RINGBUF_0_WRADDR, RINGBUF_WRADDR);
1955#endif
1956   
1957        /* Check for potential overflow */
1958        if ( wrap )
1959        {
1960            if ( ((rdaddr-base)+numBytes) > fifoSize )
1961            {
1962                BKNI_LeaveCriticalSection();
1963                BDBG_ERR(("Invalid number of bytes provided to BAPE_OutputCapture_ConsumeData [wrap]"));
1964                BDBG_ERR(("rd %#x wr %#x base %#x size %#x numBytes %#x", rd, wr, base, fifoSize, numBytes));
1965                return BERR_TRACE(BERR_INVALID_PARAMETER);
1966            }
1967        }
1968        else
1969        {
1970            if ( (rdaddr+numBytes) > wraddr )
1971            {
1972                BKNI_LeaveCriticalSection();
1973                BDBG_ERR(("Invalid number of bytes provided to BAPE_OutputCapture_ConsumeData [no wrap]"));
1974                BDBG_ERR(("rd %#x wr %#x base %#x size %#x numBytes %#x", rd, wr, base, fifoSize, numBytes));
1975                return BERR_TRACE(BERR_INVALID_PARAMETER);
1976            }
1977        }
1978   
1979        /* Update read pointer */
1980        rdaddr += numBytes;
1981#ifdef BCHP_AUD_FMM_BF_CTRL_RINGBUF_0_RDADDR
1982        wrapBit = rd & BCHP_MASK(AUD_FMM_BF_CTRL_RINGBUF_0_RDADDR, RINGBUF_RDADDR_WRAP);
1983        if ( (rdaddr-base) >= fifoSize )
1984        {
1985            wrapBit ^= BCHP_MASK(AUD_FMM_BF_CTRL_RINGBUF_0_RDADDR, RINGBUF_RDADDR_WRAP);
1986            rdaddr = base;
1987        }
1988#else
1989        wrapBit = rd & BCHP_MASK(AUD_FMM_BF_CTRL_SOURCECH_RINGBUF_0_RDADDR, RINGBUF_RDADDR_WRAP);
1990        if ( (rdaddr-base) >= fifoSize )
1991        {
1992            wrapBit ^= BCHP_MASK(AUD_FMM_BF_CTRL_SOURCECH_RINGBUF_0_RDADDR, RINGBUF_RDADDR_WRAP);
1993            rdaddr = base;
1994        }
1995#endif
1996        rdaddr |= wrapBit;
1997        rdaddrRegs[2*i] = rdaddr;
1998       
1999        if ( handle->settings.interleaveData == false )
2000        {
2001            /* Read registers */
2002            rd = BREG_Read32_isr(handle->deviceHandle->regHandle, BAPE_P_DFIFO_TO_RDADDR_REG(handle->dfifoIds[i])+BAPE_P_RINGBUFFER_STRIDE);
2003            wr = BREG_Read32_isr(handle->deviceHandle->regHandle, BAPE_P_DFIFO_TO_WRADDR_REG(handle->dfifoIds[i])+BAPE_P_RINGBUFFER_STRIDE);
2004            base = BREG_Read32_isr(handle->deviceHandle->regHandle, BAPE_P_DFIFO_TO_BASEADDR_REG(handle->dfifoIds[i])+BAPE_P_RINGBUFFER_STRIDE);
2005
2006#ifdef BCHP_AUD_FMM_BF_CTRL_RINGBUF_0_RDADDR
2007            /* Same toggle bit means no wrap.  Opposite toggle bits means wrap. */   
2008            wrap = BCHP_GET_FIELD_DATA(rd, AUD_FMM_BF_CTRL_RINGBUF_0_RDADDR, RINGBUF_RDADDR_WRAP) ^ 
2009                   BCHP_GET_FIELD_DATA(wr, AUD_FMM_BF_CTRL_RINGBUF_0_WRADDR, RINGBUF_WRADDR_WRAP);
2010
2011            /* Mask off toggle bits */
2012            rdaddr = BCHP_GET_FIELD_DATA(rd, AUD_FMM_BF_CTRL_RINGBUF_0_RDADDR, RINGBUF_RDADDR);
2013            wraddr = BCHP_GET_FIELD_DATA(wr, AUD_FMM_BF_CTRL_RINGBUF_0_WRADDR, RINGBUF_WRADDR);
2014#else
2015            /* Same toggle bit means no wrap.  Opposite toggle bits means wrap. */   
2016            wrap = BCHP_GET_FIELD_DATA(rd, AUD_FMM_BF_CTRL_SOURCECH_RINGBUF_0_RDADDR, RINGBUF_RDADDR_WRAP) ^ 
2017                   BCHP_GET_FIELD_DATA(wr, AUD_FMM_BF_CTRL_SOURCECH_RINGBUF_0_WRADDR, RINGBUF_WRADDR_WRAP);
2018
2019            /* Mask off toggle bits */
2020            rdaddr = BCHP_GET_FIELD_DATA(rd, AUD_FMM_BF_CTRL_SOURCECH_RINGBUF_0_RDADDR, RINGBUF_RDADDR);
2021            wraddr = BCHP_GET_FIELD_DATA(wr, AUD_FMM_BF_CTRL_SOURCECH_RINGBUF_0_WRADDR, RINGBUF_WRADDR);           
2022#endif
2023
2024            /* Check for potential overflow */
2025            if ( wrap )
2026            {
2027                if ( ((rdaddr-base)+numBytes) > fifoSize )
2028                {
2029                    BKNI_LeaveCriticalSection();
2030                    BDBG_ERR(("Invalid number of bytes provided to BAPE_OutputCapture_ConsumeData [wrap]"));
2031                    BDBG_ERR(("rd %#x wr %#x base %#x size %#x numBytes %#x", rd, wr, base, fifoSize, numBytes));
2032                    return BERR_TRACE(BERR_INVALID_PARAMETER);
2033                }
2034            }
2035            else
2036            {
2037                if ( (rdaddr+numBytes) > wraddr )
2038                {
2039                    BKNI_LeaveCriticalSection();
2040                    BDBG_ERR(("Invalid number of bytes provided to BAPE_OutputCapture_ConsumeData [no wrap]"));
2041                    BDBG_ERR(("rd %#x wr %#x base %#x size %#x numBytes %#x", rd, wr, base, fifoSize, numBytes));
2042                    return BERR_TRACE(BERR_INVALID_PARAMETER);
2043                }
2044            }
2045
2046            /* Update read pointer */
2047            rdaddr += numBytes;
2048#ifdef BCHP_AUD_FMM_BF_CTRL_RINGBUF_0_RDADDR
2049            wrapBit = rd & BCHP_MASK(AUD_FMM_BF_CTRL_RINGBUF_0_RDADDR, RINGBUF_RDADDR_WRAP);
2050            if ( (rdaddr-base) >= fifoSize )
2051            {
2052                wrapBit ^= BCHP_MASK(AUD_FMM_BF_CTRL_RINGBUF_0_RDADDR, RINGBUF_RDADDR_WRAP);
2053                rdaddr = base;
2054            }
2055#else
2056            wrapBit = rd & BCHP_MASK(AUD_FMM_BF_CTRL_SOURCECH_RINGBUF_0_RDADDR, RINGBUF_RDADDR_WRAP);
2057            if ( (rdaddr-base) >= fifoSize )
2058            {
2059                wrapBit ^= BCHP_MASK(AUD_FMM_BF_CTRL_SOURCECH_RINGBUF_0_RDADDR, RINGBUF_RDADDR_WRAP);
2060                rdaddr = base;
2061            }
2062#endif
2063            rdaddr |= wrapBit;
2064            rdaddrRegs[(2*i)+1] = rdaddr;
2065        }
2066    }
2067
2068    /* Move the actual read pointer after validation */
2069    for ( i = 0; i < handle->numChannelPairs; i++ )
2070    {
2071        BREG_Write32_isr(handle->deviceHandle->regHandle, BAPE_P_DFIFO_TO_RDADDR_REG(handle->dfifoIds[i]), rdaddrRegs[2*i]);
2072        if ( false == handle->settings.interleaveData )
2073        {
2074            BREG_Write32_isr(handle->deviceHandle->regHandle, BAPE_P_DFIFO_TO_RDADDR_REG(handle->dfifoIds[i])+BAPE_P_RINGBUFFER_STRIDE, rdaddrRegs[(2*i)+1]);
2075        }
2076    }
2077
2078    return BERR_SUCCESS;
2079}
2080
2081BERR_Code BAPE_DfifoGroup_P_Flush_isr(
2082    BAPE_DfifoGroupHandle handle
2083    )
2084{
2085    uint32_t regAddr, regVal, offset, wrap;
2086    unsigned i;
2087
2088    /* To flush, first compute where the read address should be in terms
2089       of offset from base.  Then apply to all buffers. */
2090    regAddr = BAPE_P_DFIFO_TO_WRADDR_REG(handle->dfifoIds[0]);
2091    regVal = BREG_Read32_isr(handle->deviceHandle->regHandle, regAddr);
2092#ifdef BCHP_AUD_FMM_BF_CTRL_RINGBUF_0_RDADDR
2093    wrap = regVal & BCHP_MASK(AUD_FMM_BF_CTRL_RINGBUF_0_RDADDR, RINGBUF_RDADDR_WRAP);
2094    offset = (regVal & BCHP_MASK(AUD_FMM_BF_CTRL_RINGBUF_0_RDADDR, RINGBUF_RDADDR)) - handle->settings.bufferInfo[0].base;   
2095#else
2096    wrap = regVal & BCHP_MASK(AUD_FMM_BF_CTRL_SOURCECH_RINGBUF_0_RDADDR, RINGBUF_RDADDR_WRAP);
2097    offset = (regVal & BCHP_MASK(AUD_FMM_BF_CTRL_SOURCECH_RINGBUF_0_RDADDR, RINGBUF_RDADDR)) - handle->settings.bufferInfo[0].base;   
2098#endif
2099    for ( i = 0; i < handle->numChannelPairs; i++ )
2100    {
2101        regAddr = BAPE_P_DFIFO_TO_RDADDR_REG(handle->dfifoIds[i]);
2102        regVal = wrap | (offset+handle->settings.bufferInfo[2*i].base);
2103        BREG_Write32_isr(handle->deviceHandle->regHandle, regAddr, regVal);
2104        if ( handle->settings.interleaveData )
2105        {
2106            regAddr += BAPE_P_RINGBUFFER_STRIDE;
2107            regVal = wrap | (offset+handle->settings.bufferInfo[(2*i)+1].base);
2108            BREG_Write32_isr(handle->deviceHandle->regHandle, regAddr, regVal);
2109        }
2110    }
2111
2112    return BERR_SUCCESS;
2113}
2114
2115BERR_Code BAPE_DfifoGroup_P_SetFullmarkInterrupt(
2116    BAPE_DfifoGroupHandle handle,
2117    BINT_CallbackFunc callback_isr,
2118    void *pParam1,
2119    int param2
2120    )
2121{
2122    return BAPE_P_SetDfifoFullmarkInterrupt(handle->deviceHandle,
2123                                            handle->dfifoIds[0],
2124                                            callback_isr,
2125                                            pParam1,
2126                                            param2);
2127}
2128
2129void BAPE_DfifoGroup_P_RearmFullmarkInterrupt_isr(
2130    BAPE_DfifoGroupHandle handle
2131    )
2132{
2133    uint32_t regVal;
2134
2135    BDBG_ASSERT(NULL != handle);
2136    BDBG_ASSERT(handle->allocated);
2137    BKNI_ASSERT_ISR_CONTEXT();
2138
2139#ifdef BCHP_AUD_FMM_BF_CTRL_REARM_FREEFULL_MARK
2140    /* Clear the ESR status */
2141    regVal = BCHP_FIELD_DATA(AUD_FMM_BF_ESR2_H_STATUS_CLEAR, DEST_RINGBUF_0_EXCEED_FULLMARK, 1) << handle->dfifoIds[0];
2142    BREG_Write32_isr(handle->deviceHandle->regHandle, BCHP_AUD_FMM_BF_ESR2_H_STATUS_CLEAR, regVal);       
2143    /* Rearm */
2144    regVal = (1<<BCHP_SHIFT(AUD_FMM_BF_CTRL_REARM_FREEFULL_MARK, REARM_FULLMARK))<<handle->dfifoIds[0];
2145    BREG_Write32_isr(handle->deviceHandle->regHandle, BCHP_AUD_FMM_BF_CTRL_REARM_FREEFULL_MARK, regVal);
2146#else
2147    /* Clear the ESR status */
2148    regVal = BCHP_FIELD_DATA(AUD_FMM_BF_ESR_ESR4_STATUS_CLEAR, DEST_RINGBUF_0_EXCEED_FULLMARK, 1) << handle->dfifoIds[0];
2149    BREG_Write32_isr(handle->deviceHandle->regHandle, BCHP_AUD_FMM_BF_ESR_ESR4_STATUS_CLEAR, regVal);       
2150    /* Rearm */
2151    regVal = (1<<BCHP_SHIFT(AUD_FMM_BF_CTRL_REARM_FULL_MARK, REARM_FULLMARK))<<handle->dfifoIds[0];
2152    BREG_Write32_isr(handle->deviceHandle->regHandle, BCHP_AUD_FMM_BF_CTRL_REARM_FULL_MARK, regVal);
2153#endif
2154}
2155
2156BERR_Code BAPE_DfifoGroup_P_SetOverflowInterrupt(
2157    BAPE_DfifoGroupHandle handle,
2158    BINT_CallbackFunc callback_isr,
2159    void *pParam1,
2160    int param2
2161    )
2162{
2163    return BAPE_P_SetDfifoOverflowInterrupt(handle->deviceHandle,
2164                                            handle->dfifoIds[0],
2165                                            callback_isr,
2166                                            pParam1,
2167                                            param2);
2168}
2169
2170void BAPE_DfifoGroup_P_RearmOverflowInterrupt_isr(
2171    BAPE_DfifoGroupHandle handle
2172    )
2173{
2174    uint32_t regVal;
2175
2176    BDBG_ASSERT(NULL != handle);
2177    BDBG_ASSERT(handle->allocated);
2178    BKNI_ASSERT_ISR_CONTEXT();
2179
2180#ifdef BCHP_AUD_FMM_BF_ESR1_H_STATUS_CLEAR
2181    /* Clear the ESR status */
2182    regVal = BCHP_FIELD_DATA(AUD_FMM_BF_ESR1_H_STATUS_CLEAR, DEST_RINGBUF_0_OVERFLOW, 1) << handle->dfifoIds[0];
2183    BREG_Write32_isr(handle->deviceHandle->regHandle, BCHP_AUD_FMM_BF_ESR1_H_STATUS_CLEAR, regVal);
2184#else
2185    /* Clear the ESR status */
2186    regVal = BCHP_FIELD_DATA(AUD_FMM_BF_ESR_ESR2_STATUS_CLEAR, DEST_RINGBUF_0_OVERFLOW, 1) << handle->dfifoIds[0];
2187    BREG_Write32_isr(handle->deviceHandle->regHandle, BCHP_AUD_FMM_BF_ESR_ESR2_STATUS_CLEAR, regVal);
2188#endif
2189}
2190
2191uint32_t BAPE_DfifoGroup_P_GetHwIndex(
2192    BAPE_DfifoGroupHandle handle,
2193    BAPE_ChannelPair channelPair
2194    )
2195{
2196    BDBG_ASSERT(NULL != handle);
2197    BDBG_ASSERT(handle->allocated);
2198
2199    if ( channelPair >= handle->numChannelPairs )
2200    {
2201        return 0xFFFFFFFF;
2202    }
2203    else
2204    {
2205        return handle->dfifoIds[channelPair];
2206    }
2207}
2208
2209
2210BERR_Code BAPE_P_InitBfSw(
2211    BAPE_Handle handle
2212    )
2213{
2214    unsigned i;
2215
2216    BDBG_OBJECT_ASSERT(handle, BAPE_Device);
2217
2218    BDBG_MSG(("Allocating %u SFIFO Groups", BAPE_CHIP_MAX_SFIFO_GROUPS));
2219    handle->sfifoGroups[0] = BKNI_Malloc(BAPE_CHIP_MAX_SFIFO_GROUPS*sizeof(BAPE_SfifoGroup));
2220    if ( NULL == handle->sfifoGroups[0] )
2221    {
2222        BAPE_P_UninitBfSw(handle);
2223        return BERR_TRACE(BERR_OUT_OF_SYSTEM_MEMORY);
2224    }
2225    BKNI_Memset(handle->sfifoGroups[0], 0, BAPE_CHIP_MAX_SFIFO_GROUPS*sizeof(BAPE_SfifoGroup));
2226    for ( i = 1; i < BAPE_CHIP_MAX_SFIFO_GROUPS; i++ )
2227    {
2228        handle->sfifoGroups[i] = handle->sfifoGroups[0] + i;
2229    }
2230    BDBG_MSG(("Allocating %u DFIFO Groups", BAPE_CHIP_MAX_DFIFO_GROUPS));
2231    handle->dfifoGroups[0] = BKNI_Malloc(BAPE_CHIP_MAX_DFIFO_GROUPS*sizeof(BAPE_DfifoGroup));
2232    BKNI_Memset(handle->dfifoGroups[0], 0, BAPE_CHIP_MAX_DFIFO_GROUPS*sizeof(BAPE_DfifoGroup));
2233    if ( NULL == handle->dfifoGroups[0] )
2234    {
2235        BAPE_P_UninitBfSw(handle);
2236        return BERR_TRACE(BERR_OUT_OF_SYSTEM_MEMORY);
2237    }
2238    for ( i = 1; i < BAPE_CHIP_MAX_DFIFO_GROUPS; i++ )
2239    {
2240        handle->dfifoGroups[i] = handle->dfifoGroups[0] + i;
2241    }
2242
2243    return BERR_SUCCESS;
2244}
2245
2246BERR_Code BAPE_P_InitBfHw(
2247    BAPE_Handle handle
2248    )
2249{
2250    uint32_t regAddr, endAddr, regVal;
2251    BREG_Handle regHandle;
2252    unsigned i;
2253
2254    BDBG_OBJECT_ASSERT(handle, BAPE_Device);
2255
2256    regHandle = handle->regHandle;
2257
2258    BDBG_MSG(("Initializing BF registers"));
2259
2260#ifdef BCHP_AUD_FMM_BF_CTRL_RINGBUF_0_RDADDR
2261    /* Clear Ringbuffer registers */
2262    regAddr = BCHP_AUD_FMM_BF_CTRL_RINGBUF_0_RDADDR;
2263    endAddr = regAddr + ((BCHP_AUD_FMM_BF_CTRL_RINGBUF_2_RDADDR - BCHP_AUD_FMM_BF_CTRL_RINGBUF_0_RDADDR) * (BAPE_CHIP_MAX_SFIFOS + BAPE_CHIP_MAX_DFIFOS));
2264#ifdef BCHP_AUD_FMM_BF_CTRL_RINGBUF_0_FRMSTADDR
2265    endAddr += ((BCHP_AUD_FMM_BF_CTRL_RINGBUF_2_FRMSTADDR-BCHP_AUD_FMM_BF_CTRL_RINGBUF_0_FRMSTADDR) * (BAPE_CHIP_MAX_SFIFOS + BAPE_CHIP_MAX_DFIFOS));
2266#endif
2267    BDBG_MSG(("Clearing ringbuffer registers from 0x%x to 0x%x", regAddr, endAddr-4));
2268    while ( regAddr < endAddr )
2269    {
2270        BREG_Write32(regHandle, regAddr, 0);
2271        regAddr += 4;
2272    }
2273#else
2274    /* Clear Ringbuffer registers */
2275    regAddr = BCHP_AUD_FMM_BF_CTRL_SOURCECH_RINGBUF_0_RDADDR;
2276    endAddr = regAddr + (BAPE_P_RINGBUFFER_STRIDE * 2 * (BAPE_CHIP_MAX_SFIFOS + BAPE_CHIP_MAX_DFIFOS));
2277    BDBG_MSG(("Clearing ringbuffer registers from 0x%x to 0x%x", regAddr, endAddr-4));
2278    while ( regAddr < endAddr )
2279    {
2280        BREG_Write32(regHandle, regAddr, 0);
2281        regAddr += 4;
2282    }   
2283#ifdef BCHP_AUD_FMM_BF_CTRL_SOURCECH_RINGBUF_0_FRMSTADDR
2284    regAddr = BCHP_AUD_FMM_BF_CTRL_SOURCECH_RINGBUF_0_FRMSTADDR;
2285    endAddr = regAddr + (8*2*(BAPE_CHIP_MAX_SFIFOS + BAPE_CHIP_MAX_DFIFOS));
2286    while ( regAddr < endAddr )
2287    {
2288        BREG_Write32(regHandle, regAddr, 0);
2289        regAddr += 4;
2290    }   
2291#endif
2292#endif
2293    BDBG_MSG(("Resetting source channel group IDs to default"));
2294    regAddr = BCHP_AUD_FMM_BF_CTRL_SOURCECH_GRPi_ARRAY_BASE;
2295    for ( i = BCHP_AUD_FMM_BF_CTRL_SOURCECH_GRPi_ARRAY_START; i <= BCHP_AUD_FMM_BF_CTRL_SOURCECH_CFGi_ARRAY_END; i++ )
2296    {
2297        regVal = BREG_Read32(regHandle, regAddr);
2298        regVal &= ~BCHP_MASK(AUD_FMM_BF_CTRL_SOURCECH_GRPi, GROUP_ID);
2299        regVal |= BCHP_FIELD_DATA(AUD_FMM_BF_CTRL_SOURCECH_GRPi, GROUP_ID, i);
2300        BREG_Write32(regHandle, regAddr, regVal);
2301        regAddr += (BCHP_AUD_FMM_BF_CTRL_SOURCECH_CFGi_ARRAY_ELEMENT_SIZE/8);
2302    }
2303
2304    return BERR_SUCCESS;
2305}
2306
2307
2308void BAPE_P_UninitBfSw(
2309    BAPE_Handle handle
2310    )
2311{
2312    BDBG_OBJECT_ASSERT(handle, BAPE_Device);
2313
2314    if ( NULL != handle->sfifoGroups[0] )
2315    {
2316        BKNI_Free(handle->sfifoGroups[0]);
2317    }
2318    BKNI_Memset(handle->sfifoGroups, 0, sizeof(handle->sfifoGroups));
2319    if ( NULL != handle->dfifoGroups[0] )
2320    {
2321        BKNI_Free(handle->dfifoGroups[0]);
2322    }
2323    BKNI_Memset(handle->dfifoGroups, 0, sizeof(handle->dfifoGroups));
2324}
2325
Note: See TracBrowser for help on using the repository browser.