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


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

/**
 * @brief Early system hook to force MCLK generation for the SGTL5000 codec.
 *
 * The NXP SGTL5000 audio codec digital state machine is entirely clocked by the 
 * external MCLK line. It will stay in absolute hardware freeze and refuse to 
 * acknowledge any I2C control frames until a valid clock signal is present.
 *
 * This function bypasses the default dynamic clock gating of the Zephyr SAI driver,
 * forcing the i.MX RT1024 to output a continuous clock stream prior to kernel 
 * device driver initialization loops.
 */
static int sgtl5000_force_mclk_init(void)
{
	/* 1. Force the physical pinmux allocation for the SAI2 MCLK signal line */
	/* Target Pin: GPIO_SD_B0_00 configured to Alternative Mode 3 (SAI2_MCLK) */
	IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B0_00_SAI2_MCLK, 0U);
	
	/* 2. Configure electrical pads parameters for high-frequency clock transmission */
	/* Settings: Speed=Medium, Drive Strength=R0/6, Slew Rate=Fast, Pull=Disabled */
	IOMUXC_SetPinConfig(IOMUXC_GPIO_SD_B0_00_SAI2_MCLK, 0x10B0U);

	/* 3. Enable the main peripheral clock gate inside the i.MX RT Clock Controller */
	CLOCK_EnableClock(kCLOCK_Sai2);

	/* 4. Configure Root Clock Multiplexers and Divider Trees for SAI2 */
	/* Select PLL4 (Audio PLL) as the clock source upstream root */
	CLOCK_SetMux(kCLOCK_Sai2Mux, 0); 
	
	/* Set the pre-divider factor */
	CLOCK_SetDiv(kCLOCK_Sai2PreDiv, 3); 
	
	/* Set the post-divider fraction to achieve exact ~12.288 MHz target */
	CLOCK_SetDiv(kCLOCK_Sai2Div, 7);    

	/* 5. Force the internal SAI2 Master Control register to broadcast the clock line */
	/* Set the Bit Clock Enable (BCE) bit to activate the generation engine */
	SAI2->TCSR |= I2S_TCSR_BCE_MASK; 
	
	printk("SGTL5000 Driver Patch: Forced continuous MCLK line generation activated.\n");
	return 0;
}

/* 
 * Register the function to run at the PRE_KERNEL_2 boot phase.
 * Priority 50 ensures this executes before POST_KERNEL, which is when 
 * Zephyr processes the I2C bus device discovery array for audio codecs.
 */
SYS_INIT(sgtl5000_force_mclk_init, PRE_KERNEL_2, 50);