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

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

first commit

  • Property svn:executable set to *
File size: 32.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_pll.c $
11 * $brcm_Revision: Hydra_Software_Devel/23 $
12 * $brcm_Date: 1/27/12 4:50p $
13 *
14 * Module Description: Audio Decoder Interface
15 *
16 * Revision History:
17 *
18 * $brcm_Log: /magnum/portinginterface/ape/7422/bape_pll.c $
19 *
20 * Hydra_Software_Devel/23   1/27/12 4:50p jgarrett
21 * SW7429-55: Updating MCLK of all connected outputs when a new mixer is
22 * attached
23 *
24 * Hydra_Software_Devel/22   12/1/11 3:15p jgarrett
25 * SW7429-18: Refactoring PLL values for 256fs to match macros
26 *
27 * Hydra_Software_Devel/21   11/30/11 7:15p jgarrett
28 * SW7429-18: Dividing PLL factors for 216MHz chips
29 *
30 * Hydra_Software_Devel/20   11/14/11 3:41p gskerl
31 * SW7429-18: Merging 7429 changes back to main branch.
32 *
33 * Hydra_Software_Devel/SW7429-18/3   10/26/11 12:44p jgarrett
34 * SW7429-18: Merging latest changes from main branch
35 *
36 * Hydra_Software_Devel/SW7429-18/2   10/25/11 11:15a jgarrett
37 * SW7429-18: Adding PLL support for 7429
38 *
39 * Hydra_Software_Devel/SW7429-18/1   10/21/11 6:29p jgarrett
40 * SW7429-18: Initial compileable version for 7429
41 *
42 * Hydra_Software_Devel/19   10/24/11 2:32p gskerl
43 * SW7231-129: Added support for recovering hardware state after power
44 * standby/resume.
45 *
46 * Hydra_Software_Devel/18   8/29/11 3:07p jgarrett
47 * SWDTV-8444: Clearing LOAD_ENx for DTV PLL's after setting new values
48 *
49 * Hydra_Software_Devel/17   7/14/11 4:33p gskerl
50 * SWDTV-7838: Added additional defines for the
51 * BCHP_##Register##_##Field##_MASK variant of some register fields
52 *
53 * Hydra_Software_Devel/16   7/8/11 6:37p jgarrett
54 * SWDTV-6305: Adding missing register write for AUDIO_MODE_SEL
55 *
56 * Hydra_Software_Devel/15   7/8/11 4:26p gskerl
57 * SW7552-72: Added support for NCO/Mclkgen audio clock sources
58 *
59 * Hydra_Software_Devel/14   7/7/11 4:35p jgarrett
60 * SWDTV-6305: Setting MODE_SEL for 352xx PLL implementations to user
61 * configurable
62 *
63 * Hydra_Software_Devel/13   6/16/11 3:05p gskerl
64 * SW7425-321: Renamed BAPE_PllStatus to BAPE_AudioPll, pllStatus to
65 * audioPll, eliminated unused baseAddress and fsChannel fields, added
66 * populating of baseSampleRate and freqCh1 fields.
67 *
68 * Hydra_Software_Devel/12   5/24/11 4:40p gskerl
69 * SW7425-321: Added support for mixers with different base sample rates
70 * sharing the same PLL
71 *
72 * Hydra_Software_Devel/11   4/20/11 7:01p gskerl
73 * SW7425-384: Refactored BAPE_P_SetFsTiming_isr() to improve PLLCLKSEL
74 * logic and to add support for multiple DACS
75 *
76 * Hydra_Software_Devel/10   4/18/11 11:23p gskerl
77 * SW7425-364: Fixed Coverity CID 399 (dead code)
78 *
79 * Hydra_Software_Devel/9   4/18/11 10:13p gskerl
80 * SW7425-364: Added BAPE_Pll_EnableExternalMclk() API to APE, then called
81 * it from NEXUS_AudioModule_EnableExternalMclk()
82 *
83 * Hydra_Software_Devel/8   4/16/11 12:15p jgarrett
84 * SW7425-371: Removing tab characters
85 *
86 * Hydra_Software_Devel/7   4/6/11 1:23a jgarrett
87 * SW35330-35: Merge to main branch
88 *
89 * Hydra_Software_Devel/SW35330-35/2   4/6/11 11:15a jgarrett
90 * SW35330-35: Adding 35233
91 *
92 * Hydra_Software_Devel/SW35330-35/1   4/5/11 7:13p jgarrett
93 * SW35330-35: PCM Playback working on 35230
94 *
95 * Hydra_Software_Devel/6   3/24/11 7:54p gskerl
96 * SW7422-146: Improved audio reference clock selection logic to handle
97 * RDB differences for the 7231
98 *
99 * Hydra_Software_Devel/5   3/22/11 3:00p gskerl
100 * SW7422-146: Changed audio output connector callbacks to take the output
101 * connector as an argument
102 *
103 * Hydra_Software_Devel/4   3/3/11 8:09p jgarrett
104 * SW7422-146: Fixing DDP passthrough sample rate issue
105 *
106 * Hydra_Software_Devel/3   2/10/11 5:44p gskerl
107 * SW7422-146: Refactored PLL code to support faster mclk rate of 256Fs
108 *
109 * Hydra_Software_Devel/2   12/17/10 3:58p jgarrett
110 * SW7422-146: Nexus APE integration on 7422
111 *
112 * Hydra_Software_Devel/1   12/16/10 4:05p jgarrett
113 * SW7422-146: Initial compilable APE for 7422
114 *
115 ***************************************************************************/
116
117#include "bstd.h"
118#include "bkni.h"
119#include "bape.h"
120#include "bape_priv.h"
121
122#if BCHP_CLKGEN_REG_START
123#include "bchp_clkgen.h"
124#endif
125
126BDBG_MODULE(bape_pll);
127static void BAPE_Pll_UpdateDividers_isr(BAPE_Handle handle, BAPE_Pll pll, uint32_t ndivInt, uint32_t MdivCh0, uint32_t MdivCh1, uint32_t MdivCh2);
128
129
130#if BCHP_AUD_FMM_PLL0_REG_START
131
132/* Code below is for non-DTV chips that use the standard PLL macros */
133
134#include "bchp_aud_fmm_pll0.h"
135#if BAPE_CHIP_MAX_PLLS > 1
136#include "bchp_aud_fmm_pll1.h"
137#define BAPE_PLL_STRIDE (BCHP_AUD_FMM_PLL1_MACRO-BCHP_AUD_FMM_PLL0_MACRO)
138#if BAPE_CHIP_MAX_PLLS > 2
139#include "bchp_aud_fmm_pll2.h"
140#endif
141#else
142#define BAPE_PLL_STRIDE 0
143#endif
144
145static void BAPE_Pll_UpdateDividers_isr(BAPE_Handle handle, BAPE_Pll pll, uint32_t ndivInt, uint32_t MdivCh0, uint32_t MdivCh1, uint32_t MdivCh2)
146{
147    uint32_t regAddr, regVal;
148   
149    /* AUD_FMM_PLL1_MACRO.MACRO_SELECT = User */
150    regAddr = BCHP_AUD_FMM_PLL0_MACRO + (BAPE_PLL_STRIDE * pll);
151    regVal = BREG_Read32(handle->regHandle, regAddr);
152    regVal &= ~BCHP_MASK(AUD_FMM_PLL0_MACRO, MACRO_SELECT);
153    regVal |= BCHP_FIELD_ENUM(AUD_FMM_PLL0_MACRO, MACRO_SELECT, User);
154    BREG_Write32(handle->regHandle, regAddr, regVal);
155   
156    /* AUD_FMM_PLL0_CONTROL_0.USER_UPDATE_DIVIDERS = 0 */
157    regAddr = BCHP_AUD_FMM_PLL0_CONTROL_0 + (BAPE_PLL_STRIDE * pll);
158    regVal = BREG_Read32(handle->regHandle, regAddr);
159    regVal &= ~BCHP_MASK(AUD_FMM_PLL0_CONTROL_0, USER_UPDATE_DIVIDERS);
160    BREG_Write32(handle->regHandle, regAddr, regVal);
161   
162    /* AUD_FMM_PLL0_USER_NDIV.NDIV_INT = ndivInt */
163    regAddr = BCHP_AUD_FMM_PLL0_USER_NDIV + (BAPE_PLL_STRIDE * pll);
164    regVal = BREG_Read32(handle->regHandle, regAddr);
165    regVal &= ~BCHP_MASK(AUD_FMM_PLL0_USER_NDIV, NDIV_INT);
166    regVal |= BCHP_FIELD_DATA(AUD_FMM_PLL0_USER_NDIV, NDIV_INT, ndivInt);
167    BREG_Write32(handle->regHandle, regAddr, regVal);
168   
169    /* AUD_FMM_PLL0_CONTROL_0.USER_UPDATE_DIVIDERS = 1 */
170    regAddr = BCHP_AUD_FMM_PLL0_CONTROL_0 + (BAPE_PLL_STRIDE * pll);
171    regVal = BREG_Read32(handle->regHandle, regAddr);
172    regVal &= ~BCHP_MASK(AUD_FMM_PLL0_CONTROL_0, USER_UPDATE_DIVIDERS);
173    regVal |= BCHP_FIELD_DATA(AUD_FMM_PLL0_CONTROL_0, USER_UPDATE_DIVIDERS, 1 );
174    BREG_Write32(handle->regHandle, regAddr, regVal);
175   
176   
177    /* AUD_FMM_PLL0_USER_MDIV_Ch0.MDIV = MdivCh0 */
178    regAddr = BCHP_AUD_FMM_PLL0_USER_MDIV_Ch0 + (BAPE_PLL_STRIDE * pll);
179    regVal = BREG_Read32(handle->regHandle, regAddr);
180    regVal &= ~BCHP_MASK(AUD_FMM_PLL0_USER_MDIV_Ch0, MDIV);
181    regVal |= BCHP_FIELD_DATA(AUD_FMM_PLL0_USER_MDIV_Ch0, MDIV, MdivCh0);
182    BREG_Write32(handle->regHandle, regAddr, regVal);
183   
184    /* AUD_FMM_PLL0_USER_MDIV_Ch0.LOAD_EN = 1 */
185    regAddr = BCHP_AUD_FMM_PLL0_USER_MDIV_Ch0 + (BAPE_PLL_STRIDE * pll);
186    regVal = BREG_Read32(handle->regHandle, regAddr);
187    regVal |= BCHP_FIELD_DATA(AUD_FMM_PLL0_USER_MDIV_Ch0, LOAD_EN, 1 );
188    BREG_Write32(handle->regHandle, regAddr, regVal);
189   
190    /* AUD_FMM_PLL0_USER_MDIV_Ch0.LOAD_EN = 0 */
191    regAddr = BCHP_AUD_FMM_PLL0_USER_MDIV_Ch0 + (BAPE_PLL_STRIDE * pll);
192    regVal = BREG_Read32(handle->regHandle, regAddr);
193    regVal &= ~BCHP_MASK(AUD_FMM_PLL0_USER_MDIV_Ch0, LOAD_EN);
194    BREG_Write32(handle->regHandle, regAddr, regVal);
195   
196   
197    /* AUD_FMM_PLL0_USER_MDIV_Ch1.MDIV = MdivCh1 */
198    regAddr = BCHP_AUD_FMM_PLL0_USER_MDIV_Ch1 + (BAPE_PLL_STRIDE * pll);
199    regVal = BREG_Read32(handle->regHandle, regAddr);
200    regVal &= ~BCHP_MASK(AUD_FMM_PLL0_USER_MDIV_Ch1, MDIV);
201    regVal |= BCHP_FIELD_DATA(AUD_FMM_PLL0_USER_MDIV_Ch1, MDIV, MdivCh1);
202    BREG_Write32(handle->regHandle, regAddr, regVal);
203   
204    /* AUD_FMM_PLL0_USER_MDIV_Ch1.LOAD_EN = 1 */
205    regAddr = BCHP_AUD_FMM_PLL0_USER_MDIV_Ch1 + (BAPE_PLL_STRIDE * pll);
206    regVal = BREG_Read32(handle->regHandle, regAddr);
207    regVal &= ~BCHP_MASK(AUD_FMM_PLL0_USER_MDIV_Ch1, LOAD_EN);
208    regVal |= BCHP_FIELD_DATA(AUD_FMM_PLL0_USER_MDIV_Ch1, LOAD_EN, 1 );
209    BREG_Write32(handle->regHandle, regAddr, regVal);
210   
211    /* AUD_FMM_PLL0_USER_MDIV_Ch1.LOAD_EN = 0 */
212    regAddr = BCHP_AUD_FMM_PLL0_USER_MDIV_Ch1 + (BAPE_PLL_STRIDE * pll);
213    regVal = BREG_Read32(handle->regHandle, regAddr);
214    regVal &= ~BCHP_MASK(AUD_FMM_PLL0_USER_MDIV_Ch1, LOAD_EN);
215    BREG_Write32(handle->regHandle, regAddr, regVal);
216   
217   
218    /* AUD_FMM_PLL0_USER_MDIV_Ch2.MDIV = MdivCh2 */
219    regAddr = BCHP_AUD_FMM_PLL0_USER_MDIV_Ch2 + (BAPE_PLL_STRIDE * pll);
220    regVal = BREG_Read32(handle->regHandle, regAddr);
221    regVal &= ~BCHP_MASK(AUD_FMM_PLL0_USER_MDIV_Ch2, MDIV);
222    regVal |= BCHP_FIELD_DATA(AUD_FMM_PLL0_USER_MDIV_Ch2, MDIV, MdivCh2);
223    BREG_Write32(handle->regHandle, regAddr, regVal);
224   
225    /* AUD_FMM_PLL0_USER_MDIV_Ch2.LOAD_EN = 1 */
226    regAddr = BCHP_AUD_FMM_PLL0_USER_MDIV_Ch2 + (BAPE_PLL_STRIDE * pll);
227    regVal = BREG_Read32(handle->regHandle, regAddr);
228    regVal &= ~BCHP_MASK(AUD_FMM_PLL0_USER_MDIV_Ch2, LOAD_EN);
229    regVal |= BCHP_FIELD_DATA(AUD_FMM_PLL0_USER_MDIV_Ch2, LOAD_EN, 1 );
230    BREG_Write32(handle->regHandle, regAddr, regVal);
231   
232    /* AUD_FMM_PLL0_USER_MDIV_Ch2.LOAD_EN = 0 */
233    regAddr = BCHP_AUD_FMM_PLL0_USER_MDIV_Ch2 + (BAPE_PLL_STRIDE * pll);
234    regVal = BREG_Read32(handle->regHandle, regAddr);
235    regVal &= ~BCHP_MASK(AUD_FMM_PLL0_USER_MDIV_Ch2, LOAD_EN);
236    BREG_Write32(handle->regHandle, regAddr, regVal);
237}
238
239#else
240
241#include "bchp_aud_fmm_iop_pll_0.h"
242
243#ifdef BCHP_AUD_FMM_IOP_PLL_1_REG_START
244#include "bchp_aud_fmm_iop_pll_1.h"
245#define BAPE_PLL_STRIDE (BCHP_AUD_FMM_IOP_PLL_1_REG_START-BCHP_AUD_FMM_IOP_PLL_0_REG_START)
246#else
247#define BAPE_PLL_STRIDE 0
248#endif
249
250static void BAPE_Pll_UpdateDividers_isr(BAPE_Handle handle, BAPE_Pll pll, uint32_t ndivInt, uint32_t MdivCh0, uint32_t MdivCh1, uint32_t MdivCh2)
251{
252    uint32_t regAddr, regVal;
253   
254    /* AUD_FMM_PLL1_MACRO.MACRO_SELECT = User */
255    regAddr = BCHP_AUD_FMM_IOP_PLL_0_MACRO + (BAPE_PLL_STRIDE * pll);
256    regVal = BREG_Read32(handle->regHandle, regAddr);
257    regVal &= ~BCHP_MASK(AUD_FMM_IOP_PLL_0_MACRO, MACRO_SELECT);
258    regVal |= BCHP_FIELD_ENUM(AUD_FMM_IOP_PLL_0_MACRO, MACRO_SELECT, User);
259    BREG_Write32(handle->regHandle, regAddr, regVal);
260
261    /* AUD_FMM_IOP_PLL_0_CONTROL_0.USER_UPDATE_DIVIDERS = 0 */
262    regAddr = BCHP_AUD_FMM_IOP_PLL_0_CONTROL_0 + (BAPE_PLL_STRIDE * pll);
263    regVal = BREG_Read32(handle->regHandle, regAddr);
264    regVal &= ~BCHP_MASK(AUD_FMM_IOP_PLL_0_CONTROL_0, USER_UPDATE_DIVIDERS);
265    BREG_Write32(handle->regHandle, regAddr, regVal);
266
267    /* AUD_FMM_IOP_PLL_0_USER_NDIV.NDIV_INT = ndivInt */
268    regAddr = BCHP_AUD_FMM_IOP_PLL_0_USER_NDIV + (BAPE_PLL_STRIDE * pll);
269    regVal = BREG_Read32(handle->regHandle, regAddr);
270    regVal &= ~BCHP_MASK(AUD_FMM_IOP_PLL_0_USER_NDIV, NDIV_INT);
271    regVal |= BCHP_FIELD_DATA(AUD_FMM_IOP_PLL_0_USER_NDIV, NDIV_INT, ndivInt);
272    BREG_Write32(handle->regHandle, regAddr, regVal);
273
274    /* AUD_FMM_IOP_PLL_0_CONTROL_0.USER_UPDATE_DIVIDERS = 1 */
275    regAddr = BCHP_AUD_FMM_IOP_PLL_0_CONTROL_0 + (BAPE_PLL_STRIDE * pll);
276    regVal = BREG_Read32(handle->regHandle, regAddr);
277    regVal &= ~BCHP_MASK(AUD_FMM_IOP_PLL_0_CONTROL_0, USER_UPDATE_DIVIDERS);
278    regVal |= BCHP_FIELD_DATA(AUD_FMM_IOP_PLL_0_CONTROL_0, USER_UPDATE_DIVIDERS, 1 );
279    BREG_Write32(handle->regHandle, regAddr, regVal);
280
281
282    /* AUD_FMM_IOP_PLL_0_USER_MDIV_Ch0.MDIV = MdivCh0 */
283    regAddr = BCHP_AUD_FMM_IOP_PLL_0_USER_MDIV_Ch0 + (BAPE_PLL_STRIDE * pll);
284    regVal = BREG_Read32(handle->regHandle, regAddr);
285    regVal &= ~BCHP_MASK(AUD_FMM_IOP_PLL_0_USER_MDIV_Ch0, MDIV);
286    regVal |= BCHP_FIELD_DATA(AUD_FMM_IOP_PLL_0_USER_MDIV_Ch0, MDIV, MdivCh0);
287    BREG_Write32(handle->regHandle, regAddr, regVal);
288
289    /* AUD_FMM_IOP_PLL_0_USER_MDIV_Ch0.LOAD_EN = 1 */
290    regAddr = BCHP_AUD_FMM_IOP_PLL_0_USER_MDIV_Ch0 + (BAPE_PLL_STRIDE * pll);
291    regVal = BREG_Read32(handle->regHandle, regAddr);
292    regVal |= BCHP_FIELD_DATA(AUD_FMM_IOP_PLL_0_USER_MDIV_Ch0, LOAD_EN, 1 );
293    BREG_Write32(handle->regHandle, regAddr, regVal);
294
295    /* AUD_FMM_IOP_PLL_0_USER_MDIV_Ch0.LOAD_EN = 0 */
296    regAddr = BCHP_AUD_FMM_IOP_PLL_0_USER_MDIV_Ch0 + (BAPE_PLL_STRIDE * pll);
297    regVal = BREG_Read32(handle->regHandle, regAddr);
298    regVal &= ~BCHP_MASK(AUD_FMM_IOP_PLL_0_USER_MDIV_Ch0, LOAD_EN);
299    BREG_Write32(handle->regHandle, regAddr, regVal);
300
301
302    /* AUD_FMM_IOP_PLL_0_USER_MDIV_Ch1.MDIV = MdivCh1 */
303    regAddr = BCHP_AUD_FMM_IOP_PLL_0_USER_MDIV_Ch1 + (BAPE_PLL_STRIDE * pll);
304    regVal = BREG_Read32(handle->regHandle, regAddr);
305    regVal &= ~BCHP_MASK(AUD_FMM_IOP_PLL_0_USER_MDIV_Ch1, MDIV);
306    regVal |= BCHP_FIELD_DATA(AUD_FMM_IOP_PLL_0_USER_MDIV_Ch1, MDIV, MdivCh1);
307    BREG_Write32(handle->regHandle, regAddr, regVal);
308
309    /* AUD_FMM_IOP_PLL_0_USER_MDIV_Ch1.LOAD_EN = 1 */
310    regAddr = BCHP_AUD_FMM_IOP_PLL_0_USER_MDIV_Ch1 + (BAPE_PLL_STRIDE * pll);
311    regVal = BREG_Read32(handle->regHandle, regAddr);
312    regVal &= ~BCHP_MASK(AUD_FMM_IOP_PLL_0_USER_MDIV_Ch1, LOAD_EN);
313    regVal |= BCHP_FIELD_DATA(AUD_FMM_IOP_PLL_0_USER_MDIV_Ch1, LOAD_EN, 1 );
314    BREG_Write32(handle->regHandle, regAddr, regVal);
315
316    /* AUD_FMM_IOP_PLL_0_USER_MDIV_Ch1.LOAD_EN = 0 */
317    regAddr = BCHP_AUD_FMM_IOP_PLL_0_USER_MDIV_Ch1 + (BAPE_PLL_STRIDE * pll);
318    regVal = BREG_Read32(handle->regHandle, regAddr);
319    regVal &= ~BCHP_MASK(AUD_FMM_IOP_PLL_0_USER_MDIV_Ch1, LOAD_EN);
320    BREG_Write32(handle->regHandle, regAddr, regVal);
321
322
323    /* AUD_FMM_IOP_PLL_0_USER_MDIV_Ch2.MDIV = MdivCh2 */
324    regAddr = BCHP_AUD_FMM_IOP_PLL_0_USER_MDIV_Ch2 + (BAPE_PLL_STRIDE * pll);
325    regVal = BREG_Read32(handle->regHandle, regAddr);
326    regVal &= ~BCHP_MASK(AUD_FMM_IOP_PLL_0_USER_MDIV_Ch2, MDIV);
327    regVal |= BCHP_FIELD_DATA(AUD_FMM_IOP_PLL_0_USER_MDIV_Ch2, MDIV, MdivCh2);
328    BREG_Write32(handle->regHandle, regAddr, regVal);
329
330    /* AUD_FMM_IOP_PLL_0_USER_MDIV_Ch2.LOAD_EN = 1 */
331    regAddr = BCHP_AUD_FMM_IOP_PLL_0_USER_MDIV_Ch2 + (BAPE_PLL_STRIDE * pll);
332    regVal = BREG_Read32(handle->regHandle, regAddr);
333    regVal &= ~BCHP_MASK(AUD_FMM_IOP_PLL_0_USER_MDIV_Ch2, LOAD_EN);
334    regVal |= BCHP_FIELD_DATA(AUD_FMM_IOP_PLL_0_USER_MDIV_Ch2, LOAD_EN, 1 );
335    BREG_Write32(handle->regHandle, regAddr, regVal);
336
337    /* AUD_FMM_IOP_PLL_0_USER_MDIV_Ch2.LOAD_EN = 0 */
338    regAddr = BCHP_AUD_FMM_IOP_PLL_0_USER_MDIV_Ch2 + (BAPE_PLL_STRIDE * pll);
339    regVal = BREG_Read32(handle->regHandle, regAddr);
340    regVal &= ~BCHP_MASK(AUD_FMM_IOP_PLL_0_USER_MDIV_Ch2, LOAD_EN);
341    BREG_Write32(handle->regHandle, regAddr, regVal);
342}
343#endif
344
345/* Common code */
346void BAPE_Pll_GetSettings(
347    BAPE_Handle handle,
348    BAPE_Pll pll,
349    BAPE_PllSettings *pSettings /* [out] */
350    )
351{
352    BDBG_OBJECT_ASSERT(handle, BAPE_Device);
353    BDBG_ASSERT(pll < BAPE_CHIP_MAX_PLLS);
354    *pSettings = handle->audioPlls[pll].settings;
355}
356
357BERR_Code BAPE_Pll_SetSettings(
358    BAPE_Handle handle,
359    BAPE_Pll pll,
360    const BAPE_PllSettings *pSettings
361    )
362{
363    uint32_t regVal, regAddr, data;
364
365    BDBG_OBJECT_ASSERT(handle, BAPE_Device);
366    BDBG_ASSERT(pll < BAPE_CHIP_MAX_PLLS);
367    BDBG_ASSERT(NULL != pSettings);
368    handle->audioPlls[pll].settings = *pSettings;
369
370#ifdef BCHP_CLKGEN_INTERNAL_MUX_SELECT
371    if ( pSettings->freeRun )
372    {
373        #ifdef BCHP_CLKGEN_INTERNAL_MUX_SELECT_PLLAUDIO0_REFERENCE_CLOCK_Fixed
374            data = BCHP_CLKGEN_INTERNAL_MUX_SELECT_PLLAUDIO0_REFERENCE_CLOCK_Fixed;
375        #else
376            BDBG_ERR(("Can't use fixed reference clock for audio"));
377            return BERR_TRACE(BERR_NOT_SUPPORTED);
378        #endif
379    }
380    else
381    {
382        /* VCXO source */
383        switch (pSettings->vcxo)
384        {
385        #ifdef BCHP_CLKGEN_INTERNAL_MUX_SELECT_PLLAUDIO0_REFERENCE_CLOCK_Vcxo0
386        case 0:
387            data = BCHP_CLKGEN_INTERNAL_MUX_SELECT_PLLAUDIO0_REFERENCE_CLOCK_Vcxo0;
388            break;
389        #endif
390
391        #ifdef BCHP_CLKGEN_INTERNAL_MUX_SELECT_PLLAUDIO0_REFERENCE_CLOCK_Vcxo1
392        case 1:
393            data = BCHP_CLKGEN_INTERNAL_MUX_SELECT_PLLAUDIO0_REFERENCE_CLOCK_Vcxo1;
394            break;
395        #endif
396
397        #ifdef BCHP_CLKGEN_INTERNAL_MUX_SELECT_PLLAUDIO0_REFERENCE_CLOCK_Vcxo2
398        case 2:
399            data = BCHP_CLKGEN_INTERNAL_MUX_SELECT_PLLAUDIO0_REFERENCE_CLOCK_Vcxo2;
400            break;
401        #endif
402
403        #ifdef BCHP_CLKGEN_INTERNAL_MUX_SELECT_PLLAUDIO0_REFERENCE_CLOCK_Vcxo3
404        case 3:
405            data = BCHP_CLKGEN_INTERNAL_MUX_SELECT_PLLAUDIO0_REFERENCE_CLOCK_Vcxo3;
406            break;
407        #endif
408
409        default:
410            BDBG_ERR(("Invalid or unsupported audio VCXO: %u", pSettings->vcxo));
411            return BERR_TRACE(BERR_INVALID_PARAMETER);
412        }
413    }
414
415    BKNI_EnterCriticalSection();
416    regAddr = BCHP_CLKGEN_INTERNAL_MUX_SELECT;
417    regVal = BREG_Read32_isr(handle->regHandle, regAddr);
418    switch ( pll )
419    {
420    case BAPE_Pll_e0:
421        regVal &= ~BCHP_MASK(CLKGEN_INTERNAL_MUX_SELECT, PLLAUDIO0_REFERENCE_CLOCK);
422        regVal |=  BCHP_FIELD_DATA(CLKGEN_INTERNAL_MUX_SELECT, PLLAUDIO0_REFERENCE_CLOCK, data);
423        break;
424#ifdef BCHP_CLKGEN_INTERNAL_MUX_SELECT_PLLAUDIO1_REFERENCE_CLOCK_SHIFT
425    case BAPE_Pll_e1:
426        regVal &= ~BCHP_MASK(CLKGEN_INTERNAL_MUX_SELECT, PLLAUDIO1_REFERENCE_CLOCK);
427        regVal |=  BCHP_FIELD_DATA(CLKGEN_INTERNAL_MUX_SELECT, PLLAUDIO1_REFERENCE_CLOCK, data);
428        break;
429#endif
430#ifdef BCHP_CLKGEN_INTERNAL_MUX_SELECT_PLLAUDIO2_REFERENCE_CLOCK_SHIFT
431    case BAPE_Pll_e2:
432        regVal &= ~BCHP_MASK(CLKGEN_INTERNAL_MUX_SELECT, PLLAUDIO2_REFERENCE_CLOCK);
433        regVal |=  BCHP_FIELD_DATA(CLKGEN_INTERNAL_MUX_SELECT, PLLAUDIO2_REFERENCE_CLOCK, data);
434        break;
435#endif
436    default:
437        break;
438    }
439    BREG_Write32_isr(handle->regHandle, regAddr, regVal);
440    BKNI_LeaveCriticalSection();
441#endif
442
443    return BERR_SUCCESS;
444}
445
446void BAPE_P_AttachMixerToPll(BAPE_MixerHandle mixer, BAPE_Pll pll)
447{
448    BDBG_OBJECT_ASSERT(mixer, BAPE_Mixer);
449    BDBG_ASSERT(pll < BAPE_CHIP_MAX_PLLS);
450    BLST_S_INSERT_HEAD(&mixer->deviceHandle->audioPlls[pll].mixerList, mixer, pllNode);
451    /* Update MCLK source for attached outputs */
452    BKNI_EnterCriticalSection();
453    BAPE_P_UpdatePll_isr(mixer->deviceHandle, pll);
454    BKNI_LeaveCriticalSection();
455}
456
457void BAPE_P_DetachMixerFromPll(BAPE_MixerHandle mixer, BAPE_Pll pll)
458{
459    BDBG_OBJECT_ASSERT(mixer, BAPE_Mixer);
460    BDBG_ASSERT(pll < BAPE_CHIP_MAX_PLLS);
461    BLST_S_REMOVE(&mixer->deviceHandle->audioPlls[pll].mixerList, mixer, BAPE_Mixer, pllNode);
462}
463
464static BERR_Code BAPE_P_GetPllBaseSampleRate_isr(unsigned sampleRate, unsigned *pBaseRate)
465{
466    switch ( sampleRate )
467    {
468    case 32000:    /* 32K Sample rate */
469    case 64000:      /* 64K Sample rate */
470    case 128000:     /* 128K Sample rate */
471        *pBaseRate = 32000;
472        return BERR_SUCCESS;
473    case 44100:    /* 44.1K Sample rate */
474    case 88200:    /* 88.2K Sample rate */
475    case 176400:   /* 176.4K Sample rate */
476        *pBaseRate = 44100;
477        return BERR_SUCCESS;
478    case 48000:      /* 48K Sample rate */
479    case 96000:      /* 96K Sample rate */
480    case 192000:     /* 192K Sample rate */
481        *pBaseRate = 48000;
482        return BERR_SUCCESS;
483    default:
484        BDBG_ERR(("Invalid sampling rate %u", sampleRate));
485        *pBaseRate = 0;
486        return BERR_TRACE(BERR_INVALID_PARAMETER);
487    }
488}
489
490static BERR_Code BAPE_P_SetPllFreq_isr( BAPE_Handle handle, BAPE_Pll pll, unsigned baseRate )
491{
492    int i;
493
494    struct pllInfo {
495            unsigned baseFs; long freqCh1; long ndivInt; int MdivCh0; int MdivCh1; int MdivCh2;
496    } pllInfo[] = 
497    {
498        #if BAPE_BASE_PLL_TO_FS_RATIO == 128    /* Run PLL Ch0 at 128 BaseFS */
499            {  32000,               4096000,         64,          180,          180,       90 },
500            {  44100,               5644800,         49,          100,          100,       50 }, 
501            {  48000,               6144000,         64,          120,          120,       60 }, 
502   
503        #elif BAPE_BASE_PLL_TO_FS_RATIO == 256  /* Run PLL Ch0 at 256 BaseFS */
504            {  32000,               8192000,         64,           90,           90,       45 },
505            {  44100,              11289600,         49,           50,           50,       25 }, 
506            {  48000,              12288000,         64,           60,           60,       30 }, 
507   
508        #elif BAPE_BASE_PLL_TO_FS_RATIO == 512  /* Run PLL Ch0 at 512 BaseFS */
509            {  32000,              16384000,        128,           90,           90,       45 },
510            {  44100,              22579200,         98,           50,           50,       25 }, 
511            {  48000,              24576000,        128,           60,           60,       30 }
512        #else
513            #error "BAPE_BASE_PLL_TO_FS_RATIO is invalid or not defined"
514        #endif
515    };
516    int numElems = sizeof pllInfo/sizeof pllInfo[0];
517
518    for ( i=0 ; i<numElems ; i++  )
519    {
520        if ( pllInfo[i].baseFs ==  baseRate )
521        {
522            break;
523        }
524    }
525
526    if ( i >= numElems )
527    {
528        BDBG_ERR(("Invalid sampling rate %u", baseRate));
529        return BERR_TRACE(BERR_INVALID_PARAMETER);
530    }
531
532    BDBG_ASSERT(pllInfo[i].baseFs ==  baseRate);
533
534    BDBG_MSG(("Setting PLL %u frequency to %u Hz (%u * BaseFs)", pll,  pllInfo[i].freqCh1, BAPE_BASE_PLL_TO_FS_RATIO));
535
536    BAPE_Pll_UpdateDividers_isr(handle, pll, pllInfo[i].ndivInt, pllInfo[i].MdivCh0, pllInfo[i].MdivCh1, pllInfo[i].MdivCh2);
537    handle->audioPlls[pll].baseSampleRate   = baseRate;
538    handle->audioPlls[pll].freqCh1          = pllInfo[i].freqCh1;
539
540    return BERR_SUCCESS;
541}
542
543BERR_Code BAPE_P_UpdatePll_isr(BAPE_Handle handle, BAPE_Pll pll)
544{
545    unsigned baseRate = 0;
546    unsigned idleRate = 0;
547    BAPE_Mixer *pMixer;
548    BERR_Code errCode;
549
550    BDBG_OBJECT_ASSERT(handle, BAPE_Device);
551    BDBG_ASSERT(pll < BAPE_CHIP_MAX_PLLS);
552
553    /* Walk through each mixer and make sure we have no conflicts */
554    for ( pMixer = BLST_S_FIRST(&handle->audioPlls[pll].mixerList);
555          pMixer != NULL;
556          pMixer = BLST_S_NEXT(pMixer, pllNode) )
557    {
558        unsigned mixerRate;
559
560        if ( pMixer->sampleRate == 0 )
561        {
562            continue;
563        }
564
565        errCode = BAPE_P_GetPllBaseSampleRate_isr(pMixer->sampleRate, &mixerRate);
566        if ( errCode )
567        {
568            return BERR_TRACE(errCode);
569        }
570        if ( pMixer->running )
571        {
572            if ( baseRate == 0 )
573            {
574                baseRate = mixerRate;
575            }
576            else if ( baseRate != mixerRate )
577            {
578                BDBG_WRN(("Sample rate conflict on PLL %d.  One mixer requests %u another requests %u", pll, baseRate, mixerRate));
579            }
580        }
581        else if ( idleRate == 0 )
582        {
583            idleRate = mixerRate;
584        }
585    }
586
587    if ( baseRate == 0 )
588    {
589        baseRate = idleRate;
590    }
591
592    if ( baseRate != 0 )
593    {
594        BDBG_MSG(("Updating PLL %u for base sample rate of %u Hz", pll, baseRate));
595
596        errCode = BAPE_P_SetPllFreq_isr( handle, pll, baseRate );
597        if ( errCode )  return BERR_TRACE(errCode);
598
599        /* For each output, set it's mclk appropriately */
600        for ( pMixer = BLST_S_FIRST(&handle->audioPlls[pll].mixerList);
601              pMixer != NULL;
602              pMixer = BLST_S_NEXT(pMixer, pllNode) )
603        {
604            BAPE_OutputPort output;
605            unsigned rateNum = pMixer->sampleRate;
606            unsigned pllChan;
607            BAPE_MclkSource mclkSource;
608
609            BDBG_ASSERT( BAPE_MCLKSOURCE_IS_PLL(pMixer->mclkSource));
610
611            if ( pMixer->sampleRate == 0 )
612            {
613                /* Skip this mixer if it doesn't have a sample rate yet */
614                continue;
615            }
616
617            switch ( pll )
618            {
619            default:
620            case BAPE_Pll_e0:
621                mclkSource = BAPE_MclkSource_ePll0;
622                break;
623            case BAPE_Pll_e1:
624                mclkSource = BAPE_MclkSource_ePll1;
625                break;
626            case BAPE_Pll_e2:
627                mclkSource = BAPE_MclkSource_ePll2;
628                break;
629            }
630            BDBG_ASSERT( mclkSource == pMixer->mclkSource);
631
632            pllChan =  rateNum  <= 48000 ? 0 :        /* Channel 0 runs at 32 KHz, 44.1 KHz, or 48 KHz    */
633                       rateNum  <= 96000 ? 1 :        /* Channel 1 runs at 64 KHz, 88.2 KHz, or 96 KHz    */
634                                           2 ;        /* Channel 2 runs at 128 KHz, 176.4 KHz, or 192 KHz */
635                                                             
636            for ( output = BLST_S_FIRST(&pMixer->outputList);
637                  output != NULL;
638                  output = BLST_S_NEXT(output, node) )
639            {
640                if ( output->setMclk_isr )
641                {
642                    BDBG_MSG(("Setting output mclk for '%s' to source:%s channel:%u ratio:%u",
643                               output->pName, BAPE_Mixer_P_MclkSourceToText(mclkSource), pllChan, BAPE_BASE_PLL_TO_FS_RATIO));
644                    output->setMclk_isr(output, mclkSource, pllChan, BAPE_BASE_PLL_TO_FS_RATIO);
645                }
646            }
647
648            if ( pMixer->fs != BAPE_FS_INVALID )
649            {
650                BDBG_MSG(("Setting FS mclk for FS %u to source:%s ratio:%u",
651                           pMixer->fs, BAPE_Mixer_P_MclkSourceToText(mclkSource), BAPE_BASE_PLL_TO_FS_RATIO));
652                BAPE_P_SetFsTiming_isr(handle, pMixer->fs, mclkSource, pllChan, BAPE_BASE_PLL_TO_FS_RATIO);
653            }
654        }
655    }
656    else
657    {
658        BDBG_MSG(("Not updating PLL %u rate (unknown)", pll));
659    }
660
661    return BERR_SUCCESS;
662}
663
664
665
666BERR_Code BAPE_Pll_EnableExternalMclk(
667    BAPE_Handle     handle,
668    BAPE_Pll        pll,
669    unsigned        mclkIndex,
670    BAPE_MclkRate   mclkRate
671    )
672{
673    unsigned            pllChannel;
674    unsigned            pll0ToBaseFsRatio;   
675    unsigned            requestedPllToBaseFsRatio;
676    uint32_t            pllclksel;
677    uint32_t            regAddr;
678    uint32_t            regVal;
679
680    BDBG_OBJECT_ASSERT(handle, BAPE_Device);
681    BDBG_ASSERT(pll < BAPE_CHIP_MAX_PLLS);
682    BDBG_ASSERT(mclkIndex < BAPE_CHIP_MAX_EXT_MCLKS);
683
684    pll0ToBaseFsRatio = BAPE_BASE_PLL_TO_FS_RATIO;
685
686    switch (mclkRate)
687    {
688    case BAPE_MclkRate_e128Fs:
689        requestedPllToBaseFsRatio = 128;
690        break;
691
692    case BAPE_MclkRate_e256Fs:
693        requestedPllToBaseFsRatio = 256;
694        break;
695
696    case BAPE_MclkRate_e384Fs:
697        requestedPllToBaseFsRatio = 384;
698        break;
699
700    case BAPE_MclkRate_e512Fs:
701        requestedPllToBaseFsRatio = 512;
702        break;
703
704    default:
705        BDBG_ERR(("Requested mclkRate is invalid"));
706        return(BERR_TRACE(BERR_INVALID_PARAMETER));
707    }
708   
709    if (requestedPllToBaseFsRatio == pll0ToBaseFsRatio)
710    {
711        pllChannel = 0;
712    }
713    else if (requestedPllToBaseFsRatio == 2 * pll0ToBaseFsRatio)
714    {
715        pllChannel = 1;
716    }
717#if BAPE_BASE_PLL_TO_FS_RATIO < 256
718    else if (requestedPllToBaseFsRatio == 4 * pll0ToBaseFsRatio)
719    {
720        pllChannel = 2;
721    }
722#endif
723    else
724    {
725        BDBG_ERR(("Requested mclkRate:%dFs is invalid", requestedPllToBaseFsRatio));
726        if ( requestedPllToBaseFsRatio < pll0ToBaseFsRatio )
727        {
728            BDBG_ERR(("Current minimum MCLK rate is %dFs... you may need to reduce BAPE_BASE_PLL_TO_FS_RATIO", pll0ToBaseFsRatio ));
729        }
730        return(BERR_TRACE(BERR_INVALID_PARAMETER));
731    }
732           
733#if defined BCHP_AUD_FMM_OP_CTRL_MCLK_CFG_EXTi_ARRAY_BASE
734    switch ( pll )
735    {
736    /* PLL Timing */
737    #if BAPE_CHIP_MAX_PLLS > 0
738    case BAPE_Pll_e0:
739        pllclksel = BCHP_AUD_FMM_OP_CTRL_MCLK_CFG_EXTi_PLLCLKSEL_PLL0_ch1 + pllChannel;
740        break;
741    #endif
742    #if BAPE_CHIP_MAX_PLLS > 1
743    case BAPE_Pll_e1:
744        pllclksel = BCHP_AUD_FMM_OP_CTRL_MCLK_CFG_EXTi_PLLCLKSEL_PLL1_ch1 + pllChannel;
745        break;
746    #endif
747    #if BAPE_CHIP_MAX_PLLS > 2
748    case BAPE_Pll_e2:
749        pllclksel = BCHP_AUD_FMM_OP_CTRL_MCLK_CFG_EXTi_PLLCLKSEL_PLL2_ch1 + pllChannel;
750        break;
751    #endif
752    #if BAPE_CHIP_MAX_PLLS > 3
753    case BAPE_Pll_e3:
754        pllclksel = BCHP_AUD_FMM_OP_CTRL_MCLK_CFG_EXTi_PLLCLKSEL_PLL3_ch1 + pllChannel;
755        break;
756    #endif
757    #if BAPE_CHIP_MAX_PLLS > 4
758        #error "Need to add support for more PLLs"
759    #endif
760   
761    /* Should never get here */
762    default:
763        BDBG_ERR(("PLL is invalid"));
764        BDBG_ASSERT(false);     /* something went wrong somewhere! */
765        return(BERR_INVALID_PARAMETER);
766    }
767
768    /* Read the register. */
769    regAddr = BCHP_AUD_FMM_OP_CTRL_MCLK_CFG_EXTi_ARRAY_BASE + ((BCHP_AUD_FMM_OP_CTRL_MCLK_CFG_EXTi_ARRAY_ELEMENT_SIZE * mclkIndex)/8);
770    regVal = BREG_Read32(handle->regHandle, regAddr);
771
772    /* Clear the field that we're going to fill in. */
773    regVal &= ~(BCHP_MASK(AUD_FMM_OP_CTRL_MCLK_CFG_EXTi, PLLCLKSEL));
774
775    /* Fill in the PLLCLKSEL field. */
776    regVal |= BCHP_FIELD_DATA(AUD_FMM_OP_CTRL_MCLK_CFG_EXTi, PLLCLKSEL, pllclksel);
777
778    BREG_Write32(handle->regHandle, regAddr, regVal);
779
780#elif defined BCHP_AUD_FMM_IOP_MISC_MCLK_CFG_i_ARRAY_BASE
781    BSTD_UNUSED(regVal);
782    BSTD_UNUSED(pllclksel);
783    {
784        BAPE_Reg_P_FieldList regFieldList;
785
786        regAddr = BAPE_Reg_P_GetArrayAddress(AUD_FMM_IOP_MISC_MCLK_CFG_i, mclkIndex);
787        BAPE_Reg_P_InitFieldList(handle, &regFieldList);
788        switch ( pll ) 
789        {
790    #if BAPE_CHIP_MAX_PLLS > 0
791    case BAPE_Pll_e0:
792        switch ( pllChannel )
793        {
794        case 0: BAPE_Reg_P_AddEnumToFieldList(&regFieldList, AUD_FMM_IOP_MISC_MCLK_CFG_i, PLLCLKSEL, PLL0_ch1); break;
795        case 1: BAPE_Reg_P_AddEnumToFieldList(&regFieldList, AUD_FMM_IOP_MISC_MCLK_CFG_i, PLLCLKSEL, PLL0_ch2); break;
796        case 2: BAPE_Reg_P_AddEnumToFieldList(&regFieldList, AUD_FMM_IOP_MISC_MCLK_CFG_i, PLLCLKSEL, PLL0_ch3); break;
797        default: return BERR_TRACE(BERR_NOT_SUPPORTED);
798        }
799        break;
800    #endif
801    #if BAPE_CHIP_MAX_PLLS > 1
802    case BAPE_Pll_e1:
803        switch ( pllChannel )
804        {
805        case 0: BAPE_Reg_P_AddEnumToFieldList(&regFieldList, AUD_FMM_IOP_MISC_MCLK_CFG_i, PLLCLKSEL, PLL1_ch1); break;
806        case 1: BAPE_Reg_P_AddEnumToFieldList(&regFieldList, AUD_FMM_IOP_MISC_MCLK_CFG_i, PLLCLKSEL, PLL1_ch2); break;
807        case 2: BAPE_Reg_P_AddEnumToFieldList(&regFieldList, AUD_FMM_IOP_MISC_MCLK_CFG_i, PLLCLKSEL, PLL1_ch3); break;
808        default: return BERR_TRACE(BERR_NOT_SUPPORTED);
809        }
810        break;
811    #endif
812    #if BAPE_CHIP_MAX_PLLS > 2
813    case BAPE_Pll_e2:
814        switch ( pllChannel )
815        {
816        case 0: BAPE_Reg_P_AddEnumToFieldList(&regFieldList, AUD_FMM_IOP_MISC_MCLK_CFG_i, PLLCLKSEL, PLL2_ch1); break;
817        case 1: BAPE_Reg_P_AddEnumToFieldList(&regFieldList, AUD_FMM_IOP_MISC_MCLK_CFG_i, PLLCLKSEL, PLL2_ch2); break;
818        case 2: BAPE_Reg_P_AddEnumToFieldList(&regFieldList, AUD_FMM_IOP_MISC_MCLK_CFG_i, PLLCLKSEL, PLL2_ch3); break;
819        default: return BERR_TRACE(BERR_NOT_SUPPORTED);
820        }
821        break;
822    #endif
823    #if BAPE_CHIP_MAX_PLLS > 3
824    case BAPE_Pll_e3:
825        switch ( pllChannel )
826        {
827        case 0: BAPE_Reg_P_AddEnumToFieldList(&regFieldList, AUD_FMM_IOP_MISC_MCLK_CFG_i, PLLCLKSEL, PLL3_ch1); break;
828        case 1: BAPE_Reg_P_AddEnumToFieldList(&regFieldList, AUD_FMM_IOP_MISC_MCLK_CFG_i, PLLCLKSEL, PLL3_ch2); break;
829        case 2: BAPE_Reg_P_AddEnumToFieldList(&regFieldList, AUD_FMM_IOP_MISC_MCLK_CFG_i, PLLCLKSEL, PLL3_ch3); break;
830        default: return BERR_TRACE(BERR_NOT_SUPPORTED);
831        }
832        break;
833    #endif
834    #if BAPE_CHIP_MAX_PLLS > 4
835        #error "Need to add support for more PLLs"
836    #endif
837        /* Should never get here */
838        default:
839            BDBG_ERR(("PLL is invalid"));
840            BDBG_ASSERT(false);     /* something went wrong somewhere! */
841            return(BERR_INVALID_PARAMETER);
842        }
843        BAPE_Reg_P_ApplyFieldList(&regFieldList, regAddr);
844    }
845#endif
846
847    return(BERR_SUCCESS);
848   
849}
850
851BERR_Code BAPE_Pll_P_ResumeFromStandby(BAPE_Handle bapeHandle)
852{
853    BERR_Code   errCode = BERR_SUCCESS;
854    unsigned    pllIndex;
855
856    BDBG_OBJECT_ASSERT(bapeHandle, BAPE_Device);
857
858    /* For each pll, call the functions necessary to restore the hardware to it's appropriate state. */
859    for ( pllIndex=0 ; pllIndex<BAPE_CHIP_MAX_PLLS ; pllIndex++ )
860    {
861        BAPE_AudioPll *pPll = &bapeHandle->audioPlls[pllIndex];
862
863        /* Now apply changes for the settings struct. */
864        errCode = BAPE_Pll_SetSettings(bapeHandle, pllIndex, &pPll->settings );
865        if ( errCode ) return BERR_TRACE(errCode);
866
867        /* Now restore the dynamic stuff from the values saved in the device struct. */
868        if (pPll->baseSampleRate != 0)
869        {
870            BKNI_EnterCriticalSection();
871                errCode = BAPE_P_SetPllFreq_isr( bapeHandle, pllIndex, pPll->baseSampleRate );
872            BKNI_LeaveCriticalSection();
873            if ( errCode ) return BERR_TRACE(errCode);
874        }
875    }
876    return errCode;
877}
878
879
Note: See TracBrowser for help on using the repository browser.