|
17 | 17 | #include "clock_update.h"
|
18 | 18 | #include "sl_si91x_clock_manager.h"
|
19 | 19 |
|
20 |
| -#define DT_DRV_COMPAT silabs_siwx91x_clock |
21 | 20 | #define DT_DRV_COMPAT silabs_siwx91x_clock
|
22 | 21 | #define LF_FSM_CLOCK_FREQUENCY 32768
|
| 22 | +#define XTAL_FREQUENCY 40000000 |
23 | 23 |
|
24 | 24 | LOG_MODULE_REGISTER(siwx91x_clock, CONFIG_CLOCK_CONTROL_LOG_LEVEL);
|
25 | 25 |
|
@@ -89,6 +89,20 @@ static int siwx91x_clock_on(const struct device *dev, clock_control_subsys_t sys
|
89 | 89 | /* Already done in sl_calendar_init()*/
|
90 | 90 | RSI_PS_NpssPeriPowerUp(SLPSS_PWRGATE_ULP_MCURTC | SLPSS_PWRGATE_ULP_TIMEPERIOD);
|
91 | 91 | break;
|
| 92 | + case SIWX91X_CLK_I2S0: |
| 93 | + RSI_PS_M4ssPeriPowerUp(M4SS_PWRGATE_ULP_EFUSE_PERI); |
| 94 | + break; |
| 95 | + case SIWX91X_CLK_STATIC_I2S0: |
| 96 | + MISC_CFG_MISC_CTRL1 |= (1 << 23); |
| 97 | + RSI_CLK_PeripheralClkEnable(M4CLK, I2SM_CLK, ENABLE_STATIC_CLK); |
| 98 | + break; |
| 99 | + case SIWX91X_CLK_ULP_I2S: |
| 100 | + RSI_PS_UlpssPeriPowerUp(ULPSS_PWRGATE_ULP_I2S); |
| 101 | + break; |
| 102 | + case SIWX91X_CLK_STATIC_ULP_I2S: |
| 103 | + ULPCLK->ULP_I2S_CLK_GEN_REG_b.ULP_I2S_MASTER_SLAVE_MODE_b = 1; |
| 104 | + RSI_ULPSS_PeripheralEnable(ULPCLK, ULP_I2S_CLK, ENABLE_STATIC_CLK); |
| 105 | + break; |
92 | 106 | default:
|
93 | 107 | return -EINVAL;
|
94 | 108 | }
|
@@ -118,6 +132,12 @@ static int siwx91x_clock_off(const struct device *dev, clock_control_subsys_t sy
|
118 | 132 | case SIWX91X_CLK_DMA0:
|
119 | 133 | RSI_CLK_PeripheralClkDisable(M4CLK, UDMA_CLK);
|
120 | 134 | break;
|
| 135 | + case SIWX91X_CLK_STATIC_I2S0: |
| 136 | + RSI_CLK_PeripheralClkDisable(M4CLK, I2SM_CLK); |
| 137 | + break; |
| 138 | + case SIWX91X_CLK_STATIC_ULP_I2S: |
| 139 | + RSI_ULPSS_PeripheralDisable(ULPCLK, ULP_I2S_CLK); |
| 140 | + break; |
121 | 141 | case SIWX91X_CLK_ULP_UART:
|
122 | 142 | case SIWX91X_CLK_I2C0:
|
123 | 143 | case SIWX91X_CLK_I2C1:
|
@@ -162,6 +182,33 @@ static int siwx91x_clock_get_rate(const struct device *dev, clock_control_subsys
|
162 | 182 | }
|
163 | 183 | }
|
164 | 184 |
|
| 185 | +static int siwx91x_clock_set_rate(const struct device *dev, clock_control_subsys_t sys, |
| 186 | + clock_control_subsys_rate_t rate) |
| 187 | +{ |
| 188 | + uintptr_t clockid = (uintptr_t)sys; |
| 189 | + ULP_I2S_CLK_SELECT_T ref_clk; |
| 190 | + uint32_t freq; |
| 191 | + int ret; |
| 192 | + |
| 193 | + switch (clockid) { |
| 194 | + case SIWX91X_CLK_I2S0: |
| 195 | + RSI_CLK_SetI2sPllFreq(M4CLK, *((uint32_t *)rate), XTAL_FREQUENCY); |
| 196 | + RSI_CLK_I2sClkConfig(M4CLK, I2S_PLLCLK, 0); |
| 197 | + return 0; |
| 198 | + case SIWX91X_CLK_ULP_I2S: |
| 199 | + ref_clk = ULPCLK->ULP_I2S_CLK_GEN_REG_b.ULP_I2S_CLK_SEL_b; |
| 200 | + freq = RSI_CLK_GetBaseClock(ULPSS_I2S); |
| 201 | + ret = RSI_ULPSS_UlpI2sClkConfig(ULPCLK, ref_clk, freq / (*((uint32_t *)rate) / 2)); |
| 202 | + if (ret) { |
| 203 | + return -EIO; |
| 204 | + } |
| 205 | + return 0; |
| 206 | + default: |
| 207 | + /* For now, no other driver need clock rate */ |
| 208 | + return -EINVAL; |
| 209 | + } |
| 210 | +} |
| 211 | + |
165 | 212 | static enum clock_control_status siwx91x_clock_get_status(const struct device *dev,
|
166 | 213 | clock_control_subsys_t sys)
|
167 | 214 | {
|
@@ -209,6 +256,7 @@ static DEVICE_API(clock_control, siwx91x_clock_api) = {
|
209 | 256 | .on = siwx91x_clock_on,
|
210 | 257 | .off = siwx91x_clock_off,
|
211 | 258 | .get_rate = siwx91x_clock_get_rate,
|
| 259 | + .set_rate = siwx91x_clock_set_rate, |
212 | 260 | .get_status = siwx91x_clock_get_status,
|
213 | 261 | };
|
214 | 262 |
|
|
0 commit comments