1616LOG_MODULE_REGISTER (dmic_nrfx_pdm , CONFIG_AUDIO_DMIC_LOG_LEVEL );
1717
1818#if CONFIG_SOC_SERIES_NRF54HX
19- #define DMIC_NRFX_CLOCK_FREQ 8*1000*1000UL
19+ #define DMIC_NRFX_CLOCK_FREQ MHZ(16)
20+ #define DMIC_NRFX_CLOCK_FACTOR 8192
2021#else
21- #define DMIC_NRFX_CLOCK_FREQ 32*1000*1000UL
22+ #define DMIC_NRFX_CLOCK_FREQ MHZ(32)
23+ #define DMIC_NRFX_CLOCK_FACTOR 4096
2224#endif
2325
2426struct dmic_nrfx_pdm_drv_data {
2527 const nrfx_pdm_t * pdm ;
2628 struct onoff_manager * clk_mgr ;
2729 struct onoff_client clk_cli ;
2830 struct k_mem_slab * mem_slab ;
29- void * mem_slab_buffer ;
3031 uint32_t block_size ;
32+ struct k_msgq mem_slab_queue ;
3133 struct k_msgq rx_queue ;
3234 bool request_clock : 1 ;
3335 bool configured : 1 ;
@@ -47,10 +49,10 @@ struct dmic_nrfx_pdm_drv_cfg {
4749 void * mem_reg ;
4850};
4951
50- static void free_buffer (struct dmic_nrfx_pdm_drv_data * drv_data )
52+ static void free_buffer (struct dmic_nrfx_pdm_drv_data * drv_data , void * buffer )
5153{
52- k_mem_slab_free (drv_data -> mem_slab , drv_data -> mem_slab_buffer );
53- LOG_DBG ("Freed buffer %p" , drv_data -> mem_slab_buffer );
54+ k_mem_slab_free (drv_data -> mem_slab , buffer );
55+ LOG_DBG ("Freed buffer %p" , buffer );
5456}
5557
5658static void stop_pdm (struct dmic_nrfx_pdm_drv_data * drv_data )
@@ -65,20 +67,29 @@ static void event_handler(const struct device *dev, const nrfx_pdm_evt_t *evt)
6567 const struct dmic_nrfx_pdm_drv_cfg * drv_cfg = dev -> config ;
6668 int ret ;
6769 bool stop = false;
70+ void * mem_slab_buffer ;
6871
6972 if (evt -> buffer_requested ) {
7073 void * buffer ;
7174 nrfx_err_t err ;
7275
73- ret = k_mem_slab_alloc (drv_data -> mem_slab , & drv_data -> mem_slab_buffer , K_NO_WAIT );
76+ ret = k_mem_slab_alloc (drv_data -> mem_slab , & mem_slab_buffer , K_NO_WAIT );
7477 if (ret < 0 ) {
7578 LOG_ERR ("Failed to allocate buffer: %d" , ret );
7679 stop = true;
7780 } else {
78- ret = dmm_buffer_in_prepare (drv_cfg -> mem_reg , drv_data -> mem_slab_buffer ,
81+ ret = dmm_buffer_in_prepare (drv_cfg -> mem_reg , mem_slab_buffer ,
7982 drv_data -> block_size , & buffer );
8083 if (ret < 0 ) {
8184 LOG_ERR ("Failed to prepare buffer: %d" , ret );
85+ free_buffer (drv_data , mem_slab_buffer );
86+ stop_pdm (drv_data );
87+ return ;
88+ }
89+ ret = k_msgq_put (& drv_data -> mem_slab_queue , & mem_slab_buffer , K_NO_WAIT );
90+ if (ret < 0 ) {
91+ LOG_ERR ("Unable to put mem slab in queue" );
92+ free_buffer (drv_data , mem_slab_buffer );
8293 stop_pdm (drv_data );
8394 return ;
8495 }
@@ -92,14 +103,18 @@ static void event_handler(const struct device *dev, const nrfx_pdm_evt_t *evt)
92103
93104 if (drv_data -> stopping ) {
94105 if (evt -> buffer_released ) {
95- ret = dmm_buffer_in_release (drv_cfg -> mem_reg , drv_data -> mem_slab_buffer ,
106+ ret = k_msgq_get (& drv_data -> mem_slab_queue , & mem_slab_buffer , K_NO_WAIT );
107+ if (ret < 0 ) {
108+ LOG_ERR ("No buffers to free" );
109+ return ;
110+ }
111+ ret = dmm_buffer_in_release (drv_cfg -> mem_reg , mem_slab_buffer ,
96112 drv_data -> block_size , evt -> buffer_released );
97113 if (ret < 0 ) {
98114 LOG_ERR ("Failed to release buffer: %d" , ret );
99- stop_pdm (drv_data );
100115 return ;
101116 }
102- free_buffer (drv_data );
117+ free_buffer (drv_data , mem_slab_buffer );
103118 }
104119
105120 if (drv_data -> active ) {
@@ -109,20 +124,26 @@ static void event_handler(const struct device *dev, const nrfx_pdm_evt_t *evt)
109124 }
110125 }
111126 } else if (evt -> buffer_released ) {
112- ret = dmm_buffer_in_release (drv_cfg -> mem_reg , drv_data -> mem_slab_buffer ,
127+ ret = k_msgq_get (& drv_data -> mem_slab_queue , & mem_slab_buffer , K_NO_WAIT );
128+ if (ret < 0 ) {
129+ LOG_ERR ("No buffers to free" );
130+ stop_pdm (drv_data );
131+ return ;
132+ }
133+ ret = dmm_buffer_in_release (drv_cfg -> mem_reg , mem_slab_buffer ,
113134 drv_data -> block_size , evt -> buffer_released );
114135 if (ret < 0 ) {
115136 LOG_ERR ("Failed to release buffer: %d" , ret );
116137 stop_pdm (drv_data );
117138 return ;
118139 }
119140 ret = k_msgq_put (& drv_data -> rx_queue ,
120- & drv_data -> mem_slab_buffer ,
141+ & mem_slab_buffer ,
121142 K_NO_WAIT );
122143 if (ret < 0 ) {
123144 LOG_ERR ("No room in RX queue" );
124145 stop = true;
125- free_buffer (drv_data );
146+ free_buffer (drv_data , mem_slab_buffer );
126147 } else {
127148 LOG_DBG ("Queued buffer %p" , evt -> buffer_released );
128149 }
@@ -234,7 +255,7 @@ static bool check_pdm_frequencies(const struct dmic_nrfx_pdm_drv_cfg *drv_cfg,
234255
235256 if (is_in_freq_range (act_freq , pdm_cfg ) &&
236257 is_better (act_freq , ratio , req_rate , best_diff , best_rate , best_freq )) {
237- config -> clock_freq = clk_factor * 4096 ;
258+ config -> clock_freq = clk_factor * DMIC_NRFX_CLOCK_FACTOR ;
238259
239260 better_found = true;
240261 }
@@ -403,7 +424,6 @@ static int dmic_nrfx_pdm_configure(const struct device *dev,
403424
404425 channel -> act_num_streams = 1 ;
405426 channel -> act_chan_map_hi = 0 ;
406- channel -> act_chan_map_lo = def_map ;
407427
408428 if (channel -> req_num_streams != 1 ||
409429 channel -> req_num_chan > 2 ||
@@ -434,9 +454,13 @@ static int dmic_nrfx_pdm_configure(const struct device *dev,
434454 nrfx_cfg .mode = channel -> req_num_chan == 1
435455 ? NRF_PDM_MODE_MONO
436456 : NRF_PDM_MODE_STEREO ;
437- nrfx_cfg .edge = channel -> req_chan_map_lo == def_map
438- ? NRF_PDM_EDGE_LEFTFALLING
439- : NRF_PDM_EDGE_LEFTRISING ;
457+ if (channel -> req_chan_map_lo == def_map ) {
458+ nrfx_cfg .edge = NRF_PDM_EDGE_LEFTFALLING ;
459+ channel -> act_chan_map_lo = def_map ;
460+ } else {
461+ nrfx_cfg .edge = NRF_PDM_EDGE_LEFTRISING ;
462+ channel -> act_chan_map_lo = alt_map ;
463+ }
440464#if NRF_PDM_HAS_MCLKCONFIG
441465 nrfx_cfg .mclksrc = drv_cfg -> clk_src == ACLK
442466 ? NRF_PDM_MCLKSRC_ACLK
@@ -633,6 +657,7 @@ static const struct _dmic_ops dmic_ops = {
633657
634658#define PDM_NRFX_DEVICE (idx ) \
635659 static void *rx_msgs##idx[DT_PROP(PDM(idx), queue_size)]; \
660+ static void *mem_slab_msgs##idx[DT_PROP(PDM(idx), queue_size)]; \
636661 static struct dmic_nrfx_pdm_drv_data dmic_nrfx_pdm_data##idx; \
637662 static const nrfx_pdm_t dmic_nrfx_pdm##idx = NRFX_PDM_INSTANCE(idx); \
638663 static int pdm_nrfx_init##idx(const struct device *dev) \
@@ -649,6 +674,9 @@ static const struct _dmic_ops dmic_ops = {
649674 k_msgq_init(&dmic_nrfx_pdm_data##idx.rx_queue, \
650675 (char *)rx_msgs##idx, sizeof(void *), \
651676 ARRAY_SIZE(rx_msgs##idx)); \
677+ k_msgq_init(&dmic_nrfx_pdm_data##idx.mem_slab_queue, \
678+ (char *)mem_slab_msgs##idx, sizeof(void *), \
679+ ARRAY_SIZE(mem_slab_msgs##idx)); \
652680 IF_ENABLED(CONFIG_CLOCK_CONTROL_NRF, \
653681 (init_clock_manager(dev);)) \
654682 return 0; \
0 commit comments