Загрузка данных


#include <zephyr/init.h>
#include <fsl_clock.h>
#include <fsl_iomuxc.h>

/**
 * @brief Universal hardware clock configuration logic for an individual SAI block.
 */
static void sgtl5000_activate_sai_mclk(uint32_t base_addr)
{
	if (base_addr == DT_REG_ADDR(DT_NODELABEL(sai1))) {
		IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B1_09_SAI1_MCLK, 0U);
		IOMUXC_SetPinConfig(IOMUXC_GPIO_AD_B1_09_SAI1_MCLK, 0x10B0U);
		CLOCK_EnableClock(kCLOCK_Sai1);
		CLOCK_SetMux(kCLOCK_Sai1Mux, 0); /* Select PLL4 (Audio PLL) */
		CLOCK_SetDiv(kCLOCK_Sai1PreDiv, 3); 
		CLOCK_SetDiv(kCLOCK_Sai1Div, 7); 
		printk("SGTL5000 Dynamic Patch: Started clock configuration for SAI1\n");

	} else if (base_addr == DT_REG_ADDR(DT_NODELABEL(sai2))) {
		IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B0_00_SAI2_MCLK, 0U);
		IOMUXC_SetPinConfig(IOMUXC_GPIO_SD_B0_00_SAI2_MCLK, 0x10B0U);
		CLOCK_EnableClock(kCLOCK_Sai2);
		CLOCK_SetMux(kCLOCK_Sai2Mux, 0); /* Select PLL4 (Audio PLL) */
		CLOCK_SetDiv(kCLOCK_Sai2PreDiv, 3); 
		CLOCK_SetDiv(kCLOCK_Sai2Div, 7);    
		printk("SGTL5000 Dynamic Patch: Started clock configuration for SAI2\n");

	} else if (base_addr == DT_REG_ADDR(DT_NODELABEL(sai3))) {
		IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B1_00_SAI3_MCLK, 0U);
		IOMUXC_SetPinConfig(IOMUXC_GPIO_AD_B1_00_SAI3_MCLK, 0x10B0U);
		CLOCK_EnableClock(kCLOCK_Sai3);
		CLOCK_SetMux(kCLOCK_Sai3Mux, 0); /* Select PLL4 (Audio PLL) */
		CLOCK_SetDiv(kCLOCK_Sai3PreDiv, 3); 
		CLOCK_SetDiv(kCLOCK_Sai3Div, 7); 
		printk("SGTL5000 Dynamic Patch: Started clock configuration for SAI3\n");
	} else {
		printk("SGTL5000 Dynamic Patch ERROR: Unknown SAI base 0x%08X\n", base_addr);
		return;
	}

	/* Trigger continuous bit clock output stream on the active registers address */
	((I2S_Type *)base_addr)->TCSR |= I2S_TCSR_BCE_MASK;
	printk("SGTL5000 Dynamic Patch: Continuous MCLK un-gated for block at 0x%08X\n", base_addr);
}

/**
 * @brief Multi-instance loop framework wrapper.
 *
 * This macro handles metadata substitution for every discovered active 
 * "nxp,sgtl5000" node declared inside the device tree overlay at compile-time.
 */
#define CONFIGURE_MCLK_FOR_INSTANCE(inst) \
	sgtl5000_activate_sai_mclk(DT_REG_ADDR(DT_PHANDLE(DT_DRV_INST(inst), bus_sai)));

static int sgtl5000_global_force_mclk_init(void)
{
	/* Automatically execute the clock un-gating code for ALL defined active codecs */
	DT_INST_FOREACH_STATUS_OKAY(CONFIGURE_MCLK_FOR_INSTANCE)
	return 0;
}

/* Run at PRE_KERNEL_2 phase to unlock all codecs I2C state engines simultaneously */
SYS_INIT(sgtl5000_global_force_mclk_init, PRE_KERNEL_2, 50);