@@ -64,20 +64,6 @@ static void find_suitable_clock(const struct i2s_nrfx_drv_cfg *drv_cfg,
6464 nrfx_i2s_config_t * config ,
6565 const struct i2s_config * i2s_cfg )
6666{
67- static const struct {
68- uint16_t ratio_val ;
69- nrf_i2s_ratio_t ratio_enum ;
70- } ratios [] = {
71- { 32 , NRF_I2S_RATIO_32X },
72- { 48 , NRF_I2S_RATIO_48X },
73- { 64 , NRF_I2S_RATIO_64X },
74- { 96 , NRF_I2S_RATIO_96X },
75- { 128 , NRF_I2S_RATIO_128X },
76- { 192 , NRF_I2S_RATIO_192X },
77- { 256 , NRF_I2S_RATIO_256X },
78- { 384 , NRF_I2S_RATIO_384X },
79- { 512 , NRF_I2S_RATIO_512X }
80- };
8167 const uint32_t src_freq =
8268 (NRF_I2S_HAS_CLKCONFIG && drv_cfg -> clk_src == ACLK )
8369 /* The I2S_NRFX_DEVICE() macro contains build assertions that
@@ -89,123 +75,12 @@ static void find_suitable_clock(const struct i2s_nrfx_drv_cfg *drv_cfg,
8975 */
9076 ? DT_PROP_OR (DT_NODELABEL (clock ), hfclkaudio_frequency , 0 )
9177 : 32 * 1000 * 1000UL ;
92- uint32_t bits_per_frame = 2 * i2s_cfg -> word_size ;
93- uint32_t best_diff = UINT32_MAX ;
94- uint8_t r , best_r = 0 ;
95- nrf_i2s_mck_t best_mck_cfg = 0 ;
96- uint32_t best_mck = 0 ;
97-
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-
118- for (r = 0 ; (best_diff != 0 ) && (r < ARRAY_SIZE (ratios )); ++ r ) {
119- /* Only multiples of the frame width can be used as ratios. */
120- if ((ratios [r ].ratio_val % bits_per_frame ) != 0 ) {
121- continue ;
122- }
123-
124- if (IS_ENABLED (CONFIG_SOC_SERIES_NRF53X ) || IS_ENABLED (CONFIG_SOC_SERIES_NRF54LX )) {
125- uint32_t requested_mck =
126- i2s_cfg -> frame_clk_freq * ratios [r ].ratio_val ;
127- /* As specified in the nRF5340 PS:
128- *
129- * MCKFREQ = 4096 * floor(f_MCK * 1048576 /
130- * (f_source + f_MCK / 2))
131- * f_actual = f_source /
132- * floor(1048576 * 4096 / MCKFREQ)
133- */
134- enum { MCKCONST = 1048576 };
135- uint32_t mck_factor =
136- (uint32_t )(((uint64_t )requested_mck * MCKCONST ) /
137- (src_freq + requested_mck / 2 ));
138-
139- /* skip cases when mck_factor is too big for dividing */
140- if (mck_factor > MCKCONST ) {
141- continue ;
142- }
143- uint32_t actual_mck = src_freq / (MCKCONST / mck_factor );
144-
145- uint32_t lrck_freq = actual_mck / ratios [r ].ratio_val ;
146- uint32_t diff = lrck_freq >= i2s_cfg -> frame_clk_freq
147- ? (lrck_freq - i2s_cfg -> frame_clk_freq )
148- : (i2s_cfg -> frame_clk_freq - lrck_freq );
149-
150- if (diff < best_diff ) {
151- best_mck_cfg = mck_factor * 4096 ;
152- best_mck = actual_mck ;
153- best_r = r ;
154- best_diff = diff ;
155- }
156- } else {
157- static const struct {
158- uint8_t divider_val ;
159- nrf_i2s_mck_t divider_enum ;
160- } dividers [] = {
161- { 8 , NRF_I2S_MCK_32MDIV8 },
162- { 10 , NRF_I2S_MCK_32MDIV10 },
163- { 11 , NRF_I2S_MCK_32MDIV11 },
164- { 15 , NRF_I2S_MCK_32MDIV15 },
165- { 16 , NRF_I2S_MCK_32MDIV16 },
166- { 21 , NRF_I2S_MCK_32MDIV21 },
167- { 23 , NRF_I2S_MCK_32MDIV23 },
168- { 30 , NRF_I2S_MCK_32MDIV30 },
169- { 31 , NRF_I2S_MCK_32MDIV31 },
170- { 32 , NRF_I2S_MCK_32MDIV32 },
171- { 42 , NRF_I2S_MCK_32MDIV42 },
172- { 63 , NRF_I2S_MCK_32MDIV63 },
173- { 125 , NRF_I2S_MCK_32MDIV125 }
174- };
175-
176- for (uint8_t d = 0 ; (best_diff != 0 ) && (d < ARRAY_SIZE (dividers )); ++ d ) {
177- uint32_t mck_freq =
178- src_freq / dividers [d ].divider_val ;
179- uint32_t lrck_freq =
180- mck_freq / ratios [r ].ratio_val ;
181- uint32_t diff =
182- lrck_freq >= i2s_cfg -> frame_clk_freq
183- ? (lrck_freq - i2s_cfg -> frame_clk_freq )
184- : (i2s_cfg -> frame_clk_freq - lrck_freq );
185-
186- if (diff < best_diff ) {
187- best_mck_cfg = dividers [d ].divider_enum ;
188- best_mck = mck_freq ;
189- best_r = r ;
190- best_diff = diff ;
191- }
19278
193- /* Since dividers are in ascending order, stop
194- * checking next ones for the current ratio
195- * after resulting LRCK frequency falls below
196- * the one requested.
197- */
198- if (lrck_freq < i2s_cfg -> frame_clk_freq ) {
199- break ;
200- }
201- }
202- }
79+ if (nrfx_i2s_prescalers_calc (src_freq , i2s_cfg -> frame_clk_freq , config -> sample_width ,
80+ IS_ENABLED (CONFIG_I2S_NRFX_ALLOW_MCK_BYPASS ),
81+ & config -> prescalers ) != NRFX_SUCCESS ) {
82+ LOG_ERR ("Failed to find suitable I2S clock configuration." );
20383 }
204-
205- config -> mck_setup = best_mck_cfg ;
206- config -> ratio = ratios [best_r ].ratio_enum ;
207- LOG_INF ("I2S MCK frequency: %u, actual PCM rate: %u" ,
208- best_mck , best_mck / ratios [best_r ].ratio_val );
20984}
21085
21186static bool get_next_tx_buffer (struct i2s_nrfx_drv_data * drv_data ,
@@ -551,7 +426,7 @@ static int i2s_nrfx_configure(const struct device *dev, enum i2s_dir dir,
551426 */
552427 drv_data -> request_clock = (drv_cfg -> clk_src != PCLK32M );
553428 } else {
554- nrfx_cfg .mck_setup = NRF_I2S_MCK_DISABLED ;
429+ nrfx_cfg .prescalers . mck_setup = NRF_I2S_MCK_DISABLED ;
555430 drv_data -> request_clock = false;
556431 }
557432
@@ -780,7 +655,7 @@ static int trigger_start(const struct device *dev)
780655 nrf_i2s_clk_configure (drv_cfg -> i2s .p_reg ,
781656 drv_cfg -> clk_src == ACLK ? NRF_I2S_CLKSRC_ACLK
782657 : NRF_I2S_CLKSRC_PCLK32M ,
783- nrfx_cfg -> enable_bypass );
658+ nrfx_cfg -> prescalers . enable_bypass );
784659#endif
785660
786661 /* If it is required to use certain HF clock, request it to be running
0 commit comments