1 /* 2 * Copyright 2020-2021 NXP 3 * All rights reserved. 4 * 5 * SPDX-License-Identifier: BSD-3-Clause 6 */ 7 #include "fsl_audiomix.h" 8 9 /******************************************************************************* 10 * Definitions 11 ******************************************************************************/ 12 /* Component ID definition, used by tools. */ 13 #ifndef FSL_COMPONENT_ID 14 #define FSL_COMPONENT_ID "platform.drivers.audiomix" 15 #endif 16 17 /******************************************************************************* 18 * Prototypes 19 ******************************************************************************/ 20 21 /******************************************************************************* 22 * Variables 23 ******************************************************************************/ 24 25 /******************************************************************************* 26 * Code 27 ******************************************************************************/ 28 /*! 29 * brief audiomix attach clock. 30 * 31 * param base audiomix base address. 32 * param id attach clock id. 33 */ AUDIOMIX_AttachClk(AUDIOMIX_Type * base,audiomix_attch_clk_t id)34void AUDIOMIX_AttachClk(AUDIOMIX_Type *base, audiomix_attch_clk_t id) 35 { 36 /* extract offset, mask, value */ 37 uint32_t offset = GET_AUDIOMIX_ATTACH_ID_OFFSET(id); 38 uint32_t mask = GET_AUDIOMIX_ATTACH_ID_MASK(id); 39 uint32_t value = GET_AUDIOMIX_ATTACH_ID_value(id); 40 volatile uint32_t *baseAddr = (volatile uint32_t *)((uintptr_t)base + offset); 41 /* load to register */ 42 *baseAddr = (*baseAddr & ~mask) | value; 43 } 44 45 /*! 46 * brief Initializes the SAI PLL. 47 * note This function can't detect whether the AUDIO PLL has been enabled and 48 * used by some IPs. 49 * 50 * param config Pointer to the configuration structure(see ref ccm_analog_frac_pll_config_t enumeration). 51 * 52 */ AUDIOMIX_InitAudioPll(AUDIOMIX_Type * base,const ccm_analog_frac_pll_config_t * config)53void AUDIOMIX_InitAudioPll(AUDIOMIX_Type *base, const ccm_analog_frac_pll_config_t *config) 54 { 55 assert(config != NULL); 56 57 uint32_t fracCfg1 = base->SAI_PLL_FDIV_CTL0; 58 uint32_t fracCfg2 = base->SAI_PLL_FDIV_CTL1; 59 60 /* PLL power down and no bypass */ 61 base->SAI_PLL_GNRL_CTL = 62 base->SAI_PLL_GNRL_CTL & (~(AUDIOMIX_SAI_PLL_GNRL_CTL_RESETB_MASK | AUDIOMIX_SAI_PLL_GNRL_CTL_BYPASS_MASK)); 63 base->SAI_PLL_FDIV_CTL0 = 64 (fracCfg1 & (~(AUDIOMIX_SAI_PLL_FDIV_CTL0_MAIN_DIV_MASK | AUDIOMIX_SAI_PLL_FDIV_CTL0_PRE_DIV_MASK | 65 AUDIOMIX_SAI_PLL_FDIV_CTL0_POST_DIV_MASK))) | 66 AUDIOMIX_SAI_PLL_FDIV_CTL0_MAIN_DIV(config->mainDiv) | AUDIOMIX_SAI_PLL_FDIV_CTL0_PRE_DIV(config->preDiv) | 67 AUDIOMIX_SAI_PLL_FDIV_CTL0_POST_DIV(config->postDiv); 68 69 base->SAI_PLL_FDIV_CTL1 = 70 (fracCfg2 & (~(AUDIOMIX_SAI_PLL_FDIV_CTL1_DSM_MASK))) | AUDIOMIX_SAI_PLL_FDIV_CTL1_DSM(config->dsm); 71 72 base->SAI_PLL_GNRL_CTL |= 73 AUDIOMIX_SAI_PLL_GNRL_CTL_RESETB_MASK | AUDIOMIX_SAI_PLL_GNRL_CTL_CKE_MASK; /* Enable and power up PLL clock. */ 74 75 /* Wait for PLL to be locked. */ 76 while ((base->SAI_PLL_GNRL_CTL & AUDIOMIX_SAI_PLL_GNRL_CTL_LOCK_MASK) == 0U) 77 { 78 } 79 } 80 81 /*! 82 * brief De-initialize the SAI PLL. 83 */ AUDIOMIX_DeinitAudioPll1(AUDIOMIX_Type * base)84void AUDIOMIX_DeinitAudioPll1(AUDIOMIX_Type *base) 85 { 86 base->SAI_PLL_GNRL_CTL &= ~AUDIOMIX_SAI_PLL_GNRL_CTL_RESETB_MASK; 87 } 88 89 /*! 90 * brief Get the sai PLL output freq. 91 * 92 * retval sai pll output freq. 93 */ AUDIOMIX_GetAudioPllFreq(AUDIOMIX_Type * base)94uint32_t AUDIOMIX_GetAudioPllFreq(AUDIOMIX_Type *base) 95 { 96 uint32_t fracCfg1 = base->SAI_PLL_FDIV_CTL0; 97 uint32_t fracCfg2 = base->SAI_PLL_FDIV_CTL1; 98 uint64_t fracClk = 0U; 99 /* get reference clock freq */ 100 uint32_t refClkFreq = 101 (base->SAI_PLL_GNRL_CTL & AUDIOMIX_SAI_PLL_GNRL_CTL_REF_CLK_SEL_MASK) != 0U ? CLKPAD_FREQ : OSC24M_CLK_FREQ; 102 /* main divider */ 103 uint32_t mainDiv = 104 (fracCfg1 & AUDIOMIX_SAI_PLL_FDIV_CTL0_MAIN_DIV_MASK) >> AUDIOMIX_SAI_PLL_FDIV_CTL0_MAIN_DIV_SHIFT; 105 /* pre divider */ 106 uint32_t preDiv = (fracCfg1 & AUDIOMIX_SAI_PLL_FDIV_CTL0_PRE_DIV_MASK) >> AUDIOMIX_SAI_PLL_FDIV_CTL0_PRE_DIV_SHIFT; 107 /* post divider */ 108 uint32_t postDiv = 109 ((fracCfg1 & AUDIOMIX_SAI_PLL_FDIV_CTL0_POST_DIV_MASK) >> AUDIOMIX_SAI_PLL_FDIV_CTL0_POST_DIV_SHIFT); 110 uint32_t dsm = (fracCfg2 & AUDIOMIX_SAI_PLL_FDIV_CTL1_DSM_MASK) >> AUDIOMIX_SAI_PLL_FDIV_CTL1_DSM_SHIFT; 111 112 /* calculate the audio pll frequ */ 113 fracClk = (uint64_t)refClkFreq * ((uint64_t)mainDiv * 65536UL + dsm) / (65536UL * preDiv * (1UL << postDiv)); 114 115 return (uint32_t)fracClk; 116 } 117