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


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

/* Retrieve the base memory address of the linked SAI instance directly from DTS */
#define CODEC_SAI_BASE_ADDR   DT_REG_ADDR(DT_PHANDLE(DT_DRV_INST(0), bus-sai))
#define AUDIO_SAI_PERIPHERAL  ((I2S_Type *)CODEC_SAI_BASE_ADDR)

/**
 * @brief Early system hook to force MCLK generation for the SGTL5000 codec.
 *
 * This function automatically detects which SAI instance is selected in the
 * device tree, maps its hardware registers, and enables continuous MCLK generation.
 */
static int sgtl5000_force_mclk_init(void)
{
	/* 
	 * 1. Configure the physical pinmux allocation for the SAI MCLK signal line.
	 * NOTE: Pinmux settings are board-dependent and usually handled by the pinctrl driver.
	 * If your pinctrl driver runs later, we force the configuration here:
	 */
#if (CODEC_SAI_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); 
	CLOCK_SetDiv(kCLOCK_Sai2PreDiv, 3); 
	CLOCK_SetDiv(kCLOCK_Sai2Div, 7);    
#elif (CODEC_SAI_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); 
	CLOCK_SetDiv(kCLOCK_Sai1PreDiv, 3); 
	CLOCK_SetDiv(kCLOCK_Sai1Div, 7); 
#endif

	/* 
	 * 2. Dynamically access the selected SAI peripheral registers.
	 * This un-gates the master clock generation engine for whichever SAI is active.
	 */
	AUDIO_SAI_PERIPHERAL->TCSR |= I2S_TCSR_BCE_MASK; 
	
	printk("SGTL5000 Patch: Dynamic MCLK generation enabled for SAI register block 0x%08X\n", 
	       CODEC_SAI_BASE_ADDR);
           
	return 0;
}

/* Run during PRE_KERNEL_2 phase to unlock I2C state machine before device discovery loops */
SYS_INIT(sgtl5000_force_mclk_init, PRE_KERNEL_2, 50);