source: svn/trunk/newcon3bcm2_21bu/magnum/portinginterface/ape/7552/bape_dac.c

Last change on this file was 2, checked in by jglee, 11 years ago

first commit

  • Property svn:executable set to *
File size: 57.6 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_dac.c $
11 * $brcm_Revision: Hydra_Software_Devel/30 $
12 * $brcm_Date: 3/6/12 2:57p $
13 *
14 * Module Description: Audio DAC Interface
15 *
16 * Revision History:
17 *
18 * $brcm_Log: /magnum/portinginterface/ape/7422/bape_dac.c $
19 *
20 * Hydra_Software_Devel/30   3/6/12 2:57p gskerl
21 * SW7425-2570: Renamed OutputPortObject substruct from connector to
22 * outputPort.
23 *
24 * Hydra_Software_Devel/29   2/23/12 10:53a jgarrett
25 * SW7405-5003: Removing BKNI_Memcmp where structures aren't copied with
26 * BKNI_Memcpy
27 *
28 * Hydra_Software_Devel/28   2/8/12 1:48p gskerl
29 * SW7425-2339: Moved DAC dynamic power management from enable/disable to
30 * open/close (because it causes a small pop that's noticeable when the
31 * receiver is at 100% volume)
32 *
33 * Hydra_Software_Devel/27   1/27/12 5:11p jgarrett
34 * SW7429-55: Changing ncoRequired to builtinNco
35 *
36 * Hydra_Software_Devel/26   1/27/12 4:52p jgarrett
37 * SW7429-55: Setting ncoRequired field for 7429 to indicate only NCO
38 * outputs may share a mixer with DACs
39 *
40 * Hydra_Software_Devel/25   11/30/11 6:36p jgarrett
41 * SW7429-18: Fixing DAC powerup and init on 7429
42 *
43 * Hydra_Software_Devel/24   11/16/11 3:11p gskerl
44 * SW7429-18: Corrected accessing of TESTTONE_SAMPLE register array.
45 *
46 * Hydra_Software_Devel/23   11/14/11 3:31p gskerl
47 * SW7429-18: Merging 7429 changes back to main branch.
48 *
49 * Hydra_Software_Devel/SW7429-18/3   10/25/11 5:41p jgarrett
50 * SW7429-18: Removing DAC MCLK output for 7429
51 *
52 * Hydra_Software_Devel/SW7429-18/2   10/25/11 10:42a jgarrett
53 * SW7429-18: Removing RM warning for 7429
54 *
55 * Hydra_Software_Devel/SW7429-18/1   10/21/11 6:29p jgarrett
56 * SW7429-18: Initial compileable version for 7429
57 *
58 * Hydra_Software_Devel/22   9/30/11 11:30a gskerl
59 * SW7231-129: Updated comments.
60 *
61 * Hydra_Software_Devel/21   9/28/11 5:36p gskerl
62 * SW7231-129: Renamed BAPE_Dac_ApplySettings() to
63 * BAPE_Dac_P_ApplySettings()
64 *
65 * Hydra_Software_Devel/20   9/19/11 5:28p gskerl
66 * SW7231-129: Added support for recovering hardware state after power
67 * standby/resume.
68 *
69 * Hydra_Software_Devel/19   9/16/11 6:49p gskerl
70 * SW7231-129: Refactored to put hardware and software initialization into
71 * separate functions.
72 *
73 * Hydra_Software_Devel/18   8/24/11 11:53a jgarrett
74 * SW7425-724: Adding RF Audio Encoder
75 *
76 * Hydra_Software_Devel/17   8/18/11 3:19p jgarrett
77 * SWDTV-8296: Handling IOP/OP mismatches in stream IDs for DTV chips
78 *
79 * Hydra_Software_Devel/16   8/16/11 2:44p gskerl
80 * SW7231-246: Re-enabled and fixed DAC dynamic power management
81 *
82 * Hydra_Software_Devel/15   8/12/11 3:57p gskerl
83 * SW7231-246: Temporarily disabling audio DAC powerdown because when it
84 * is powered down for more than a minute, it takes a really long time
85 * (like 20 seconds) to power back up
86 *
87 * Hydra_Software_Devel/14   6/8/11 6:55p gskerl
88 * SW7425-321: Changed BAPE_Dac_Open() to mute RF Mod output.
89 *
90 * Hydra_Software_Devel/13   5/20/11 7:24p gskerl
91 * SW7231-128: Added DAC power control
92 *
93 * Hydra_Software_Devel/12   5/20/11 5:16p jgarrett
94 * SW7425-402: Adding error code to handle output enable callback failing.
95 *
96 * Hydra_Software_Devel/11   5/3/11 10:45a gskerl
97 * SW7422-354: Added index and type args to APE_P_InitOutputPort macro
98 *
99 * Hydra_Software_Devel/10   4/16/11 12:15p jgarrett
100 * SW7425-371: Removing tab characters
101 *
102 * Hydra_Software_Devel/9   4/6/11 1:23a jgarrett
103 * SW35330-35: Merge to main branch
104 *
105 * Hydra_Software_Devel/SW35330-35/2   4/5/11 7:13p jgarrett
106 * SW35330-35: PCM Playback working on 35230
107 *
108 * Hydra_Software_Devel/SW35330-35/1   4/5/11 12:49p jgarrett
109 * SW35330-35: FMM Abstraction refactoring to support DTV
110 *
111 * Hydra_Software_Devel/8   3/28/11 2:54p gskerl
112 * SW7422-375: Fixed PEAK_GAIN handling
113 *
114 * Hydra_Software_Devel/7   3/25/11 12:43p gskerl
115 * SW7422-375: Removed peakA1 and peakA2 from DAC settings
116 *
117 * Hydra_Software_Devel/6   3/24/11 1:40p gskerl
118 * SW7422-375: Added handling for DAC peaking filter settings
119 *
120 * Hydra_Software_Devel/5   3/22/11 2:56p gskerl
121 * SW7422-146: Changed audio output connector callbacks to take the output
122 * connector as an argument
123 *
124 * Hydra_Software_Devel/4   2/28/11 11:29a gskerl
125 * SW7422-146: Added support for multiple DACs.
126 *
127 * Hydra_Software_Devel/3   2/22/11 5:43p jgarrett
128 * SW7422-146: Implemented type renaming based on filter graph review
129 * comments
130 *
131 * Hydra_Software_Devel/2   1/6/11 5:15p jgarrett
132 * SW7422-146: Adding DAC init register setup
133 *
134 * Hydra_Software_Devel/1   12/16/10 4:04p jgarrett
135 * SW7422-146: Initial compilable APE for 7422
136 *
137 ***************************************************************************/
138
139#include "bstd.h"
140#include "bkni.h"
141#include "bape.h"
142#include "bape_priv.h"
143#ifdef BCHP_HIFIDAC_CTRL0_REG_START
144/* Old-style RDB */
145#include "bchp_hifidac_ctrl0.h"
146#include "bchp_hifidac_rm0.h"
147#include "bchp_aud_fmm_op_ctrl.h"
148
149#if BAPE_CHIP_MAX_DACS > 1
150#include "bchp_hifidac_ctrl1.h"
151#include "bchp_hifidac_rm1.h"
152#if BAPE_CHIP_MAX_DACS > 2
153#include "bchp_hifidac_ctrl2.h"
154#include "bchp_hifidac_rm2.h"
155#endif
156#endif
157
158#else
159/* 7429 and later */
160#include "bchp_hifidac_ctrl_0.h"
161#include "bchp_hifidac_rm_0.h"
162#include "bchp_aud_fmm_iop_out_dac_ctrl_0.h"
163
164#if BAPE_CHIP_MAX_DACS > 1
165#include "bchp_hifidac_ctrl_1.h"
166#include "bchp_hifidac_rm_1.h"
167#include "bchp_aud_fmm_iop_out_dac_ctrl_1.h"
168#if BAPE_CHIP_MAX_DACS > 2
169#include "bchp_hifidac_ctrl_2.h"
170#include "bchp_hifidac_rm_2.h"
171#include "bchp_aud_fmm_iop_out_dac_ctrl_2.h"
172#endif
173#endif
174
175#endif
176
177
178BDBG_MODULE(bape_dac);
179
180BDBG_OBJECT_ID(BAPE_Dac);
181
182typedef struct BAPE_Dac
183{
184    BDBG_OBJECT(BAPE_Dac)
185    BAPE_Handle deviceHandle;
186    BAPE_DacSettings settings;
187    unsigned index;
188    BAPE_OutputPortObject outputPort;
189    unsigned sampleRate;
190    bool compressed;
191    bool enabled;
192    BAVC_Timebase timebase;
193    char name[7];   /* DAC %d */
194} BAPE_Dac;
195
196/* Define some default register values (in case they get used in more than one place) */
197#define  BAPE_DAC_DEFAULT_HIFIDAC_CTRL0_PEAK_GAIN_PEAK_GAIN     0xAA90
198#define  BAPE_DAC_DEFAULT_HIFIDAC_CTRL0_PEAK_A1_PEAK_A1         0x1C402
199#define  BAPE_DAC_DEFAULT_HIFIDAC_CTRL0_PEAK_A2_PEAK_A2         0x32CB4
200#define  BAPE_DAC_DEFAULT_HIFIDAC_CTRL0_RANGE_ASRCOUT           0x02
201#define  BAPE_DAC_DEFAULT_HIFIDAC_CTRL0_DAC_VOLUMECFG_STEPSIZE  0x04
202
203/* The peaking filter must be reprogrammed if the source is RF data */
204#define  BAPE_DAC_RF_HIFIDAC_CTRL0_PEAK_GAIN_PEAK_GAIN        0xe100    /* Taken from brap_hifidac.c */
205#define  BAPE_DAC_RF_HIFIDAC_CTRL0_PEAK_A1_PEAK_A1            0
206#define  BAPE_DAC_RF_HIFIDAC_CTRL0_PEAK_A2_PEAK_A2            0
207#define  BAPE_DAC_RF_HIFIDAC_CTRL0_RANGE_ASRCOUT              0x06
208#define  BAPE_DAC_RF_HIFIDAC_CTRL0_DAC_VOLUMECFG_STEPSIZE     0xfff
209
210/* Static function prototypes */
211static void         BAPE_Dac_P_SetRateManager_isr(BAPE_DacHandle handle, unsigned sampleRate);
212static void         BAPE_Dac_P_SyncVolume(BAPE_DacHandle handle);
213static void         BAPE_Dac_P_PowerDown(BAPE_Handle bapeHandle, unsigned dacIndex);
214static void         BAPE_Dac_P_PowerUp(BAPE_Handle bapeHandle, unsigned dacIndex);
215static BERR_Code    BAPE_Dac_P_OpenHw(BAPE_DacHandle hDac);
216static BERR_Code    BAPE_Dac_P_ApplySettings(BAPE_DacHandle handle, const BAPE_DacSettings *pSettings, bool force);
217
218/* Output port callbacks */
219static void         BAPE_Dac_P_SetTimingParams_isr(BAPE_OutputPort output, unsigned sampleRate, BAVC_Timebase timebase);
220static void         BAPE_Dac_P_SetMute(BAPE_OutputPort output, bool muted, bool sync);
221static BERR_Code    BAPE_Dac_P_Enable(BAPE_OutputPort output);
222static void         BAPE_Dac_P_Disable(BAPE_OutputPort output);
223
224
225#ifdef BCHP_HIFIDAC_CTRL0_REG_START
226#define DAC_MASK(prefix, suffix, field) (BCHP_MASK(prefix##0##suffix, field))
227#define DAC_FIELD_DATA(prefix, suffix, field, val) (BCHP_FIELD_DATA(prefix##0##suffix, field, val))
228#define DAC_FIELD_ENUM(prefix, suffix, field, val) (BCHP_FIELD_ENUM(prefix##0##suffix, field, val))
229#define DAC_GET_FIELD_DATA(val, prefix, suffix, field) (BCHP_GET_FIELD_DATA(val, prefix##0##suffix, field))
230
231#if BAPE_CHIP_MAX_DACS > 1
232    #define  GET_DAC_REG_ADDR2(prefix,idx)         (prefix##0         + (prefix##1         - prefix##0        ) * idx )
233    #define  GET_DAC_REG_ADDR3(prefix,idx,suffix)  (prefix##0##suffix + (prefix##1##suffix - prefix##0##suffix) * idx )
234#ifdef BCHP_AUD_FMM_IOP_CTRL_MIX_IOP_IDMAP98
235    /* 35230 style*/
236    #define  GET_DAC_OP_STREAM_ID(idx) ((idx) == 0 ? 2 :(idx) == 1 ? 8 : (idx) == 2 ? 9 : (BDBG_ASSERT(0), 0))
237    #define  GET_DAC_IOP_STREAM_ID(idx) ((idx) == 0 ? 2 :(idx) == 1 ? 8 : (idx) == 2 ? 13 : (BDBG_ASSERT(0), 0))    /* DTV chips have loopback stuck in the middle of the IOP indexes */
238#else
239    /* 7422/7425 style */
240    #define  GET_DAC_OP_STREAM_ID(idx) ((idx) == 0 ? 2 :(idx) == 1 ? 9 : (BDBG_ASSERT(0), 0))
241    #define  GET_DAC_IOP_STREAM_ID(idx) GET_DAC_OP_STREAM_ID(idx) /* STB chips have this right */
242#endif
243#else
244    #define  GET_DAC_REG_ADDR2(prefix,idx       )  (prefix##0         )
245    #define  GET_DAC_REG_ADDR3(prefix,idx,suffix)  (prefix##0##suffix )
246    #define  GET_DAC_OP_STREAM_ID(idx) (2)         /* DAC 0 seems to always be stream 2. */
247    #define  GET_DAC_IOP_STREAM_ID(idx) GET_DAC_OP_STREAM_ID(idx)
248#endif
249
250#else
251
252#define DAC_MASK(prefix, suffix, field) (BCHP_MASK(prefix##_0##suffix, field))
253#define DAC_FIELD_DATA(prefix, suffix, field, val) (BCHP_FIELD_DATA(prefix##_0##suffix, field, val))
254#define DAC_FIELD_ENUM(prefix, suffix, field, val) (BCHP_FIELD_ENUM(prefix##_0##suffix, field, val))
255#define DAC_GET_FIELD_DATA(val, prefix, suffix, field) (BCHP_GET_FIELD_DATA(val, prefix##_0##suffix, field))
256
257#define GET_DAC_OP_STREAM_ID(idx)  (0xffffffff)
258#define GET_DAC_IOP_STREAM_ID(idx) (0xffffffff)
259
260#if BAPE_CHIP_MAX_DACS > 1
261    #define  GET_DAC_REG_ADDR2(prefix,idx)         (prefix##_0         + (prefix##_1         - prefix##_0        ) * idx )
262    #define  GET_DAC_REG_ADDR3(prefix,idx,suffix)  (prefix##_0##suffix + (prefix##_1##suffix - prefix##_0##suffix) * idx )
263#else
264    #define  GET_DAC_REG_ADDR2(prefix,idx       )  (prefix##_0         )
265    #define  GET_DAC_REG_ADDR3(prefix,idx,suffix)  (prefix##_0##suffix )
266#endif
267#endif
268
269
270/***************************************************************************
271        Public APIs: From bape_output.h
272***************************************************************************/
273
274void BAPE_Dac_GetDefaultSettings(
275    BAPE_DacSettings *pSettings
276    )
277{
278    BDBG_ASSERT(NULL != pSettings);
279    BKNI_Memset(pSettings, 0, sizeof(*pSettings));
280
281    pSettings->stereoMode = BAPE_StereoMode_eLeftRight;
282    pSettings->muteType = BAPE_DacMuteType_eDrive0;
283    pSettings->customLeftValue = 0x3333;
284    pSettings->customRightValue = 0xcccc;
285    pSettings->testTone.sharedSamples = true;
286    pSettings->testTone.sampleRate = 48000;
287
288    pSettings->peakGain = BAPE_DAC_DEFAULT_HIFIDAC_CTRL0_PEAK_GAIN_PEAK_GAIN;
289}
290
291/**************************************************************************/
292
293BERR_Code BAPE_Dac_Open(
294    BAPE_Handle deviceHandle,
295    unsigned index,
296    const BAPE_DacSettings *pSettings,
297    BAPE_DacHandle *pHandle             /* [out] */
298    )
299{
300    BERR_Code errCode;
301    BAPE_DacHandle handle;
302    BAPE_DacSettings defaultSettings;
303
304    BDBG_OBJECT_ASSERT(deviceHandle, BAPE_Device);
305    BDBG_ASSERT(NULL != pHandle);
306   
307    BDBG_MSG(("%s: Opening DAC Output: %u", __FUNCTION__, index));
308
309    *pHandle = NULL;    /* Set up to return null handle in case of error. */
310
311    if ( index >= BAPE_CHIP_MAX_DACS )
312    {
313        BDBG_ERR(("Request to open DAC %d but chip only has %u DACs", index, BAPE_CHIP_MAX_DACS));
314        return BERR_TRACE(BERR_INVALID_PARAMETER);
315    }
316
317    if ( deviceHandle->dacs[index] )
318    {
319        BDBG_ERR(("DAC %d already open", index));
320        return BERR_TRACE(BERR_INVALID_PARAMETER);
321    }
322
323    /* Allocate the device structure, then fill in all the fields. */
324    handle = BKNI_Malloc(sizeof(BAPE_Dac));
325    if ( NULL == handle )
326    {
327        return BERR_TRACE(BERR_OUT_OF_SYSTEM_MEMORY);
328    }
329
330    BKNI_Memset(handle, 0, sizeof(BAPE_Dac));
331    BDBG_OBJECT_SET(handle, BAPE_Dac);
332    handle->deviceHandle = deviceHandle;
333    handle->index = index;
334    BAPE_P_InitOutputPort(&handle->outputPort, BAPE_OutputPortType_eDac, index, handle);
335    handle->outputPort.maxChannelPairs = 1;          /* DAC is stero only */
336    handle->outputPort.compressedSupported = true;   /* For RF audio only */
337    handle->outputPort.builtinNco = true;
338#ifdef BCHP_HIFIDAC_CTRL0_REG_START
339    /* Starting with 7429, DACn is not a valid MCLK source - it is private to the DAC itself */
340    handle->outputPort.mclkOutput = BAPE_MclkSource_eHifidac0 + index;
341#endif
342    handle->outputPort.setTimingParams_isr = BAPE_Dac_P_SetTimingParams_isr;
343    handle->outputPort.setMute = BAPE_Dac_P_SetMute;
344    handle->outputPort.enable = BAPE_Dac_P_Enable;
345    handle->outputPort.disable = BAPE_Dac_P_Disable;
346    BKNI_Snprintf(handle->name, sizeof(handle->name), "DAC %u", index);
347    handle->outputPort.pName = handle->name;
348
349    /* Setup to 48k, muted by default */
350    BKNI_EnterCriticalSection();
351    BAPE_Dac_P_SetTimingParams_isr(&handle->outputPort, 48000, BAVC_Timebase_e0);
352    BKNI_LeaveCriticalSection();
353    BAPE_Dac_P_SetMute(&handle->outputPort, false, false);
354
355    /* Init to specified settings */
356    if ( NULL == pSettings )
357    {
358        BAPE_Dac_GetDefaultSettings(&defaultSettings);
359        pSettings = &defaultSettings;
360    }
361
362    errCode = BAPE_Dac_P_OpenHw(handle);
363    if ( errCode )
364    {
365        BAPE_Dac_Close(handle);
366        return BERR_TRACE(errCode);
367    }
368
369    errCode = BAPE_Dac_SetSettings(handle, pSettings);
370    if ( errCode )
371    {
372        BAPE_Dac_Close(handle);
373        return BERR_TRACE(errCode);
374    }
375
376    *pHandle = handle;
377    handle->deviceHandle->dacs[index] = handle;
378    return BERR_SUCCESS;
379}
380
381/**************************************************************************/
382
383void BAPE_Dac_Close(
384    BAPE_DacHandle handle
385    )
386{
387    BDBG_OBJECT_ASSERT(handle, BAPE_Dac);
388
389    /* Make sure we're not still connected to anything */
390    if ( handle->outputPort.mixer )
391    {
392        BDBG_ERR(("Cannot close dac %p (%d), still connected to mixer %p", handle, handle->index, handle->outputPort.mixer));
393        BDBG_ASSERT(NULL == handle->outputPort.mixer);
394        return;
395    }
396
397    /* Turn off power to the DAC. */
398    BAPE_Dac_P_PowerDown(handle->deviceHandle, handle->index);
399
400    handle->deviceHandle->dacs[handle->index] = NULL;
401    BDBG_OBJECT_DESTROY(handle, BAPE_Dac);
402    BKNI_Free(handle);   
403}
404
405/**************************************************************************/
406
407void BAPE_Dac_GetSettings(
408    BAPE_DacHandle handle,
409    BAPE_DacSettings *pSettings     /* [out] */
410    )
411{
412    BDBG_OBJECT_ASSERT(handle, BAPE_Dac);
413    BDBG_ASSERT(NULL != pSettings);
414    *pSettings = handle->settings;
415}
416
417/**************************************************************************/
418
419BERR_Code BAPE_Dac_SetSettings(
420    BAPE_DacHandle handle,
421    const BAPE_DacSettings *pSettings
422    )
423{
424    BERR_Code   errCode = BERR_SUCCESS;
425
426    BDBG_OBJECT_ASSERT(handle, BAPE_Dac);
427    BDBG_ASSERT(NULL != pSettings);
428
429    errCode = BAPE_Dac_P_ApplySettings(handle, pSettings, false); /* false => don't force (only update HW for changes) */
430    return errCode;
431}
432
433/**************************************************************************/
434
435void BAPE_Dac_GetOutputPort(
436    BAPE_DacHandle handle,
437    BAPE_OutputPort *pOutputPort        /* [out] */
438    )
439{
440    BDBG_OBJECT_ASSERT(handle, BAPE_Dac);
441    BDBG_ASSERT(NULL != pOutputPort);
442    *pOutputPort = &handle->outputPort;
443}
444
445
446/***************************************************************************
447        BAPE Internal APIs: From bape_fmm_priv.h
448***************************************************************************/
449
450BERR_Code BAPE_Dac_P_ResumeFromStandby(BAPE_Handle bapeHandle)
451{
452    BERR_Code   errCode = BERR_SUCCESS;
453    unsigned    dacIndex;
454
455    BDBG_OBJECT_ASSERT(bapeHandle, BAPE_Device);
456
457    /* For each opened DAC, call the functions necessary to restore the hardware to it's appropriate state.
458     * The DACs have already been initialized by BAPE_P_InitDacHw() before this function gets called.
459     */
460    for ( dacIndex=0 ; dacIndex<BAPE_CHIP_MAX_DACS ; dacIndex++ )
461    {
462        if ( bapeHandle->dacs[dacIndex] )       /* If this DAC is open... */
463        {
464            BAPE_DacHandle hDac = bapeHandle->dacs[dacIndex];
465
466            /* Put the HW into the generic open state. */
467            errCode = BAPE_Dac_P_OpenHw(hDac);
468            if ( errCode ) return BERR_TRACE(errCode);
469           
470            /* Now apply changes for the settings struct. */
471            errCode = BAPE_Dac_P_ApplySettings(hDac, &hDac->settings, true);   /* true => force update of HW */
472            if ( errCode ) return BERR_TRACE(errCode);
473
474            /* Now restore the timebase and sampleRate from the values saved in the device struct. */
475            BKNI_EnterCriticalSection();
476                BAPE_Dac_P_SetTimingParams_isr(&hDac->outputPort, hDac->sampleRate, hDac->timebase);
477                BAPE_Dac_P_SetRateManager_isr(hDac, hDac->sampleRate);
478            BKNI_LeaveCriticalSection();
479        }
480    }
481    return errCode;
482}
483
484/**************************************************************************/
485
486BERR_Code BAPE_P_InitDacHw( BAPE_Handle bapeHandle )
487{
488    unsigned   dacIndex;
489
490    BDBG_OBJECT_ASSERT(bapeHandle, BAPE_Device);
491
492    BDBG_MSG(("Initializing DAC registers"));
493
494    for ( dacIndex=0 ; dacIndex<BAPE_CHIP_MAX_DACS ; dacIndex++ )
495    {
496        /* Power down the DAC, it will get powered up at enable time. */
497        BAPE_Dac_P_PowerDown(bapeHandle, dacIndex);
498    }
499
500    return BERR_SUCCESS;
501}
502
503/***************************************************************************
504        Private callbacks: Protyped above
505***************************************************************************/
506
507static void BAPE_Dac_P_SetTimingParams_isr(BAPE_OutputPort output, unsigned sampleRate, BAVC_Timebase timebase)
508{
509    uint32_t regAddr, regVal;
510    BAPE_DacHandle handle;
511
512    BDBG_OBJECT_ASSERT(output, BAPE_OutputPort);
513
514    handle = output->pHandle;
515    BDBG_OBJECT_ASSERT(handle, BAPE_Dac);
516
517    /* Update timebase */
518    regAddr = GET_DAC_REG_ADDR3(BCHP_HIFIDAC_RM, handle->index, _CONTROL );
519    regVal = BREG_Read32_isr(handle->deviceHandle->regHandle, regAddr);
520    regVal &= ~DAC_MASK(HIFIDAC_RM,_CONTROL,TIMEBASE);
521    switch ( timebase )
522    {
523    case BAVC_Timebase_e0:
524        regVal |= DAC_FIELD_ENUM(HIFIDAC_RM,_CONTROL, TIMEBASE, TIMEBASE_0);
525        break;
526    case BAVC_Timebase_e1:
527        regVal |= DAC_FIELD_ENUM(HIFIDAC_RM,_CONTROL, TIMEBASE, TIMEBASE_1);
528        break;
529    case BAVC_Timebase_e2:
530        regVal |= DAC_FIELD_ENUM(HIFIDAC_RM,_CONTROL, TIMEBASE, TIMEBASE_2);
531        break;
532    case BAVC_Timebase_e3:
533        regVal |= DAC_FIELD_ENUM(HIFIDAC_RM,_CONTROL, TIMEBASE, TIMEBASE_3);
534        break;
535    }
536    BREG_Write32_isr(handle->deviceHandle->regHandle, regAddr, regVal);
537
538    /* Update Sample Rate */
539    handle->sampleRate = sampleRate;
540    handle->timebase   = timebase;
541    BAPE_Dac_P_SetRateManager_isr(handle, sampleRate);
542}
543
544/**************************************************************************/
545
546static void BAPE_Dac_P_SetMute(BAPE_OutputPort output, bool muted, bool sync)
547{
548    BAPE_DacHandle handle;
549    uint32_t regAddr, regVal;
550
551    BDBG_OBJECT_ASSERT(output, BAPE_OutputPort);
552
553    handle = output->pHandle;
554    BDBG_OBJECT_ASSERT(handle, BAPE_Dac);
555
556    regAddr = GET_DAC_REG_ADDR3(BCHP_HIFIDAC_CTRL, handle->index, _MUTECTRL_DACONLY );
557    regVal = BREG_Read32(handle->deviceHandle->regHandle, regAddr);
558    regVal &= ~DAC_MASK(HIFIDAC_CTRL,_MUTECTRL_DACONLY, MUTEDAC);
559    if ( muted )
560    {
561        regVal |= DAC_FIELD_ENUM(HIFIDAC_CTRL,_MUTECTRL_DACONLY, MUTEDAC, Ramp_mute);
562    }
563    BREG_Write32(handle->deviceHandle->regHandle, regAddr, regVal);
564    if ( sync )
565    {
566        BAPE_Dac_P_SyncVolume(handle);
567    }
568}
569
570/**************************************************************************/
571
572static BERR_Code BAPE_Dac_P_Enable(BAPE_OutputPort output)
573{
574    BAPE_DacHandle handle;
575    uint32_t regAddr, regVal;
576    uint32_t peakGain, peakA1, peakA2, asrcout, stepSize;
577    unsigned streamId;
578
579    BDBG_OBJECT_ASSERT(output, BAPE_OutputPort);
580
581    handle = output->pHandle;
582    BDBG_OBJECT_ASSERT(handle, BAPE_Dac);
583    BDBG_ASSERT(false == handle->enabled);
584
585    streamId = GET_DAC_IOP_STREAM_ID(handle->index);
586    BDBG_MSG(("Enabling DAC %u [stream %u]", handle->index, streamId));
587
588#ifdef BCHP_AUD_FMM_IOP_CTRL_REG_START
589    {
590        BAPE_IopStreamSettings streamSettings;
591        BERR_Code errCode;
592        /* Write source FCI to IOP */
593        BAPE_Iop_P_GetStreamSettings(handle->deviceHandle, streamId, &streamSettings);
594        streamSettings.resolution = 24;
595        streamSettings.input = output->sourceMixerFci.ids[BAPE_ChannelPair_eLeftRight];         /* Take source FCI provided from mixer */
596        errCode = BAPE_Iop_P_SetStreamSettings(handle->deviceHandle, streamId, &streamSettings);
597        if ( errCode )
598        {
599            return BERR_TRACE(errCode);
600        }
601    }
602#else
603    regAddr = GET_DAC_REG_ADDR3(BCHP_AUD_FMM_IOP_OUT_DAC_CTRL, handle->index, _STREAM_CFG_0);
604    regVal = BREG_Read32(handle->deviceHandle->regHandle, regAddr);
605    regVal &= ~DAC_MASK(AUD_FMM_IOP_OUT_DAC_CTRL,_STREAM_CFG_0,FCI_ID);
606    regVal |= DAC_FIELD_DATA(AUD_FMM_IOP_OUT_DAC_CTRL,_STREAM_CFG_0, FCI_ID, output->sourceMixerFci.ids[BAPE_ChannelPair_eLeftRight]);
607    regVal &= ~DAC_MASK(AUD_FMM_IOP_OUT_DAC_CTRL,_STREAM_CFG_0,STREAM_BIT_RESOLUTION);
608    regVal |= DAC_FIELD_ENUM(AUD_FMM_IOP_OUT_DAC_CTRL,_STREAM_CFG_0, STREAM_BIT_RESOLUTION, Res_24_Bit);
609    BREG_Write32(handle->deviceHandle->regHandle, regAddr, regVal);
610#endif
611
612    handle->compressed = output->mixer->compressed;
613    if ( handle->compressed )
614    {
615        if ( output->mixer->pathNode.paths[0].connector.codec != BAVC_AudioCompressionStd_eMax )
616        {
617            BDBG_ERR(("DACs can only handle RF encoded data and not other compressed formats."));
618            return BERR_TRACE(BERR_NOT_SUPPORTED);
619        }
620       
621        /* Setup peaking filter for RF audio */
622        peakGain = BAPE_DAC_RF_HIFIDAC_CTRL0_PEAK_GAIN_PEAK_GAIN;
623        peakA1 = BAPE_DAC_RF_HIFIDAC_CTRL0_PEAK_A1_PEAK_A1;
624        peakA2 = BAPE_DAC_RF_HIFIDAC_CTRL0_PEAK_A2_PEAK_A2;
625        asrcout = BAPE_DAC_RF_HIFIDAC_CTRL0_RANGE_ASRCOUT;
626        stepSize = BAPE_DAC_RF_HIFIDAC_CTRL0_DAC_VOLUMECFG_STEPSIZE;
627    }
628    else
629    {
630        /* Setup peaking filter for PCM audio */
631        peakGain = handle->settings.peakGain;
632        peakA1 = BAPE_DAC_DEFAULT_HIFIDAC_CTRL0_PEAK_A1_PEAK_A1;
633        peakA2 = BAPE_DAC_DEFAULT_HIFIDAC_CTRL0_PEAK_A2_PEAK_A2;
634        asrcout = BAPE_DAC_DEFAULT_HIFIDAC_CTRL0_RANGE_ASRCOUT;       
635        stepSize = BAPE_DAC_DEFAULT_HIFIDAC_CTRL0_DAC_VOLUMECFG_STEPSIZE;
636    }
637   
638    regAddr = GET_DAC_REG_ADDR3(BCHP_HIFIDAC_CTRL, handle->index, _PEAK_GAIN );
639    regVal = DAC_FIELD_DATA(HIFIDAC_CTRL,_PEAK_GAIN, PEAK_GAIN, peakGain);
640    BREG_Write32(handle->deviceHandle->regHandle, regAddr, regVal);
641
642    regAddr = GET_DAC_REG_ADDR3(BCHP_HIFIDAC_CTRL, handle->index, _PEAK_A1 );
643    regVal = BREG_Read32(handle->deviceHandle->regHandle, regAddr );
644    regVal &= ~(DAC_MASK(HIFIDAC_CTRL,_PEAK_A1, PEAK_A1));
645    regVal |= DAC_FIELD_DATA(HIFIDAC_CTRL,_PEAK_A1, PEAK_A1, peakA1);
646    BREG_Write32(handle->deviceHandle->regHandle, regAddr, regVal);
647
648    regAddr = GET_DAC_REG_ADDR3(BCHP_HIFIDAC_CTRL, handle->index, _PEAK_A2 );
649    regVal = BREG_Read32(handle->deviceHandle->regHandle, regAddr );
650    regVal &= ~(DAC_MASK(HIFIDAC_CTRL,_PEAK_A2, PEAK_A2));
651    regVal |= DAC_FIELD_DATA(HIFIDAC_CTRL,_PEAK_A2, PEAK_A2, peakA2);
652    BREG_Write32(handle->deviceHandle->regHandle, regAddr, regVal);
653               
654    regAddr = GET_DAC_REG_ADDR3(BCHP_HIFIDAC_CTRL, handle->index, _RANGE );
655    regVal = BREG_Read32(handle->deviceHandle->regHandle, regAddr);
656    regVal &= ~DAC_MASK(HIFIDAC_CTRL,_RANGE, ASRCOUT);
657    regVal |= DAC_FIELD_DATA(HIFIDAC_CTRL,_RANGE, ASRCOUT, asrcout);
658    BREG_Write32(handle->deviceHandle->regHandle, regAddr, regVal);
659   
660    regAddr = GET_DAC_REG_ADDR3(BCHP_HIFIDAC_CTRL, handle->index, _DAC_VOLUMECFG );
661    regVal = BREG_Read32(handle->deviceHandle->regHandle, regAddr );
662    regVal &= ~(DAC_MASK(HIFIDAC_CTRL,_DAC_VOLUMECFG, STEPSIZE));
663    regVal |= DAC_FIELD_DATA(HIFIDAC_CTRL,_DAC_VOLUMECFG, STEPSIZE, stepSize);
664    BREG_Write32(handle->deviceHandle->regHandle, regAddr, regVal);
665
666    /* Write the enable bit in the OP (only stereo) */
667#ifdef BCHP_AUD_FMM_IOP_CTRL_REG_START
668    streamId = GET_DAC_OP_STREAM_ID(handle->index);
669    BDBG_MSG(("Writing %x to enable set", (BCHP_MASK(AUD_FMM_OP_CTRL_ENABLE_SET, STREAM0_ENA))<<(streamId)));
670    BREG_Write32(handle->deviceHandle->regHandle, 
671                 BCHP_AUD_FMM_OP_CTRL_ENABLE_SET,
672                 (BCHP_MASK(AUD_FMM_OP_CTRL_ENABLE_SET, STREAM0_ENA))<<(streamId));
673#else
674    regAddr = GET_DAC_REG_ADDR3(BCHP_AUD_FMM_IOP_OUT_DAC_CTRL, handle->index, _STREAM_CFG_0);
675    regVal = BREG_Read32(handle->deviceHandle->regHandle, regAddr);
676    regVal &= ~DAC_MASK(AUD_FMM_IOP_OUT_DAC_CTRL,_STREAM_CFG_0,ENA);
677    regVal |= DAC_FIELD_DATA(AUD_FMM_IOP_OUT_DAC_CTRL,_STREAM_CFG_0, ENA, 1);
678    BREG_Write32(handle->deviceHandle->regHandle, regAddr, regVal);
679#endif
680
681    BAPE_Dac_P_SetMute(output, false, false);
682     
683    handle->enabled = true;
684
685    return BERR_SUCCESS;
686}
687
688/**************************************************************************/
689
690static void BAPE_Dac_P_Disable(BAPE_OutputPort output)
691{
692    BAPE_DacHandle handle;
693    unsigned streamId;
694
695    BDBG_OBJECT_ASSERT(output, BAPE_OutputPort);
696
697    handle = output->pHandle;
698    BDBG_OBJECT_ASSERT(handle, BAPE_Dac);
699
700    streamId = GET_DAC_OP_STREAM_ID(handle->index);
701    BDBG_MSG(("Disabling DAC %u [stream %u]", handle->index, streamId));
702
703    if ( !handle->settings.testTone.enabled )
704    {
705        BAPE_Dac_P_SetMute(output, true, true);
706    }
707
708#ifdef BCHP_AUD_FMM_IOP_CTRL_REG_START
709    {
710        BAPE_IopStreamSettings streamSettings;
711        BERR_Code errCode;
712        /* Clear the enable bit in the OP */
713        BDBG_MSG(("Writing %x to enable clear", (BCHP_MASK(AUD_FMM_OP_CTRL_ENABLE_SET, STREAM0_ENA))<<(streamId)));
714        BREG_Write32(handle->deviceHandle->regHandle, 
715                     BCHP_AUD_FMM_OP_CTRL_ENABLE_CLEAR,
716                     BCHP_MASK(AUD_FMM_OP_CTRL_ENABLE_CLEAR, STREAM0_ENA)<<streamId);
717
718        /* Reset source FCI to Invalid */
719        streamId = GET_DAC_IOP_STREAM_ID(handle->index);
720        BAPE_Iop_P_GetStreamSettings(handle->deviceHandle, streamId, &streamSettings);
721        streamSettings.input = BAPE_FCI_ID_INVALID;
722        errCode = BAPE_Iop_P_SetStreamSettings(handle->deviceHandle, streamId, &streamSettings);
723        BDBG_ASSERT(BERR_SUCCESS == errCode);
724    }
725#else
726    {
727        uint32_t regAddr, regVal;
728
729        regAddr = GET_DAC_REG_ADDR3(BCHP_AUD_FMM_IOP_OUT_DAC_CTRL, handle->index, _STREAM_CFG_0);
730        regVal = BREG_Read32(handle->deviceHandle->regHandle, regAddr);
731        regVal &= ~DAC_MASK(AUD_FMM_IOP_OUT_DAC_CTRL,_STREAM_CFG_0,ENA);
732        regVal &= ~DAC_MASK(AUD_FMM_IOP_OUT_DAC_CTRL,_STREAM_CFG_0,FCI_ID);
733        regVal |= DAC_FIELD_DATA(AUD_FMM_IOP_OUT_DAC_CTRL,_STREAM_CFG_0, FCI_ID, BAPE_FCI_ID_INVALID);
734        BREG_Write32(handle->deviceHandle->regHandle, regAddr, regVal);
735    }
736#endif
737
738    handle->enabled = false;
739    handle->compressed = false;
740}
741
742/***************************************************************************
743        Private functions: Protyped above
744***************************************************************************/
745
746static void BAPE_Dac_P_SetRateManager_isr(BAPE_DacHandle handle, unsigned sampleRate)
747{
748    uint32_t regAddr, regVal, numerator, denominator, sampleInc, phaseInc;
749    unsigned rateNum;
750
751    rateNum = sampleRate;
752
753    BDBG_MSG(("Setting DAC %u to %u Hz", handle->index, sampleRate));
754
755    regAddr = GET_DAC_REG_ADDR3(BCHP_HIFIDAC_CTRL, handle->index, _CONFIG );
756    regVal = BREG_Read32_isr(handle->deviceHandle->regHandle, regAddr);
757    regVal &= ~DAC_MASK(HIFIDAC_CTRL,_CONFIG, FIR_MODE);
758    if ( rateNum > 96000 )
759    {
760        regVal |= DAC_FIELD_ENUM(HIFIDAC_CTRL,_CONFIG, FIR_MODE, Audio_over100kHz);
761    }
762    else
763    {
764        regVal |= DAC_FIELD_ENUM(HIFIDAC_CTRL,_CONFIG, FIR_MODE, Audio_under100kHz);
765    }
766    BREG_Write32_isr(handle->deviceHandle->regHandle, regAddr, regVal);
767
768    /* Program the Oversampling frequency */
769    regAddr = GET_DAC_REG_ADDR3(BCHP_HIFIDAC_CTRL, handle->index, _RATEMGRCFG );
770    regVal = BREG_Read32_isr(handle->deviceHandle->regHandle, regAddr);
771    regVal &= ~DAC_MASK(HIFIDAC_CTRL,_RATEMGRCFG, OVERSAMPLE);
772    if ( rateNum <= 48000 )
773    {
774        regVal |= DAC_FIELD_ENUM(HIFIDAC_CTRL,_RATEMGRCFG, OVERSAMPLE, Fs256);
775    }
776    else
777    {
778        regVal |= DAC_FIELD_ENUM(HIFIDAC_CTRL,_RATEMGRCFG, OVERSAMPLE, Fs64);
779    }
780    BREG_Write32_isr(handle->deviceHandle->regHandle, regAddr, regVal);
781
782    /* These chips run at 108 MHz */
783    switch ( sampleRate )
784    {
785    case 128000:
786    case 32000:
787        numerator = 303;
788        denominator = 1024;
789        sampleInc = 3;
790        phaseInc = 0x0009b583;
791        break;
792    case 64000:
793        numerator = 303;
794        denominator = 512;
795        sampleInc = 6;
796        phaseInc = 0x0004dac2;
797        break;
798    case 176400:
799    case 44100:
800        numerator = 307;
801        denominator = 784;
802        sampleInc = 2;
803        phaseInc = 0x000d6159;
804        break;
805    case 88200:
806        numerator = 307;
807        denominator = 392;
808        sampleInc = 4;
809        phaseInc = 0x0006b0ad;
810        break;
811    default:
812        BDBG_WRN(("Unsupported DAC sampling rate (%d).  Defaulting to 48k.", sampleRate));
813        /* Fall through */
814    case 192000:
815    case 48000:
816        numerator = 101;
817        denominator = 512;
818        sampleInc = 2;
819        phaseInc = 0x000e9045;
820        break;
821    case 96000:
822        numerator = 101;
823        denominator = 256;
824        sampleInc = 4;
825        phaseInc = 0x00074823;
826        break;
827    }
828
829    regAddr = GET_DAC_REG_ADDR3(BCHP_HIFIDAC_RM, handle->index, _RATE_RATIO );
830    regVal = BREG_Read32_isr(handle->deviceHandle->regHandle, regAddr);
831    regVal &= ~DAC_MASK(HIFIDAC_RM,_RATE_RATIO, DENOMINATOR);
832    regVal |= DAC_FIELD_DATA(HIFIDAC_RM,_RATE_RATIO, DENOMINATOR, denominator);
833    BREG_Write32_isr(handle->deviceHandle->regHandle, regAddr, regVal);
834
835    regAddr = GET_DAC_REG_ADDR3(BCHP_HIFIDAC_RM, handle->index, _SAMPLE_INC );
836    regVal = BREG_Read32_isr(handle->deviceHandle->regHandle, regAddr);
837    regVal &= ~(DAC_MASK(HIFIDAC_RM,_SAMPLE_INC, SAMPLE_INC) | DAC_MASK(HIFIDAC_RM,_SAMPLE_INC, NUMERATOR));
838    regVal |= DAC_FIELD_DATA(HIFIDAC_RM,_SAMPLE_INC, NUMERATOR, numerator);
839    regVal |= DAC_FIELD_DATA(HIFIDAC_RM,_SAMPLE_INC, SAMPLE_INC, sampleInc);
840    BREG_Write32_isr(handle->deviceHandle->regHandle, regAddr, regVal);
841
842    regAddr = GET_DAC_REG_ADDR3(BCHP_HIFIDAC_RM, handle->index, _PHASE_INC );
843    regVal = BREG_Read32_isr(handle->deviceHandle->regHandle, regAddr);
844    regVal &= ~DAC_MASK(HIFIDAC_RM,_PHASE_INC, PHASE_INC);
845    regVal |= DAC_FIELD_DATA(HIFIDAC_RM,_PHASE_INC, PHASE_INC, phaseInc);
846    BREG_Write32_isr(handle->deviceHandle->regHandle, regAddr, regVal);
847}
848
849/**************************************************************************/
850
851static void BAPE_Dac_P_SyncVolume(BAPE_DacHandle handle)
852{
853    uint32_t regAddr;
854    int i;
855
856    BDBG_OBJECT_ASSERT(handle, BAPE_Dac);
857
858    regAddr = GET_DAC_REG_ADDR3(BCHP_HIFIDAC_CTRL, handle->index, _STATUS );
859    for ( i = 0; i < 1000; i++ )
860    {
861        uint32_t status = BREG_Read32(handle->deviceHandle->regHandle, regAddr);
862        if ( DAC_GET_FIELD_DATA(status, HIFIDAC_CTRL,_STATUS, VOLUME_AT_TARGET) )
863        {
864            break;
865        }
866        BKNI_Sleep(1);
867    }
868}
869
870/**************************************************************************/
871
872static void BAPE_Dac_P_PowerDown(BAPE_Handle bapeHandle, unsigned dacIndex)
873{
874    uint32_t regVal, regAddr, regMask;
875
876    BDBG_OBJECT_ASSERT(bapeHandle, BAPE_Device);
877    BDBG_ASSERT(dacIndex < BAPE_CHIP_MAX_DACS);
878
879/* While the DAC is powered off, keep its SYNC_INIT_DAC (or SYNC_RESET_DAC) bit set.
880     * And don't clear it until after the DAC is powered back up.
881     */
882    #ifdef BCHP_HIFIDAC_CTRL0_RESET   /* 35230 */
883        regAddr = GET_DAC_REG_ADDR3(BCHP_HIFIDAC_CTRL, dacIndex, _RESET );
884        regVal = BREG_Read32(bapeHandle->regHandle, regAddr);
885        regVal |= BCHP_MASK(HIFIDAC_CTRL0_RESET, SYNC_RESET_DAC );      /* Set the reset bit*/
886        BREG_Write32(bapeHandle->regHandle, regAddr, regVal);
887    #elif defined BCHP_HIFIDAC_CTRL0_INIT || defined BCHP_HIFIDAC_CTRL_0_INIT
888        regAddr = GET_DAC_REG_ADDR3(BCHP_HIFIDAC_CTRL, dacIndex, _INIT );
889        regVal = BREG_Read32(bapeHandle->regHandle, regAddr);
890        regVal |= DAC_MASK(HIFIDAC_CTRL,_INIT, SYNC_INIT_DAC );      /* Set the reset bit*/
891        BREG_Write32(bapeHandle->regHandle, regAddr, regVal);
892    #endif
893
894#ifdef BCHP_AIO_MISC_PWRDOWN
895    /* Figure out which powerdown bits to set. */
896    switch ( dacIndex )
897    {
898    #if BAPE_CHIP_MAX_DACS > 0
899       case 0:
900            regMask = BCHP_MASK(AIO_MISC_PWRDOWN, DAC0_POWERDN_REF) | 
901                      BCHP_MASK(AIO_MISC_PWRDOWN, DAC0_POWERDN_LR);
902            break;
903    #endif
904    #if BAPE_CHIP_MAX_DACS > 1
905        case 1:
906            regMask = BCHP_MASK(AIO_MISC_PWRDOWN, DAC1_POWERDN_REF) | 
907                      BCHP_MASK(AIO_MISC_PWRDOWN, DAC1_POWERDN_LR);
908            break;
909    #endif
910    #if BAPE_CHIP_MAX_DACS > 2
911        case 2:
912            regMask = BCHP_MASK(AIO_MISC_PWRDOWN, DAC2_POWERDN_REF) | 
913                      BCHP_MASK(AIO_MISC_PWRDOWN, DAC2_POWERDN_LR);
914            break;
915    #endif
916    #if BAPE_CHIP_MAX_DACS > 3
917        case 3:
918            regMask = BCHP_MASK(AIO_MISC_PWRDOWN, DAC3_POWERDN_REF) | 
919                      BCHP_MASK(AIO_MISC_PWRDOWN, DAC3_POWERDN_LR);
920            break;
921    #endif
922    #if BAPE_CHIP_MAX_DACS > 4
923            #error "Need to add support for more DACS"
924    #endif
925    /* Should never get here */
926    default:
927        BDBG_ERR(("DAC index (%u) doesn't refer to a valid DAC", dacIndex));
928        BDBG_ASSERT(false);     /* something went wrong somewhere! */
929        return;
930    }
931
932    /* Now just set those bits in the DAC's powerdown register */
933    regAddr = BCHP_AIO_MISC_PWRDOWN;
934    regVal = BREG_Read32(bapeHandle->regHandle, regAddr);
935    regVal |= regMask;
936    BREG_Write32(bapeHandle->regHandle, regAddr, regVal);
937#else
938    /* Figure out which powerdown bits to set. */
939    switch ( dacIndex )
940    {
941    #if BAPE_CHIP_MAX_DACS > 0
942       case 0:
943            regMask = BCHP_MASK(AUD_MISC_PWRDOWN, DAC0_POWERDN_REF) | 
944                      BCHP_MASK(AUD_MISC_PWRDOWN, DAC0_POWERDN_LR);
945            break;
946    #endif
947    #if BAPE_CHIP_MAX_DACS > 1
948        case 1:
949            regMask = BCHP_MASK(AUD_MISC_PWRDOWN, DAC1_POWERDN_REF) | 
950                      BCHP_MASK(AUD_MISC_PWRDOWN, DAC1_POWERDN_LR);
951            break;
952    #endif
953    #if BAPE_CHIP_MAX_DACS > 2
954        case 2:
955            regMask = BCHP_MASK(AUD_MISC_PWRDOWN, DAC2_POWERDN_REF) | 
956                      BCHP_MASK(AUD_MISC_PWRDOWN, DAC2_POWERDN_LR);
957            break;
958    #endif
959    #if BAPE_CHIP_MAX_DACS > 3
960        case 3:
961            regMask = BCHP_MASK(AUD_MISC_PWRDOWN, DAC3_POWERDN_REF) | 
962                      BCHP_MASK(AUD_MISC_PWRDOWN, DAC3_POWERDN_LR);
963            break;
964    #endif
965    #if BAPE_CHIP_MAX_DACS > 4
966            #error "Need to add support for more DACS"
967    #endif
968    /* Should never get here */
969    default:
970        BDBG_ERR(("DAC index (%u) doesn't refer to a valid DAC", dacIndex));
971        BDBG_ASSERT(false);     /* something went wrong somewhere! */
972        return;
973    }
974
975    /* Now just set those bits in the DAC's powerdown register */
976    regAddr = BCHP_AUD_MISC_PWRDOWN;
977    regVal = BREG_Read32(bapeHandle->regHandle, regAddr);
978    regVal |= regMask;
979    BREG_Write32(bapeHandle->regHandle, regAddr, regVal);
980#endif
981
982    return;
983}
984
985/**************************************************************************/
986
987static void BAPE_Dac_P_PowerUp(BAPE_Handle bapeHandle, unsigned dacIndex)
988{
989    uint32_t regVal, regAddr, regMask;
990
991    BDBG_OBJECT_ASSERT(bapeHandle, BAPE_Device);
992    BDBG_ASSERT(dacIndex < BAPE_CHIP_MAX_DACS);
993
994    /* Clear bit 9 from the CURRDAC_CTRL.CTRL field during DAC power up.
995     * Otherwise, the DAC can take really long to power up... like up to
996     * 40 seconds or more.  But only clear this bit for a millisecond,
997     * then set it again.
998     */ 
999    regAddr = GET_DAC_REG_ADDR3(BCHP_HIFIDAC_CTRL, dacIndex, _CURRDAC_CTRL );
1000    regVal = BREG_Read32(bapeHandle->regHandle, regAddr);
1001    regVal &= ~(DAC_FIELD_DATA(HIFIDAC_CTRL,_CURRDAC_CTRL, CTRL, 0x200));
1002    BREG_Write32(bapeHandle->regHandle, regAddr, regVal);
1003
1004#ifdef BCHP_AIO_MISC_PWRDOWN
1005    /* Figure out which powerdown bits to clear. */
1006    switch ( dacIndex )
1007    {
1008    #if BAPE_CHIP_MAX_DACS > 0
1009       case 0:
1010            regMask = BCHP_MASK(AIO_MISC_PWRDOWN, DAC0_POWERDN_REF) | 
1011                      BCHP_MASK(AIO_MISC_PWRDOWN, DAC0_POWERDN_LR);
1012            break;
1013    #endif
1014    #if BAPE_CHIP_MAX_DACS > 1
1015        case 1:
1016            regMask = BCHP_MASK(AIO_MISC_PWRDOWN, DAC1_POWERDN_REF) | 
1017                      BCHP_MASK(AIO_MISC_PWRDOWN, DAC1_POWERDN_LR);
1018            break;
1019    #endif
1020    #if BAPE_CHIP_MAX_DACS > 2
1021        case 2:
1022            regMask = BCHP_MASK(AIO_MISC_PWRDOWN, DAC2_POWERDN_REF) | 
1023                      BCHP_MASK(AIO_MISC_PWRDOWN, DAC2_POWERDN_LR);
1024            break;
1025    #endif
1026    #if BAPE_CHIP_MAX_DACS > 3
1027        case 3:
1028            regMask = BCHP_MASK(AIO_MISC_PWRDOWN, DAC3_POWERDN_REF) | 
1029                      BCHP_MASK(AIO_MISC_PWRDOWN, DAC3_POWERDN_LR);
1030            break;
1031    #endif
1032    #if BAPE_CHIP_MAX_DACS > 4
1033            #error "Need to add support for more DACS"
1034    #endif
1035    /* Should never get here */
1036    default:
1037        BDBG_ERR(("DAC index (%u) doesn't refer to a valid DAC", dacIndex));
1038        BDBG_ASSERT(false);     /* something went wrong somewhere! */
1039        return;
1040    }
1041
1042    /* Now just clear those bits in the DAC's powerdown register */
1043    regAddr = BCHP_AIO_MISC_PWRDOWN;
1044    regVal = BREG_Read32(bapeHandle->regHandle, regAddr);
1045    regVal &= ~regMask;
1046    BREG_Write32(bapeHandle->regHandle, regAddr, regVal);
1047#else
1048    /* Figure out which powerdown bits to clear. */
1049    switch ( dacIndex )
1050    {
1051    #if BAPE_CHIP_MAX_DACS > 0
1052       case 0:
1053            regMask = BCHP_MASK(AUD_MISC_PWRDOWN, DAC0_POWERDN_REF) | 
1054                      BCHP_MASK(AUD_MISC_PWRDOWN, DAC0_POWERDN_LR);
1055            break;
1056    #endif
1057    #if BAPE_CHIP_MAX_DACS > 1
1058        case 1:
1059            regMask = BCHP_MASK(AUD_MISC_PWRDOWN, DAC1_POWERDN_REF) | 
1060                      BCHP_MASK(AUD_MISC_PWRDOWN, DAC1_POWERDN_LR);
1061            break;
1062    #endif
1063    #if BAPE_CHIP_MAX_DACS > 2
1064        case 2:
1065            regMask = BCHP_MASK(AUD_MISC_PWRDOWN, DAC2_POWERDN_REF) | 
1066                      BCHP_MASK(AUD_MISC_PWRDOWN, DAC2_POWERDN_LR);
1067            break;
1068    #endif
1069    #if BAPE_CHIP_MAX_DACS > 3
1070        case 3:
1071            regMask = BCHP_MASK(AUD_MISC_PWRDOWN, DAC3_POWERDN_REF) | 
1072                      BCHP_MASK(AUD_MISC_PWRDOWN, DAC3_POWERDN_LR);
1073            break;
1074    #endif
1075    #if BAPE_CHIP_MAX_DACS > 4
1076            #error "Need to add support for more DACS"
1077    #endif
1078    /* Should never get here */
1079    default:
1080        BDBG_ERR(("DAC index (%u) doesn't refer to a valid DAC", dacIndex));
1081        BDBG_ASSERT(false);     /* something went wrong somewhere! */
1082        return;
1083    }
1084
1085    /* Now just clear those bits in the DAC's powerdown register */
1086    regAddr = BCHP_AUD_MISC_PWRDOWN;
1087    regVal = BREG_Read32(bapeHandle->regHandle, regAddr);
1088    regVal &= ~regMask;
1089    BREG_Write32(bapeHandle->regHandle, regAddr, regVal);
1090#endif
1091
1092    /* Now that the DAC is powered up, we can take it out of reset by
1093     * clearing the SYNC_INIT_DAC (or SYNC_RESET_DAC) bit.
1094     */
1095    #ifdef BCHP_HIFIDAC_CTRL0_RESET   /* 35230 */
1096        regAddr = GET_DAC_REG_ADDR3(BCHP_HIFIDAC_CTRL, dacIndex, _RESET );
1097        regVal = BREG_Read32(bapeHandle->regHandle, regAddr);
1098        regVal &= ~DAC_MASK(HIFIDAC_CTRL,_RESET, SYNC_RESET_DAC );      /* Clear the reset bit*/
1099        BREG_Write32(bapeHandle->regHandle, regAddr, regVal);
1100    #elif defined BCHP_HIFIDAC_CTRL0_INIT || defined BCHP_HIFIDAC_CTRL_0_INIT
1101        regAddr = GET_DAC_REG_ADDR3(BCHP_HIFIDAC_CTRL, dacIndex, _INIT );
1102        regVal = BREG_Read32(bapeHandle->regHandle, regAddr);
1103        regVal &= ~DAC_MASK(HIFIDAC_CTRL,_INIT, SYNC_INIT_DAC );      /* Clear the reset bit*/
1104        BREG_Write32(bapeHandle->regHandle, regAddr, regVal);
1105    #endif
1106
1107    /* Finally, set bit 9 of the CURRDAC_CTRL.CTRL back to its normal state. */
1108    BKNI_Sleep(1);    /* Min Gyu said that bit 9 should be held clear for at least a millisecond. */
1109    regAddr = GET_DAC_REG_ADDR3(BCHP_HIFIDAC_CTRL, dacIndex, _CURRDAC_CTRL );
1110    regVal = BREG_Read32(bapeHandle->regHandle, regAddr);
1111    regVal |= DAC_FIELD_DATA(HIFIDAC_CTRL,_CURRDAC_CTRL, CTRL, 0x200);
1112    BREG_Write32(bapeHandle->regHandle, regAddr, regVal);
1113
1114    return;
1115}
1116
1117/**************************************************************************/
1118
1119static BERR_Code BAPE_Dac_P_OpenHw(BAPE_DacHandle handle)
1120{
1121    BERR_Code       errCode = BERR_SUCCESS;
1122    BAPE_Handle     deviceHandle;
1123    unsigned        i;
1124    uint32_t        regAddr, regVal;
1125
1126    BDBG_OBJECT_ASSERT(handle, BAPE_Dac);
1127
1128    deviceHandle = handle->deviceHandle;
1129    BDBG_OBJECT_ASSERT(deviceHandle, BAPE_Device);
1130
1131    #ifdef BCHP_HIFIDAC_CTRL0_RESET
1132        /* Initialize hardware before applying settings */
1133        regAddr = GET_DAC_REG_ADDR3(BCHP_HIFIDAC_CTRL, handle->index, _RESET );
1134        BREG_Write32(deviceHandle->regHandle, regAddr, 1);
1135        (void)BREG_Read32(deviceHandle->regHandle, regAddr);    /* Sync the register write */
1136        BREG_Write32(deviceHandle->regHandle, regAddr, 0);
1137    #elif defined BCHP_HIFIDAC_CTRL0_INIT || defined BCHP_HIFIDAC_CTRL_0_INIT
1138        regAddr = GET_DAC_REG_ADDR3(BCHP_HIFIDAC_CTRL, handle->index, _INIT );
1139        BREG_Write32(deviceHandle->regHandle, regAddr, 0);
1140    #endif
1141
1142    /* Init test RAM... map the testtone register array to the Samples buffer. */
1143    regAddr = GET_DAC_REG_ADDR3(BCHP_HIFIDAC_CTRL, handle->index, _TEST );
1144    regVal = BREG_Read32(deviceHandle->regHandle, regAddr);
1145    regVal &= ~DAC_MASK(HIFIDAC_CTRL,_TEST, RAM_BUF_SEL);
1146    regVal |= DAC_FIELD_ENUM(HIFIDAC_CTRL,_TEST, RAM_BUF_SEL, Samples);
1147    BREG_Write32(deviceHandle->regHandle, regAddr, regVal);
1148
1149    /* Enable the test tone, otherwise we can't write to the testtone register array. */
1150    regVal &= ~DAC_MASK(HIFIDAC_CTRL,_TEST, TESTTONE_ENABLE);
1151    regVal |= DAC_FIELD_ENUM(HIFIDAC_CTRL,_TEST, TESTTONE_ENABLE, Enable);
1152    BREG_Write32(deviceHandle->regHandle, regAddr, regVal);
1153
1154    /* Set samples buffer to zero */
1155    regAddr = GET_DAC_REG_ADDR3(BCHP_HIFIDAC_CTRL, handle->index, _TESTTONE_SAMPLE_i_ARRAY_BASE );
1156    for (   i =  GET_DAC_REG_ADDR3(BCHP_HIFIDAC_CTRL, handle->index, _TESTTONE_SAMPLE_i_ARRAY_START) ; 
1157            i <= GET_DAC_REG_ADDR3(BCHP_HIFIDAC_CTRL, handle->index, _TESTTONE_SAMPLE_i_ARRAY_END)   ;
1158            i++ )
1159    {
1160        BREG_Write32(deviceHandle->regHandle, regAddr + (4 * i), 0);
1161    }
1162
1163    /* Now map the testtone register array to the Pingpong buffer. */
1164    regAddr = GET_DAC_REG_ADDR3(BCHP_HIFIDAC_CTRL, handle->index, _TEST );
1165    regVal = BREG_Read32(deviceHandle->regHandle, regAddr);
1166    regVal &= ~DAC_MASK(HIFIDAC_CTRL,_TEST, RAM_BUF_SEL);
1167    regVal |= DAC_FIELD_ENUM(HIFIDAC_CTRL,_TEST, RAM_BUF_SEL, Pingpong);
1168    BREG_Write32(deviceHandle->regHandle, regAddr, regVal);
1169
1170    /* Set pingpong buffer to zero */
1171    regAddr = GET_DAC_REG_ADDR3(BCHP_HIFIDAC_CTRL, handle->index, _TESTTONE_SAMPLE_i_ARRAY_BASE );
1172    for (   i =  GET_DAC_REG_ADDR3(BCHP_HIFIDAC_CTRL, handle->index, _TESTTONE_SAMPLE_i_ARRAY_START) ; 
1173            i <= GET_DAC_REG_ADDR3(BCHP_HIFIDAC_CTRL, handle->index, _TESTTONE_SAMPLE_i_ARRAY_END)   ;
1174            i++ )
1175    {
1176        BREG_Write32(deviceHandle->regHandle, regAddr + (4 * i), 0);
1177    }
1178
1179    /* We're done with the testtone registers, we can turn off testone_enable. */
1180    regAddr = GET_DAC_REG_ADDR3(BCHP_HIFIDAC_CTRL, handle->index, _TEST );
1181    regVal = BREG_Read32(deviceHandle->regHandle, regAddr);
1182    regVal &= ~DAC_MASK(HIFIDAC_CTRL,_TEST, TESTTONE_ENABLE);
1183    regVal |= DAC_FIELD_ENUM(HIFIDAC_CTRL,_TEST, TESTTONE_ENABLE, Normal_operation);
1184    BREG_Write32(deviceHandle->regHandle, regAddr, regVal);
1185
1186    /* Mute RFmod by default.  It will be unmuted (if necessary) by BAPE_RfMod_SetSettings(). */
1187    regAddr = GET_DAC_REG_ADDR3(BCHP_HIFIDAC_CTRL, handle->index, _CONFIG );
1188    regVal = BREG_Read32(deviceHandle->regHandle, regAddr);
1189    regVal &= ~DAC_MASK(HIFIDAC_CTRL,_CONFIG, RFMOD_MUTE);
1190    regVal |= DAC_FIELD_ENUM(HIFIDAC_CTRL,_CONFIG, RFMOD_MUTE, Mute);
1191    BREG_Write32(deviceHandle->regHandle, regAddr, regVal);
1192
1193    /* Program MAPPER_SOFTMUTE to normal */
1194    regVal &= ~DAC_MASK(HIFIDAC_CTRL,_CONFIG, MAPPER_SOFTMUTE);
1195    regVal |= DAC_FIELD_ENUM(HIFIDAC_CTRL,_CONFIG, MAPPER_SOFTMUTE, Normal_operation);
1196    BREG_Write32(deviceHandle->regHandle, regAddr, regVal);
1197
1198    /* Write full volume by default */
1199    regAddr = GET_DAC_REG_ADDR3(BCHP_HIFIDAC_CTRL, handle->index, _DAC_VOLUME );
1200    regVal = DAC_FIELD_DATA(HIFIDAC_CTRL,_DAC_VOLUME, DAC_VOL, 0x1ffff);
1201    BREG_Write32(deviceHandle->regHandle, regAddr, regVal);
1202
1203    /* Write set the DAC's RANGE.ASRCOUT to the appropriate default */
1204    regAddr = GET_DAC_REG_ADDR3(BCHP_HIFIDAC_CTRL, handle->index, _RANGE );
1205    regVal = BREG_Read32(deviceHandle->regHandle, regAddr);
1206    regVal &= ~DAC_MASK(HIFIDAC_CTRL,_RANGE, ASRCOUT);
1207    regVal |= DAC_FIELD_DATA(HIFIDAC_CTRL,_RANGE, ASRCOUT, BAPE_DAC_DEFAULT_HIFIDAC_CTRL0_RANGE_ASRCOUT);
1208    BREG_Write32(deviceHandle->regHandle, regAddr, regVal);
1209
1210    regAddr = GET_DAC_REG_ADDR3(BCHP_HIFIDAC_CTRL, handle->index, _PEAK_A1 );
1211    regVal = BREG_Read32(handle->deviceHandle->regHandle, regAddr );
1212    regVal &= ~(DAC_MASK(HIFIDAC_CTRL,_PEAK_A1, PEAK_A1));
1213    regVal |= DAC_FIELD_DATA(HIFIDAC_CTRL,_PEAK_A1, PEAK_A1, BAPE_DAC_DEFAULT_HIFIDAC_CTRL0_PEAK_A1_PEAK_A1);
1214    BREG_Write32(handle->deviceHandle->regHandle, regAddr, regVal);
1215
1216    regAddr = GET_DAC_REG_ADDR3(BCHP_HIFIDAC_CTRL, handle->index, _PEAK_A2 );
1217    regVal = BREG_Read32(handle->deviceHandle->regHandle, regAddr );
1218    regVal &= ~(DAC_MASK(HIFIDAC_CTRL,_PEAK_A2, PEAK_A2));
1219    regVal |= DAC_FIELD_DATA(HIFIDAC_CTRL,_PEAK_A2, PEAK_A2, BAPE_DAC_DEFAULT_HIFIDAC_CTRL0_PEAK_A2_PEAK_A2);
1220    BREG_Write32(handle->deviceHandle->regHandle, regAddr, regVal);
1221
1222    regAddr = GET_DAC_REG_ADDR3(BCHP_HIFIDAC_CTRL, handle->index, _DAC_VOLUMECFG );
1223    regVal = BREG_Read32(handle->deviceHandle->regHandle, regAddr );
1224    regVal &= ~(DAC_MASK(HIFIDAC_CTRL,_DAC_VOLUMECFG, STEPSIZE));
1225    regVal |= DAC_FIELD_DATA(HIFIDAC_CTRL,_DAC_VOLUMECFG, STEPSIZE, BAPE_DAC_DEFAULT_HIFIDAC_CTRL0_DAC_VOLUMECFG_STEPSIZE);
1226    BREG_Write32(handle->deviceHandle->regHandle, regAddr, regVal);
1227
1228    /* mute */
1229    BAPE_Dac_P_SetMute(&handle->outputPort, true, false);
1230
1231    /* Power up the DAC */
1232    BAPE_Dac_P_PowerUp(handle->deviceHandle, handle->index);
1233
1234    /* unmute the DACALL Control port */
1235    regAddr = GET_DAC_REG_ADDR3(BCHP_HIFIDAC_CTRL, handle->index, _MUTECTRL );
1236    regVal = BREG_Read32 (deviceHandle->regHandle, regAddr);
1237    regVal &= ~DAC_MASK(HIFIDAC_CTRL,_MUTECTRL, MUTEALL);
1238    regVal |= DAC_FIELD_ENUM(HIFIDAC_CTRL,_MUTECTRL, MUTEALL, Ramp_unmute);
1239    BREG_Write32(deviceHandle->regHandle, regAddr, regVal);
1240
1241    return errCode;
1242}
1243
1244/**************************************************************************/
1245
1246static bool BAPE_Dac_P_ToneSettingsChanged(const BAPE_DacSettings *pSettings1, const BAPE_DacSettings *pSettings2)
1247{
1248    unsigned i;
1249
1250    BDBG_ASSERT(NULL != pSettings1);
1251    BDBG_ASSERT(NULL != pSettings2);
1252
1253    if ( pSettings1->testTone.enabled != pSettings2->testTone.enabled )
1254    {
1255        return true;
1256    }
1257    if ( pSettings1->testTone.zeroOnLeft != pSettings2->testTone.zeroOnLeft )
1258    {
1259        return true;
1260    }
1261    if ( pSettings1->testTone.zeroOnRight != pSettings2->testTone.zeroOnRight )
1262    {
1263        return true;
1264    }
1265    if ( pSettings1->testTone.sharedSamples != pSettings2->testTone.sharedSamples )
1266    {
1267        return true;
1268    }
1269    if ( pSettings1->testTone.numSamplesLeft != pSettings2->testTone.numSamplesLeft )
1270    {
1271        return true;
1272    }
1273    if ( pSettings1->testTone.numSamplesRight != pSettings2->testTone.numSamplesRight )
1274    {
1275        return true;
1276    }
1277    if ( pSettings1->testTone.sampleRate != pSettings2->testTone.sampleRate )
1278    {
1279        return true;
1280    }
1281    if ( pSettings1->testTone.sampleRate != pSettings2->testTone.sampleRate )
1282    {
1283        return true;
1284    }
1285    for ( i = 0; i < sizeof(pSettings1->testTone.samples)/sizeof(int32_t); i++ )
1286    {
1287        if ( pSettings1->testTone.samples[i] != pSettings2->testTone.samples[i] )
1288        {
1289            return true;
1290        }
1291    }
1292    return false;
1293}
1294
1295/**************************************************************************/
1296
1297static BERR_Code BAPE_Dac_P_ApplySettings(
1298    BAPE_DacHandle handle,
1299    const BAPE_DacSettings *pSettings,
1300    bool force
1301    )
1302{
1303    uint32_t regAddr, regVal, origRegVal;
1304    unsigned i;
1305    BDBG_OBJECT_ASSERT(handle, BAPE_Dac);
1306    BDBG_ASSERT(NULL != pSettings);
1307   
1308    /* Sanity checks before changing any settings */
1309    if ( pSettings->testTone.enabled && 
1310         (pSettings->testTone.numSamplesLeft < 1 || pSettings->testTone.numSamplesLeft > 64 ||
1311          pSettings->testTone.numSamplesRight < 1 || pSettings->testTone.numSamplesRight > 64) )
1312    {
1313        BDBG_ERR(("Test tone samples must be between 1 and 64 for both left and right."));
1314        return BERR_TRACE(BERR_INVALID_PARAMETER);
1315    }
1316
1317    /* Mute before changing this setting */
1318
1319    regAddr = GET_DAC_REG_ADDR3(BCHP_HIFIDAC_CTRL, handle->index, _CONFIG );
1320    origRegVal = regVal = BREG_Read32(handle->deviceHandle->regHandle, regAddr );
1321    regVal &= ~(DAC_MASK(HIFIDAC_CTRL,_CONFIG, MAPPER_MUTETYPE) |
1322                DAC_MASK(HIFIDAC_CTRL,_CONFIG, I2S_SELECT_RIGHT) |
1323                DAC_MASK(HIFIDAC_CTRL,_CONFIG, I2S_SELECT_LEFT));
1324    switch ( pSettings->muteType )
1325    {
1326    case BAPE_DacMuteType_eDrive0:
1327        regVal |= DAC_FIELD_ENUM(HIFIDAC_CTRL,_CONFIG, MAPPER_MUTETYPE, Drive_0);
1328        break;
1329    case BAPE_DacMuteType_eDriveNegative1:
1330        regVal |= DAC_FIELD_ENUM(HIFIDAC_CTRL,_CONFIG, MAPPER_MUTETYPE, Drive_neg1);
1331        break;
1332    case BAPE_DacMuteType_eCustom:
1333        regVal |= DAC_FIELD_ENUM(HIFIDAC_CTRL,_CONFIG, MAPPER_MUTETYPE, Use_reg_val);
1334        {
1335            uint32_t  myRegAddr, myRegVal;
1336
1337            myRegAddr = GET_DAC_REG_ADDR3(BCHP_HIFIDAC_CTRL, handle->index, _DAC_CONST_VAL );
1338            myRegVal = BREG_Read32(handle->deviceHandle->regHandle, myRegAddr);
1339            myRegVal &= ~(DAC_MASK(HIFIDAC_CTRL,_DAC_CONST_VAL, LEFT)|DAC_MASK(HIFIDAC_CTRL,_DAC_CONST_VAL, RIGHT));
1340            myRegVal |= DAC_FIELD_DATA(HIFIDAC_CTRL,_DAC_CONST_VAL, LEFT, pSettings->customLeftValue);
1341            myRegVal |= DAC_FIELD_DATA(HIFIDAC_CTRL,_DAC_CONST_VAL, RIGHT, pSettings->customRightValue);
1342            BREG_Write32(handle->deviceHandle->regHandle, myRegAddr, myRegVal);
1343        }
1344        break;
1345    default:
1346        BDBG_ERR(("Invalid DAC mute type %d", pSettings->muteType));
1347        return BERR_TRACE(BERR_INVALID_PARAMETER);
1348    }
1349
1350    switch ( pSettings->stereoMode )
1351    {
1352    case BAPE_StereoMode_eLeftRight:
1353        regVal |= DAC_FIELD_ENUM(HIFIDAC_CTRL,_CONFIG, I2S_SELECT_LEFT, Left) | 
1354                  DAC_FIELD_ENUM(HIFIDAC_CTRL,_CONFIG, I2S_SELECT_RIGHT, Right);
1355        break;
1356    case BAPE_StereoMode_eLeftLeft:
1357        regVal |= DAC_FIELD_ENUM(HIFIDAC_CTRL,_CONFIG, I2S_SELECT_LEFT, Left) | 
1358                  DAC_FIELD_ENUM(HIFIDAC_CTRL,_CONFIG, I2S_SELECT_RIGHT, Left);
1359        break;
1360    case BAPE_StereoMode_eRightLeft:
1361        regVal |= DAC_FIELD_ENUM(HIFIDAC_CTRL,_CONFIG, I2S_SELECT_LEFT, Right) | 
1362                  DAC_FIELD_ENUM(HIFIDAC_CTRL,_CONFIG, I2S_SELECT_RIGHT, Left);
1363        break;
1364    case BAPE_StereoMode_eRightRight:
1365        regVal |= DAC_FIELD_ENUM(HIFIDAC_CTRL,_CONFIG, I2S_SELECT_LEFT, Right) | 
1366                  DAC_FIELD_ENUM(HIFIDAC_CTRL,_CONFIG, I2S_SELECT_RIGHT, Right);
1367        break;
1368    }
1369
1370    if ( (regVal != origRegVal) || force )
1371    {
1372        uint32_t  myRegAddr, myRegVal;
1373
1374        /* If the register is going to change, we need to mute first to avoid a pop */
1375        myRegAddr = GET_DAC_REG_ADDR3(BCHP_HIFIDAC_CTRL, handle->index, _DAC_VOLUME );
1376        myRegVal  = BREG_Read32(handle->deviceHandle->regHandle, myRegAddr);
1377        BREG_Write32(handle->deviceHandle->regHandle, myRegAddr, 0);
1378        BAPE_Dac_P_SyncVolume(handle);
1379
1380        /* write the new register and unmute */
1381        BREG_Write32(handle->deviceHandle->regHandle, regAddr, regVal);
1382        BREG_Write32(handle->deviceHandle->regHandle, myRegAddr, myRegVal);
1383    }
1384
1385    /* Update PEAK_GAIN if it has changed */
1386    if ( (handle->settings.peakGain != pSettings->peakGain && !handle->compressed) || force )
1387    {
1388        regAddr = GET_DAC_REG_ADDR3(BCHP_HIFIDAC_CTRL, handle->index, _PEAK_GAIN );
1389        regVal = BREG_Read32(handle->deviceHandle->regHandle, regAddr );
1390        regVal &= ~(DAC_MASK(HIFIDAC_CTRL,_PEAK_GAIN, PEAK_GAIN));
1391        regVal |= DAC_FIELD_DATA(HIFIDAC_CTRL,_PEAK_GAIN, PEAK_GAIN, pSettings->peakGain);
1392        BREG_Write32(handle->deviceHandle->regHandle, regAddr, regVal);
1393    }
1394
1395    /* Only do this if test tone settings have changed */
1396    if ( BAPE_Dac_P_ToneSettingsChanged(&handle->settings, pSettings) || force )
1397    {
1398        /* Setup the test tone if enabled */
1399        regAddr = GET_DAC_REG_ADDR3(BCHP_HIFIDAC_CTRL, handle->index, _TEST );
1400        regVal = BREG_Read32(handle->deviceHandle->regHandle, regAddr );
1401        if ( pSettings->testTone.enabled )
1402        {
1403            regVal &= ~(DAC_MASK(HIFIDAC_CTRL,_TEST, RAM_BUF_SEL)|
1404                        DAC_MASK(HIFIDAC_CTRL,_TEST, TESTTONE_LEFT)|
1405                        DAC_MASK(HIFIDAC_CTRL,_TEST, TESTTONE_RIGHT)|
1406                        DAC_MASK(HIFIDAC_CTRL,_TEST, TESTTONE_SHARE)|
1407                        DAC_MASK(HIFIDAC_CTRL,_TEST, TESTTONE_REPEAT_LEFT)|
1408                        DAC_MASK(HIFIDAC_CTRL,_TEST, TESTTONE_REPEAT_RIGHT)|
1409                        DAC_MASK(HIFIDAC_CTRL,_TEST, TESTTONE_ENABLE));
1410   
1411            /* Disable the test tone first if it's enabled */
1412            BREG_Write32(handle->deviceHandle->regHandle, regAddr, regVal);
1413   
1414            regVal |= DAC_FIELD_ENUM(HIFIDAC_CTRL,_TEST, RAM_BUF_SEL, Samples);
1415            regVal |= DAC_FIELD_ENUM(HIFIDAC_CTRL,_TEST, TESTTONE_ENABLE, Enable);
1416   
1417            if ( pSettings->testTone.zeroOnLeft )
1418                regVal |= DAC_FIELD_ENUM(HIFIDAC_CTRL,_TEST, TESTTONE_LEFT, Output_zero);
1419            else
1420                regVal |= DAC_FIELD_ENUM(HIFIDAC_CTRL,_TEST, TESTTONE_LEFT, Output_testtone);
1421   
1422            if ( pSettings->testTone.zeroOnRight )
1423                regVal |= DAC_FIELD_ENUM(HIFIDAC_CTRL,_TEST, TESTTONE_RIGHT, Output_zero);
1424            else
1425                regVal |= DAC_FIELD_ENUM(HIFIDAC_CTRL,_TEST, TESTTONE_RIGHT, Output_testtone);
1426   
1427            if ( pSettings->testTone.sharedSamples )
1428                regVal |= DAC_FIELD_ENUM(HIFIDAC_CTRL,_TEST, TESTTONE_SHARE, Share);
1429            else
1430                regVal |= DAC_FIELD_ENUM(HIFIDAC_CTRL,_TEST, TESTTONE_SHARE, Dont_share);
1431   
1432            regVal |= DAC_FIELD_DATA(HIFIDAC_CTRL,_TEST, TESTTONE_REPEAT_LEFT, pSettings->testTone.numSamplesLeft-1);
1433            regVal |= DAC_FIELD_DATA(HIFIDAC_CTRL,_TEST, TESTTONE_REPEAT_RIGHT, pSettings->testTone.numSamplesRight-1);
1434   
1435            /* Enable the tone */
1436            BREG_Write32(handle->deviceHandle->regHandle, regAddr, regVal);
1437   
1438            /* Load samples afterward */
1439            regAddr = GET_DAC_REG_ADDR3(BCHP_HIFIDAC_CTRL, handle->index, _TESTTONE_SAMPLE_i_ARRAY_BASE );
1440            for (   i =  GET_DAC_REG_ADDR3(BCHP_HIFIDAC_CTRL, handle->index, _TESTTONE_SAMPLE_i_ARRAY_START) ; 
1441                    i <= GET_DAC_REG_ADDR3(BCHP_HIFIDAC_CTRL, handle->index, _TESTTONE_SAMPLE_i_ARRAY_END)   ;
1442                    i++ )
1443            {
1444                BREG_Write32(handle->deviceHandle->regHandle, regAddr + (i*4),
1445                             pSettings->testTone.samples[i] & DAC_MASK(HIFIDAC_CTRL,_TESTTONE_SAMPLE_i, TESTTONE_SAMPLE));
1446            }
1447
1448            /* Un-Mute */
1449            BAPE_Dac_P_SetMute(&handle->outputPort, false, false);
1450        }
1451        else
1452        {
1453            if ( DAC_GET_FIELD_DATA(regVal, HIFIDAC_CTRL,_TEST, TESTTONE_ENABLE) )
1454            {
1455                if ( !handle->enabled )
1456                {
1457                    /* Mute */
1458                    BAPE_Dac_P_SetMute(&handle->outputPort, true, true);
1459                }
1460
1461                /* Clear sample buffer */
1462                regAddr = GET_DAC_REG_ADDR3(BCHP_HIFIDAC_CTRL, handle->index, _TESTTONE_SAMPLE_i_ARRAY_BASE );
1463                for (   i =  GET_DAC_REG_ADDR3(BCHP_HIFIDAC_CTRL, handle->index, _TESTTONE_SAMPLE_i_ARRAY_START) ; 
1464                        i <= GET_DAC_REG_ADDR3(BCHP_HIFIDAC_CTRL, handle->index, _TESTTONE_SAMPLE_i_ARRAY_END)   ;
1465                        i++ )
1466                {
1467                    BREG_Write32(handle->deviceHandle->regHandle, regAddr + (i*4), 0);
1468                }
1469
1470                regAddr = GET_DAC_REG_ADDR3(BCHP_HIFIDAC_CTRL, handle->index, _TEST );
1471                regVal &= ~DAC_MASK(HIFIDAC_CTRL,_TEST, TESTTONE_ENABLE);
1472                BREG_Write32(handle->deviceHandle->regHandle, regAddr, regVal);
1473                /* Set the rate manager back to the desired rate */
1474                BKNI_EnterCriticalSection();
1475                BAPE_Dac_P_SetRateManager_isr(handle, handle->sampleRate);
1476                BKNI_LeaveCriticalSection();
1477            }
1478        }
1479    }
1480
1481    handle->settings = *pSettings;
1482
1483    return BERR_SUCCESS;
1484}
1485
1486/**************************************************************************/
1487
1488
Note: See TracBrowser for help on using the repository browser.