1515LOG_MODULE_REGISTER (dmic_nrfx_pdm , CONFIG_AUDIO_DMIC_LOG_LEVEL );
1616
1717struct dmic_nrfx_pdm_drv_data {
18+ const nrfx_pdm_t * pdm ;
1819 struct onoff_manager * clk_mgr ;
1920 struct onoff_client clk_cli ;
2021 struct k_mem_slab * mem_slab ;
@@ -28,6 +29,7 @@ struct dmic_nrfx_pdm_drv_data {
2829
2930struct dmic_nrfx_pdm_drv_cfg {
3031 nrfx_pdm_event_handler_t event_handler ;
32+ nrfx_pdm_t pdm ;
3133 nrfx_pdm_config_t nrfx_def_cfg ;
3234 const struct pinctrl_dev_config * pcfg ;
3335 enum clock_source {
@@ -58,8 +60,7 @@ static void event_handler(const struct device *dev, const nrfx_pdm_evt_t *evt)
5860 LOG_ERR ("Failed to allocate buffer: %d" , ret );
5961 stop = true;
6062 } else {
61- err = nrfx_pdm_buffer_set (buffer ,
62- drv_data -> block_size / 2 );
63+ err = nrfx_pdm_buffer_set (drv_data -> pdm , buffer , drv_data -> block_size / 2 );
6364 if (err != NRFX_SUCCESS ) {
6465 LOG_ERR ("Failed to set buffer: 0x%08x" , err );
6566 stop = true;
@@ -94,7 +95,7 @@ static void event_handler(const struct device *dev, const nrfx_pdm_evt_t *evt)
9495
9596 if (stop ) {
9697 drv_data -> stopping = true;
97- nrfx_pdm_stop ();
98+ nrfx_pdm_stop (drv_data -> pdm );
9899 }
99100}
100101
@@ -132,6 +133,37 @@ static bool check_pdm_frequencies(const struct dmic_nrfx_pdm_drv_cfg *drv_cfg,
132133 uint32_t req_rate = pdm_cfg -> streams [0 ].pcm_rate ;
133134 bool better_found = false;
134135
136+ #if NRF_PDM_HAS_PRESCALER
137+ uint32_t src_freq = 32 * 1000 * 1000UL ;
138+ uint32_t req_freq = req_rate * ratio ;
139+ uint32_t prescaler = src_freq / req_freq ;
140+ uint32_t act_freq = src_freq / prescaler ;
141+
142+ if (act_freq >= pdm_cfg -> io .min_pdm_clk_freq && act_freq <= pdm_cfg -> io .max_pdm_clk_freq &&
143+ is_better (act_freq , ratio , req_rate , best_diff , best_rate , best_freq )) {
144+ config -> prescaler = prescaler ;
145+
146+ better_found = true;
147+ }
148+
149+ /* Stop if an exact rate match is found. */
150+ if (* best_diff == 0 ) {
151+ return true;
152+ }
153+
154+ /* Prescaler value is rounded down by default,
155+ * thus value rounded up should be checked as well.
156+ */
157+ prescaler += 1 ;
158+ act_freq = src_freq / prescaler ;
159+
160+ if (act_freq >= pdm_cfg -> io .min_pdm_clk_freq && act_freq <= pdm_cfg -> io .max_pdm_clk_freq &&
161+ is_better (act_freq , ratio , req_rate , best_diff , best_rate , best_freq )) {
162+ config -> prescaler = prescaler ;
163+
164+ better_found = true;
165+ }
166+ #else
135167 if (IS_ENABLED (CONFIG_SOC_SERIES_NRF53X )) {
136168 const uint32_t src_freq =
137169 (NRF_PDM_HAS_MCLKCONFIG && drv_cfg -> clk_src == ACLK )
@@ -171,17 +203,17 @@ static bool check_pdm_frequencies(const struct dmic_nrfx_pdm_drv_cfg *drv_cfg,
171203 uint32_t freq_val ;
172204 nrf_pdm_freq_t freq_enum ;
173205 } freqs [] = {
174- { 1000000 , NRF_PDM_FREQ_1000K },
175- { 1032000 , NRF_PDM_FREQ_1032K },
176- { 1067000 , NRF_PDM_FREQ_1067K },
206+ {1000000 , NRF_PDM_FREQ_1000K },
207+ {1032000 , NRF_PDM_FREQ_1032K },
208+ {1067000 , NRF_PDM_FREQ_1067K },
177209#if defined(PDM_PDMCLKCTRL_FREQ_1231K )
178- { 1231000 , NRF_PDM_FREQ_1231K },
210+ {1231000 , NRF_PDM_FREQ_1231K },
179211#endif
180212#if defined(PDM_PDMCLKCTRL_FREQ_1280K )
181- { 1280000 , NRF_PDM_FREQ_1280K },
213+ {1280000 , NRF_PDM_FREQ_1280K },
182214#endif
183215#if defined(PDM_PDMCLKCTRL_FREQ_1333K )
184- { 1333000 , NRF_PDM_FREQ_1333K }
216+ {1333000 , NRF_PDM_FREQ_1333K }
185217#endif
186218 };
187219
@@ -216,6 +248,7 @@ static bool check_pdm_frequencies(const struct dmic_nrfx_pdm_drv_cfg *drv_cfg,
216248 }
217249 }
218250 }
251+ #endif
219252
220253 return better_found ;
221254}
@@ -236,8 +269,26 @@ static bool find_suitable_clock(const struct dmic_nrfx_pdm_drv_cfg *drv_cfg,
236269 uint8_t ratio_val ;
237270 nrf_pdm_ratio_t ratio_enum ;
238271 } ratios [] = {
239- { 64 , NRF_PDM_RATIO_64X },
240- { 80 , NRF_PDM_RATIO_80X }
272+ #if defined(PDM_RATIO_RATIO_Ratio32 )
273+ {32 , NRF_PDM_RATIO_32X },
274+ #endif
275+ #if defined(PDM_RATIO_RATIO_Ratio48 )
276+ {48 , NRF_PDM_RATIO_48X },
277+ #endif
278+ #if defined(PDM_RATIO_RATIO_Ratio50 )
279+ {50 , NRF_PDM_RATIO_50X },
280+ #endif
281+ {64 , NRF_PDM_RATIO_64X },
282+ {80 , NRF_PDM_RATIO_80X },
283+ #if defined(PDM_RATIO_RATIO_Ratio96 )
284+ {96 , NRF_PDM_RATIO_96X },
285+ #endif
286+ #if defined(PDM_RATIO_RATIO_Ratio100 )
287+ {100 , NRF_PDM_RATIO_100X },
288+ #endif
289+ #if defined(PDM_RATIO_RATIO_Ratio128 )
290+ {128 , NRF_PDM_RATIO_128X }
291+ #endif
241292 };
242293
243294 for (int r = 0 ; best_diff != 0 && r < ARRAY_SIZE (ratios ); ++ r ) {
@@ -327,7 +378,7 @@ static int dmic_nrfx_pdm_configure(const struct device *dev,
327378 /* If either rate or width is 0, the stream is to be disabled. */
328379 if (stream -> pcm_rate == 0 || stream -> pcm_width == 0 ) {
329380 if (drv_data -> configured ) {
330- nrfx_pdm_uninit ();
381+ nrfx_pdm_uninit (drv_data -> pdm );
331382 drv_data -> configured = false;
332383 }
333384
@@ -357,11 +408,11 @@ static int dmic_nrfx_pdm_configure(const struct device *dev,
357408 }
358409
359410 if (drv_data -> configured ) {
360- nrfx_pdm_uninit ();
411+ nrfx_pdm_uninit (drv_data -> pdm );
361412 drv_data -> configured = false;
362413 }
363414
364- err = nrfx_pdm_init (& nrfx_cfg , drv_cfg -> event_handler );
415+ err = nrfx_pdm_init (drv_data -> pdm , & nrfx_cfg , drv_cfg -> event_handler );
365416 if (err != NRFX_SUCCESS ) {
366417 LOG_ERR ("Failed to initialize PDM: 0x%08x" , err );
367418 return - EIO ;
@@ -385,7 +436,7 @@ static int start_transfer(struct dmic_nrfx_pdm_drv_data *drv_data)
385436 nrfx_err_t err ;
386437 int ret ;
387438
388- err = nrfx_pdm_start ();
439+ err = nrfx_pdm_start (drv_data -> pdm );
389440 if (err == NRFX_SUCCESS ) {
390441 return 0 ;
391442 }
@@ -460,7 +511,7 @@ static int dmic_nrfx_pdm_trigger(const struct device *dev,
460511 case DMIC_TRIGGER_STOP :
461512 if (drv_data -> active ) {
462513 drv_data -> stopping = true;
463- nrfx_pdm_stop ();
514+ nrfx_pdm_stop (drv_data -> pdm );
464515 }
465516 break ;
466517
@@ -540,11 +591,28 @@ static const struct _dmic_ops dmic_ops = {
540591
541592#define PDM_NRFX_DEVICE (idx ) \
542593 static void *rx_msgs##idx[DT_PROP(PDM(idx), queue_size)]; \
543- static struct dmic_nrfx_pdm_drv_data dmic_nrfx_pdm_data##idx; \
594+ static void event_handler##idx(const nrfx_pdm_evt_t *evt) \
595+ { \
596+ event_handler(DEVICE_DT_GET(PDM(idx)), evt); \
597+ } \
598+ PINCTRL_DT_DEFINE(PDM(idx)); \
599+ static const struct dmic_nrfx_pdm_drv_cfg dmic_nrfx_pdm_cfg##idx = { \
600+ .event_handler = event_handler##idx, \
601+ .pdm = NRFX_PDM_INSTANCE(idx), \
602+ .nrfx_def_cfg = NRFX_PDM_DEFAULT_CONFIG(0, 0), \
603+ .nrfx_def_cfg.skip_gpio_cfg = true, \
604+ .nrfx_def_cfg.skip_psel_cfg = true, \
605+ .pcfg = PINCTRL_DT_DEV_CONFIG_GET(PDM(idx)), \
606+ .clk_src = PDM_CLK_SRC(idx), \
607+ }; \
608+ static struct dmic_nrfx_pdm_drv_data dmic_nrfx_pdm_data##idx = \
609+ { \
610+ .pdm = &dmic_nrfx_pdm_cfg##idx.pdm \
611+ }; \
544612 static int pdm_nrfx_init##idx(const struct device *dev) \
545613 { \
546614 IRQ_CONNECT(DT_IRQN(PDM(idx)), DT_IRQ(PDM(idx), priority), \
547- nrfx_isr, nrfx_pdm_irq_handler , 0); \
615+ nrfx_isr, nrfx_pdm_##idx##_irq_handler , 0); \
548616 const struct dmic_nrfx_pdm_drv_cfg *drv_cfg = dev->config; \
549617 int err = pinctrl_apply_state(drv_cfg->pcfg, \
550618 PINCTRL_STATE_DEFAULT); \
@@ -557,19 +625,6 @@ static const struct _dmic_ops dmic_ops = {
557625 init_clock_manager(dev); \
558626 return 0; \
559627 } \
560- static void event_handler##idx(const nrfx_pdm_evt_t *evt) \
561- { \
562- event_handler(DEVICE_DT_GET(PDM(idx)), evt); \
563- } \
564- PINCTRL_DT_DEFINE(PDM(idx)); \
565- static const struct dmic_nrfx_pdm_drv_cfg dmic_nrfx_pdm_cfg##idx = { \
566- .event_handler = event_handler##idx, \
567- .nrfx_def_cfg = NRFX_PDM_DEFAULT_CONFIG(0, 0), \
568- .nrfx_def_cfg.skip_gpio_cfg = true, \
569- .nrfx_def_cfg.skip_psel_cfg = true, \
570- .pcfg = PINCTRL_DT_DEV_CONFIG_GET(PDM(idx)), \
571- .clk_src = PDM_CLK_SRC(idx), \
572- }; \
573628 BUILD_ASSERT(PDM_CLK_SRC(idx) != ACLK || NRF_PDM_HAS_MCLKCONFIG, \
574629 "Clock source ACLK is not available."); \
575630 BUILD_ASSERT(PDM_CLK_SRC(idx) != ACLK || \
@@ -582,5 +637,14 @@ static const struct _dmic_ops dmic_ops = {
582637 POST_KERNEL, CONFIG_AUDIO_DMIC_INIT_PRIORITY, \
583638 &dmic_ops);
584639
585- /* Existing SoCs only have one PDM instance. */
640+ #ifdef CONFIG_HAS_HW_NRF_PDM0
586641PDM_NRFX_DEVICE (0 );
642+ #endif
643+
644+ #ifdef CONFIG_HAS_HW_NRF_PDM20
645+ PDM_NRFX_DEVICE (20 );
646+ #endif
647+
648+ #ifdef CONFIG_HAS_HW_NRF_PDM21
649+ PDM_NRFX_DEVICE (21 );
650+ #endif
0 commit comments