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>
@@ -36,6 +37,7 @@ struct dmic_nrfx_pdm_drv_cfg {
3637 PCLK32M_HFXO ,
3738 ACLK
3839 } clk_src ;
40+ void * mem_reg ;
3941};
4042
4143static void free_buffer (struct dmic_nrfx_pdm_drv_data * drv_data , void * buffer )
@@ -47,6 +49,7 @@ static void free_buffer(struct dmic_nrfx_pdm_drv_data *drv_data, void *buffer)
4749static void event_handler (const struct device * dev , const nrfx_pdm_evt_t * evt )
4850{
4951 struct dmic_nrfx_pdm_drv_data * drv_data = dev -> data ;
52+ const struct dmic_nrfx_pdm_drv_cfg * drv_cfg = dev -> config ;
5053 int ret ;
5154 bool stop = false;
5255
@@ -59,6 +62,14 @@ static void event_handler(const struct device *dev, const nrfx_pdm_evt_t *evt)
5962 LOG_ERR ("Failed to allocate buffer: %d" , ret );
6063 stop = true;
6164 } else {
65+ ret = dmm_buffer_in_prepare (drv_cfg -> mem_reg , & buffer ,
66+ drv_data -> block_size ,
67+ (void * )drv_data -> mem_slab -> buffer );
68+ if (ret ) {
69+ LOG_ERR ("Failed to prepare buffer: %d" , ret );
70+ stop = true;
71+ goto stop_pdm ;
72+ }
6273 err = nrfx_pdm_buffer_set (drv_data -> pdm , buffer , drv_data -> block_size / 2 );
6374 if (err != NRFX_SUCCESS ) {
6475 LOG_ERR ("Failed to set buffer: 0x%08x" , err );
@@ -69,6 +80,14 @@ static void event_handler(const struct device *dev, const nrfx_pdm_evt_t *evt)
6980
7081 if (drv_data -> stopping ) {
7182 if (evt -> buffer_released ) {
83+ ret = dmm_buffer_in_release (drv_cfg -> mem_reg , evt -> buffer_released ,
84+ drv_data -> block_size ,
85+ (void * )drv_data -> mem_slab -> buffer );
86+ if (ret ) {
87+ LOG_ERR ("Failed to release buffer: %d" , ret );
88+ stop = true;
89+ goto stop_pdm ;
90+ }
7291 free_buffer (drv_data , evt -> buffer_released );
7392 }
7493
@@ -85,13 +104,19 @@ static void event_handler(const struct device *dev, const nrfx_pdm_evt_t *evt)
85104 if (ret < 0 ) {
86105 LOG_ERR ("No room in RX queue" );
87106 stop = true;
88-
107+ ret = dmm_buffer_in_release (drv_cfg -> mem_reg , evt -> buffer_released ,
108+ drv_data -> block_size ,
109+ (void * )drv_data -> mem_slab -> buffer );
110+ if (ret ) {
111+ LOG_ERR ("Failed to release buffer: %d" , ret );
112+ goto stop_pdm ;
113+ }
89114 free_buffer (drv_data , evt -> buffer_released );
90115 } else {
91116 LOG_DBG ("Queued buffer %p" , evt -> buffer_released );
92117 }
93118 }
94-
119+ stop_pdm :
95120 if (stop ) {
96121 drv_data -> stopping = true;
97122 nrfx_pdm_stop (drv_data -> pdm );
@@ -168,7 +193,7 @@ static bool check_pdm_frequencies(const struct dmic_nrfx_pdm_drv_cfg *drv_cfg,
168193 better_found = true;
169194 }
170195#else
171- if (IS_ENABLED (CONFIG_SOC_SERIES_NRF53X )) {
196+ if (IS_ENABLED (CONFIG_SOC_SERIES_NRF53X ) || IS_ENABLED ( CONFIG_SOC_SERIES_NRF54HX ) ) {
172197 const uint32_t src_freq =
173198 (NRF_PDM_HAS_MCLKCONFIG && drv_cfg -> clk_src == ACLK )
174199 /* The DMIC_NRFX_PDM_DEVICE() macro contains build
@@ -180,9 +205,14 @@ static bool check_pdm_frequencies(const struct dmic_nrfx_pdm_drv_cfg *drv_cfg,
180205 * not defined (this expression will be eventually
181206 * optimized away then).
182207 */
208+ /* TODO : PS does not provide correct formula for nRF54H20 PDM_CLK.
209+ * Assume that master clock source frequency is 8 MHz. Remove once
210+ * correct formula is found.
211+ */
183212 ? DT_PROP_OR (DT_NODELABEL (clock ), hfclkaudio_frequency ,
184213 0 )
185- : 32 * 1000 * 1000UL ;
214+ : COND_CODE_1 (IS_ENABLED (CONFIG_SOC_SERIES_NRF54HX ),
215+ (8 * 1000 * 1000UL ), (32 * 1000 * 1000UL ));
186216 uint32_t req_freq = req_rate * ratio ;
187217 /* As specified in the nRF5340 PS:
188218 *
@@ -562,6 +592,7 @@ static int dmic_nrfx_pdm_read(const struct device *dev,
562592 return ret ;
563593}
564594
595+ #if CONFIG_CLOCK_CONTROL_NRF
565596static void init_clock_manager (const struct device * dev )
566597{
567598 struct dmic_nrfx_pdm_drv_data * drv_data = dev -> data ;
@@ -581,6 +612,7 @@ static void init_clock_manager(const struct device *dev)
581612 drv_data -> clk_mgr = z_nrf_clock_control_get_onoff (subsys );
582613 __ASSERT_NO_MSG (drv_data -> clk_mgr != NULL );
583614}
615+ #endif
584616
585617static const struct _dmic_ops dmic_ops = {
586618 .configure = dmic_nrfx_pdm_configure ,
@@ -609,7 +641,8 @@ static const struct _dmic_ops dmic_ops = {
609641 k_msgq_init(&dmic_nrfx_pdm_data##idx.rx_queue, \
610642 (char *)rx_msgs##idx, sizeof(void *), \
611643 ARRAY_SIZE(rx_msgs##idx)); \
612- init_clock_manager(dev); \
644+ IF_ENABLED(CONFIG_CLOCK_CONTROL_NRF, \
645+ (init_clock_manager(dev);)) \
613646 return 0; \
614647 } \
615648 static void event_handler##idx(const nrfx_pdm_evt_t *evt) \
@@ -624,6 +657,7 @@ static const struct _dmic_ops dmic_ops = {
624657 .nrfx_def_cfg.skip_psel_cfg = true, \
625658 .pcfg = PINCTRL_DT_DEV_CONFIG_GET(PDM(idx)), \
626659 .clk_src = PDM_CLK_SRC(idx), \
660+ .mem_reg = DMM_DEV_TO_REG(PDM(idx)), \
627661 }; \
628662 BUILD_ASSERT(PDM_CLK_SRC(idx) != ACLK || NRF_PDM_HAS_MCLKCONFIG, \
629663 "Clock source ACLK is not available."); \
0 commit comments