drivers: i2s: siwx91x: I2S clock initialization for siwx91x

Clock driver changes required for initializing the I2S clock
for the siwx91x driver

Signed-off-by: Sai Santhosh Malae <Santhosh.Malae@silabs.com>
This commit is contained in:
Sai Santhosh Malae 2025-05-08 21:30:49 +05:30 committed by Benjamin Cabé
commit dcdc8e8a55
2 changed files with 66 additions and 14 deletions

View file

@ -17,9 +17,9 @@
#include "clock_update.h"
#include "sl_si91x_clock_manager.h"
#define DT_DRV_COMPAT silabs_siwx91x_clock
#define DT_DRV_COMPAT silabs_siwx91x_clock
#define LF_FSM_CLOCK_FREQUENCY 32768
#define XTAL_FREQUENCY 40000000
LOG_MODULE_REGISTER(siwx91x_clock, CONFIG_CLOCK_CONTROL_LOG_LEVEL);
@ -89,6 +89,20 @@ static int siwx91x_clock_on(const struct device *dev, clock_control_subsys_t sys
/* Already done in sl_calendar_init()*/
RSI_PS_NpssPeriPowerUp(SLPSS_PWRGATE_ULP_MCURTC | SLPSS_PWRGATE_ULP_TIMEPERIOD);
break;
case SIWX91X_CLK_I2S0:
RSI_PS_M4ssPeriPowerUp(M4SS_PWRGATE_ULP_EFUSE_PERI);
break;
case SIWX91X_CLK_STATIC_I2S0:
MISC_CFG_MISC_CTRL1 |= (1 << 23);
RSI_CLK_PeripheralClkEnable(M4CLK, I2SM_CLK, ENABLE_STATIC_CLK);
break;
case SIWX91X_CLK_ULP_I2S:
RSI_PS_UlpssPeriPowerUp(ULPSS_PWRGATE_ULP_I2S);
break;
case SIWX91X_CLK_STATIC_ULP_I2S:
ULPCLK->ULP_I2S_CLK_GEN_REG_b.ULP_I2S_MASTER_SLAVE_MODE_b = 1;
RSI_ULPSS_PeripheralEnable(ULPCLK, ULP_I2S_CLK, ENABLE_STATIC_CLK);
break;
default:
return -EINVAL;
}
@ -118,6 +132,12 @@ static int siwx91x_clock_off(const struct device *dev, clock_control_subsys_t sy
case SIWX91X_CLK_DMA0:
RSI_CLK_PeripheralClkDisable(M4CLK, UDMA_CLK);
break;
case SIWX91X_CLK_STATIC_I2S0:
RSI_CLK_PeripheralClkDisable(M4CLK, I2SM_CLK);
break;
case SIWX91X_CLK_STATIC_ULP_I2S:
RSI_ULPSS_PeripheralDisable(ULPCLK, ULP_I2S_CLK);
break;
case SIWX91X_CLK_ULP_UART:
case SIWX91X_CLK_I2C0:
case SIWX91X_CLK_I2C1:
@ -162,6 +182,33 @@ static int siwx91x_clock_get_rate(const struct device *dev, clock_control_subsys
}
}
static int siwx91x_clock_set_rate(const struct device *dev, clock_control_subsys_t sys,
clock_control_subsys_rate_t rate)
{
uintptr_t clockid = (uintptr_t)sys;
ULP_I2S_CLK_SELECT_T ref_clk;
uint32_t freq;
int ret;
switch (clockid) {
case SIWX91X_CLK_I2S0:
RSI_CLK_SetI2sPllFreq(M4CLK, *((uint32_t *)rate), XTAL_FREQUENCY);
RSI_CLK_I2sClkConfig(M4CLK, I2S_PLLCLK, 0);
return 0;
case SIWX91X_CLK_ULP_I2S:
ref_clk = ULPCLK->ULP_I2S_CLK_GEN_REG_b.ULP_I2S_CLK_SEL_b;
freq = RSI_CLK_GetBaseClock(ULPSS_I2S);
ret = RSI_ULPSS_UlpI2sClkConfig(ULPCLK, ref_clk, freq / (*((uint32_t *)rate) / 2));
if (ret) {
return -EIO;
}
return 0;
default:
/* For now, no other driver need clock rate */
return -EINVAL;
}
}
static enum clock_control_status siwx91x_clock_get_status(const struct device *dev,
clock_control_subsys_t sys)
{
@ -209,6 +256,7 @@ static DEVICE_API(clock_control, siwx91x_clock_api) = {
.on = siwx91x_clock_on,
.off = siwx91x_clock_off,
.get_rate = siwx91x_clock_get_rate,
.set_rate = siwx91x_clock_set_rate,
.get_status = siwx91x_clock_get_status,
};

View file

@ -4,18 +4,22 @@
#ifndef ZEPHYR_INCLUDE_DT_BINDINGS_CLOCK_SILABS_SIWX91X_CLOCK_H_
#define ZEPHYR_INCLUDE_DT_BINDINGS_CLOCK_SILABS_SIWX91X_CLOCK_H_
#define SIWX91X_CLK_ULP_UART 0
#define SIWX91X_CLK_ULP_I2C 1
#define SIWX91X_CLK_ULP_DMA 2
#define SIWX91X_CLK_UART0 3
#define SIWX91X_CLK_UART1 4
#define SIWX91X_CLK_I2C0 5
#define SIWX91X_CLK_I2C1 6
#define SIWX91X_CLK_DMA0 7
#define SIWX91X_CLK_WATCHDOG 8
#define SIWX91X_CLK_PWM 9
#define SIWX91X_CLK_GSPI 10
#define SIWX91X_CLK_QSPI 11
#define SIWX91X_CLK_RTC 12
#define SIWX91X_CLK_ULP_UART 0
#define SIWX91X_CLK_ULP_I2C 1
#define SIWX91X_CLK_ULP_DMA 2
#define SIWX91X_CLK_UART0 3
#define SIWX91X_CLK_UART1 4
#define SIWX91X_CLK_I2C0 5
#define SIWX91X_CLK_I2C1 6
#define SIWX91X_CLK_DMA0 7
#define SIWX91X_CLK_WATCHDOG 8
#define SIWX91X_CLK_PWM 9
#define SIWX91X_CLK_GSPI 10
#define SIWX91X_CLK_QSPI 11
#define SIWX91X_CLK_RTC 12
#define SIWX91X_CLK_I2S0 13
#define SIWX91X_CLK_STATIC_I2S0 14
#define SIWX91X_CLK_ULP_I2S 15
#define SIWX91X_CLK_STATIC_ULP_I2S 16
#endif