Skip to content

Commit 8115d9b

Browse files
standalone-techkartben
authored andcommitted
drivers: i2s: nrfx: Allow MCK bypass for proper LRCK and MCK Ratios
nRF53 series SoCs have a dedicated configurable audio PLL and the ability to enable MCK bypass via a register value CONFIG.CLKCONFIG. This can enable higher MCK/LRCK ratios that some I2S peripherals require the host to generate. Allow an application developer to choose if they want to initially look for a bypass ratio and, if found, enable bypass in the NRFX driver. If not, the standard MCK calculation is conducted as normal. Signed-off-by: Sean O'Connor <[email protected]>
1 parent 0eb4000 commit 8115d9b

File tree

3 files changed

+36
-1
lines changed

3 files changed

+36
-1
lines changed

drivers/i2s/Kconfig.nrfx

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,14 @@ config I2S_NRFX_TX_BLOCK_COUNT
2121
int "TX queue length"
2222
default 4
2323

24+
config I2S_NRFX_ALLOW_MCK_BYPASS
25+
bool "Allow MCK bypass if a ratio exists"
26+
depends on SOC_SERIES_NRF53X
27+
help
28+
Search for a supported ratio directly from MCK and LRCK
29+
and enable bypass if a ratio exists. If not, fallback to
30+
the standard MCK selection mechanism.
31+
2432
endif # I2S_NRFX
2533

2634
menuconfig I2S_NRF_TDM

drivers/i2s/i2s_nrfx.c

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,26 @@ static void find_suitable_clock(const struct i2s_nrfx_drv_cfg *drv_cfg,
9595
nrf_i2s_mck_t best_mck_cfg = 0;
9696
uint32_t best_mck = 0;
9797

98+
#if defined(CONFIG_I2S_NRFX_ALLOW_MCK_BYPASS) && NRF_I2S_HAS_CLKCONFIG
99+
/* Check for bypass before calculating f_MCK */
100+
for (r = 0; r < ARRAY_SIZE(ratios); ++r) {
101+
if (i2s_cfg->frame_clk_freq * ratios[r].ratio_val == src_freq) {
102+
LOG_INF("MCK bypass calculated");
103+
best_r = r;
104+
best_mck = src_freq;
105+
best_diff = 0;
106+
107+
/* Set CONFIG.MCKFREQ register to non-zero reset value to
108+
* ensure peripheral functionality
109+
*/
110+
best_mck_cfg = NRF_I2S_MCK_32MDIV8;
111+
112+
config->enable_bypass = true;
113+
break;
114+
}
115+
}
116+
#endif
117+
98118
for (r = 0; (best_diff != 0) && (r < ARRAY_SIZE(ratios)); ++r) {
99119
/* Only multiples of the frame width can be used as ratios. */
100120
if ((ratios[r].ratio_val % bits_per_frame) != 0) {
@@ -760,7 +780,7 @@ static int trigger_start(const struct device *dev)
760780
nrf_i2s_clk_configure(drv_cfg->i2s.p_reg,
761781
drv_cfg->clk_src == ACLK ? NRF_I2S_CLKSRC_ACLK
762782
: NRF_I2S_CLKSRC_PCLK32M,
763-
false);
783+
nrfx_cfg->enable_bypass);
764784
#endif
765785

766786
/* If it is required to use certain HF clock, request it to be running
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
#
2+
# Copyright The Zephyr Project Contributors
3+
#
4+
# SPDX-License-Identifier: Apache-2.0
5+
#
6+
7+
CONFIG_I2S_NRFX_ALLOW_MCK_BYPASS=y

0 commit comments

Comments
 (0)