88#include <zephyr/drivers/clock_control/nrf_clock_control.h>
99#include <zephyr/drivers/pinctrl.h>
1010#include <soc.h>
11+ #include <dmm.h>
1112#include <nrfx_pdm.h>
1213
1314#include <zephyr/logging/log.h>
1415#include <zephyr/irq.h>
1516LOG_MODULE_REGISTER (dmic_nrfx_pdm , CONFIG_AUDIO_DMIC_LOG_LEVEL );
1617
18+ #if CONFIG_SOC_SERIES_NRF54HX
19+ #define DMIC_NRFX_CLOCK_FREQ 8*1000*1000UL
20+ #else
21+ #define DMIC_NRFX_CLOCK_FREQ 32*1000*1000UL
22+ #endif
23+
1724struct dmic_nrfx_pdm_drv_data {
1825 const nrfx_pdm_t * pdm ;
1926 struct onoff_manager * clk_mgr ;
@@ -36,6 +43,7 @@ struct dmic_nrfx_pdm_drv_cfg {
3643 PCLK32M_HFXO ,
3744 ACLK
3845 } clk_src ;
46+ void * mem_reg ;
3947};
4048
4149static void free_buffer (struct dmic_nrfx_pdm_drv_data * drv_data , void * buffer )
@@ -44,9 +52,16 @@ static void free_buffer(struct dmic_nrfx_pdm_drv_data *drv_data, void *buffer)
4452 LOG_DBG ("Freed buffer %p" , buffer );
4553}
4654
55+ static void stop_pdm (struct dmic_nrfx_pdm_drv_data * drv_data )
56+ {
57+ drv_data -> stopping = true;
58+ nrfx_pdm_stop (drv_data -> pdm );
59+ }
60+
4761static void event_handler (const struct device * dev , const nrfx_pdm_evt_t * evt )
4862{
4963 struct dmic_nrfx_pdm_drv_data * drv_data = dev -> data ;
64+ const struct dmic_nrfx_pdm_drv_cfg * drv_cfg = dev -> config ;
5065 int ret ;
5166 bool stop = false;
5267
@@ -59,6 +74,14 @@ static void event_handler(const struct device *dev, const nrfx_pdm_evt_t *evt)
5974 LOG_ERR ("Failed to allocate buffer: %d" , ret );
6075 stop = true;
6176 } else {
77+ ret = dmm_buffer_in_prepare (drv_cfg -> mem_reg , & buffer ,
78+ drv_data -> block_size ,
79+ (void * )drv_data -> mem_slab -> buffer );
80+ if (ret ) {
81+ LOG_ERR ("Failed to prepare buffer: %d" , ret );
82+ stop_pdm (drv_data );
83+ return ;
84+ }
6285 err = nrfx_pdm_buffer_set (drv_data -> pdm , buffer , drv_data -> block_size / 2 );
6386 if (err != NRFX_SUCCESS ) {
6487 LOG_ERR ("Failed to set buffer: 0x%08x" , err );
@@ -69,6 +92,14 @@ static void event_handler(const struct device *dev, const nrfx_pdm_evt_t *evt)
6992
7093 if (drv_data -> stopping ) {
7194 if (evt -> buffer_released ) {
95+ ret = dmm_buffer_in_release (drv_cfg -> mem_reg , evt -> buffer_released ,
96+ drv_data -> block_size ,
97+ (void * )drv_data -> mem_slab -> buffer );
98+ if (ret ) {
99+ LOG_ERR ("Failed to release buffer: %d" , ret );
100+ stop_pdm (drv_data );
101+ return ;
102+ }
72103 free_buffer (drv_data , evt -> buffer_released );
73104 }
74105
@@ -85,16 +116,21 @@ static void event_handler(const struct device *dev, const nrfx_pdm_evt_t *evt)
85116 if (ret < 0 ) {
86117 LOG_ERR ("No room in RX queue" );
87118 stop = true;
88-
119+ ret = dmm_buffer_in_release (drv_cfg -> mem_reg , evt -> buffer_released ,
120+ drv_data -> block_size ,
121+ (void * )drv_data -> mem_slab -> buffer );
122+ if (ret ) {
123+ LOG_ERR ("Failed to release buffer: %d" , ret );
124+ stop_pdm (drv_data );
125+ return ;
126+ }
89127 free_buffer (drv_data , evt -> buffer_released );
90128 } else {
91129 LOG_DBG ("Queued buffer %p" , evt -> buffer_released );
92130 }
93131 }
94-
95132 if (stop ) {
96- drv_data -> stopping = true;
97- nrfx_pdm_stop (drv_data -> pdm );
133+ stop_pdm (drv_data );
98134 }
99135}
100136
@@ -168,7 +204,7 @@ static bool check_pdm_frequencies(const struct dmic_nrfx_pdm_drv_cfg *drv_cfg,
168204 better_found = true;
169205 }
170206#else
171- if (IS_ENABLED (CONFIG_SOC_SERIES_NRF53X )) {
207+ if (IS_ENABLED (CONFIG_SOC_SERIES_NRF53X ) || IS_ENABLED ( CONFIG_SOC_SERIES_NRF54HX ) ) {
172208 const uint32_t src_freq =
173209 (NRF_PDM_HAS_MCLKCONFIG && drv_cfg -> clk_src == ACLK )
174210 /* The DMIC_NRFX_PDM_DEVICE() macro contains build
@@ -180,9 +216,13 @@ static bool check_pdm_frequencies(const struct dmic_nrfx_pdm_drv_cfg *drv_cfg,
180216 * not defined (this expression will be eventually
181217 * optimized away then).
182218 */
219+ /* TODO : PS does not provide correct formula for nRF54H20 PDM_CLK.
220+ * Assume that master clock source frequency is 8 MHz. Remove once
221+ * correct formula is found.
222+ */
183223 ? DT_PROP_OR (DT_NODELABEL (clock ), hfclkaudio_frequency ,
184224 0 )
185- : 32 * 1000 * 1000UL ;
225+ : DMIC_NRFX_CLOCK_FREQ ;
186226 uint32_t req_freq = req_rate * ratio ;
187227 /* As specified in the nRF5340 PS:
188228 *
@@ -562,6 +602,7 @@ static int dmic_nrfx_pdm_read(const struct device *dev,
562602 return ret ;
563603}
564604
605+ #if CONFIG_CLOCK_CONTROL_NRF
565606static void init_clock_manager (const struct device * dev )
566607{
567608 struct dmic_nrfx_pdm_drv_data * drv_data = dev -> data ;
@@ -581,6 +622,7 @@ static void init_clock_manager(const struct device *dev)
581622 drv_data -> clk_mgr = z_nrf_clock_control_get_onoff (subsys );
582623 __ASSERT_NO_MSG (drv_data -> clk_mgr != NULL );
583624}
625+ #endif
584626
585627static const struct _dmic_ops dmic_ops = {
586628 .configure = dmic_nrfx_pdm_configure ,
@@ -609,7 +651,8 @@ static const struct _dmic_ops dmic_ops = {
609651 k_msgq_init(&dmic_nrfx_pdm_data##idx.rx_queue, \
610652 (char *)rx_msgs##idx, sizeof(void *), \
611653 ARRAY_SIZE(rx_msgs##idx)); \
612- init_clock_manager(dev); \
654+ IF_ENABLED(CONFIG_CLOCK_CONTROL_NRF, \
655+ (init_clock_manager(dev);)) \
613656 return 0; \
614657 } \
615658 static void event_handler##idx(const nrfx_pdm_evt_t *evt) \
@@ -624,6 +667,7 @@ static const struct _dmic_ops dmic_ops = {
624667 .nrfx_def_cfg.skip_psel_cfg = true, \
625668 .pcfg = PINCTRL_DT_DEV_CONFIG_GET(PDM(idx)), \
626669 .clk_src = PDM_CLK_SRC(idx), \
670+ .mem_reg = DMM_DEV_TO_REG(PDM(idx)), \
627671 }; \
628672 BUILD_ASSERT(PDM_CLK_SRC(idx) != ACLK || NRF_PDM_HAS_MCLKCONFIG, \
629673 "Clock source ACLK is not available."); \
0 commit comments