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 ;
2027 struct onoff_client clk_cli ;
2128 struct k_mem_slab * mem_slab ;
29+ void * mem_slab_buffer ;
2230 uint32_t block_size ;
2331 struct k_msgq rx_queue ;
2432 bool request_clock : 1 ;
@@ -36,29 +44,44 @@ struct dmic_nrfx_pdm_drv_cfg {
3644 PCLK32M_HFXO ,
3745 ACLK
3846 } clk_src ;
47+ void * mem_reg ;
3948};
4049
41- static void free_buffer (struct dmic_nrfx_pdm_drv_data * drv_data , void * buffer )
50+ static void free_buffer (struct dmic_nrfx_pdm_drv_data * drv_data )
51+ {
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+ }
55+
56+ static void stop_pdm (struct dmic_nrfx_pdm_drv_data * drv_data )
4257{
43- k_mem_slab_free ( drv_data -> mem_slab , buffer ) ;
44- LOG_DBG ( "Freed buffer %p" , buffer );
58+ drv_data -> stopping = true ;
59+ nrfx_pdm_stop ( drv_data -> pdm );
4560}
4661
4762static void event_handler (const struct device * dev , const nrfx_pdm_evt_t * evt )
4863{
4964 struct dmic_nrfx_pdm_drv_data * drv_data = dev -> data ;
65+ const struct dmic_nrfx_pdm_drv_cfg * drv_cfg = dev -> config ;
5066 int ret ;
5167 bool stop = false;
5268
5369 if (evt -> buffer_requested ) {
5470 void * buffer ;
5571 nrfx_err_t err ;
5672
57- ret = k_mem_slab_alloc (drv_data -> mem_slab , & buffer , K_NO_WAIT );
73+ ret = k_mem_slab_alloc (drv_data -> mem_slab , & drv_data -> mem_slab_buffer , K_NO_WAIT );
5874 if (ret < 0 ) {
5975 LOG_ERR ("Failed to allocate buffer: %d" , ret );
6076 stop = true;
6177 } else {
78+ ret = dmm_buffer_in_prepare (drv_cfg -> mem_reg , drv_data -> mem_slab_buffer ,
79+ drv_data -> block_size , & buffer );
80+ if (ret < 0 ) {
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,7 +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 ) {
72- free_buffer (drv_data , evt -> buffer_released );
95+ ret = dmm_buffer_in_release (drv_cfg -> mem_reg , drv_data -> mem_slab_buffer ,
96+ drv_data -> block_size , evt -> buffer_released );
97+ if (ret < 0 ) {
98+ LOG_ERR ("Failed to release buffer: %d" , ret );
99+ stop_pdm (drv_data );
100+ return ;
101+ }
102+ free_buffer (drv_data );
73103 }
74104
75105 if (drv_data -> active ) {
@@ -79,22 +109,26 @@ static void event_handler(const struct device *dev, const nrfx_pdm_evt_t *evt)
79109 }
80110 }
81111 } else if (evt -> buffer_released ) {
112+ ret = dmm_buffer_in_release (drv_cfg -> mem_reg , drv_data -> mem_slab_buffer ,
113+ drv_data -> block_size , evt -> buffer_released );
114+ if (ret < 0 ) {
115+ LOG_ERR ("Failed to release buffer: %d" , ret );
116+ stop_pdm (drv_data );
117+ return ;
118+ }
82119 ret = k_msgq_put (& drv_data -> rx_queue ,
83- & evt -> buffer_released ,
120+ & drv_data -> mem_slab_buffer ,
84121 K_NO_WAIT );
85122 if (ret < 0 ) {
86123 LOG_ERR ("No room in RX queue" );
87124 stop = true;
88-
89- free_buffer (drv_data , evt -> buffer_released );
125+ free_buffer (drv_data );
90126 } else {
91127 LOG_DBG ("Queued buffer %p" , evt -> buffer_released );
92128 }
93129 }
94-
95130 if (stop ) {
96- drv_data -> stopping = true;
97- nrfx_pdm_stop (drv_data -> pdm );
131+ stop_pdm (drv_data );
98132 }
99133}
100134
@@ -168,7 +202,7 @@ static bool check_pdm_frequencies(const struct dmic_nrfx_pdm_drv_cfg *drv_cfg,
168202 better_found = true;
169203 }
170204#else
171- if (IS_ENABLED (CONFIG_SOC_SERIES_NRF53X )) {
205+ if (IS_ENABLED (CONFIG_SOC_SERIES_NRF53X ) || IS_ENABLED ( CONFIG_SOC_SERIES_NRF54HX ) ) {
172206 const uint32_t src_freq =
173207 (NRF_PDM_HAS_MCLKCONFIG && drv_cfg -> clk_src == ACLK )
174208 /* The DMIC_NRFX_PDM_DEVICE() macro contains build
@@ -180,9 +214,13 @@ static bool check_pdm_frequencies(const struct dmic_nrfx_pdm_drv_cfg *drv_cfg,
180214 * not defined (this expression will be eventually
181215 * optimized away then).
182216 */
217+ /* TODO : PS does not provide correct formula for nRF54H20 PDM_CLK.
218+ * Assume that master clock source frequency is 8 MHz. Remove once
219+ * correct formula is found.
220+ */
183221 ? DT_PROP_OR (DT_NODELABEL (clock ), hfclkaudio_frequency ,
184222 0 )
185- : 32 * 1000 * 1000UL ;
223+ : DMIC_NRFX_CLOCK_FREQ ;
186224 uint32_t req_freq = req_rate * ratio ;
187225 /* As specified in the nRF5340 PS:
188226 *
@@ -562,6 +600,7 @@ static int dmic_nrfx_pdm_read(const struct device *dev,
562600 return ret ;
563601}
564602
603+ #if CONFIG_CLOCK_CONTROL_NRF
565604static void init_clock_manager (const struct device * dev )
566605{
567606 struct dmic_nrfx_pdm_drv_data * drv_data = dev -> data ;
@@ -581,6 +620,7 @@ static void init_clock_manager(const struct device *dev)
581620 drv_data -> clk_mgr = z_nrf_clock_control_get_onoff (subsys );
582621 __ASSERT_NO_MSG (drv_data -> clk_mgr != NULL );
583622}
623+ #endif
584624
585625static const struct _dmic_ops dmic_ops = {
586626 .configure = dmic_nrfx_pdm_configure ,
@@ -609,7 +649,8 @@ static const struct _dmic_ops dmic_ops = {
609649 k_msgq_init(&dmic_nrfx_pdm_data##idx.rx_queue, \
610650 (char *)rx_msgs##idx, sizeof(void *), \
611651 ARRAY_SIZE(rx_msgs##idx)); \
612- init_clock_manager(dev); \
652+ IF_ENABLED(CONFIG_CLOCK_CONTROL_NRF, \
653+ (init_clock_manager(dev);)) \
613654 return 0; \
614655 } \
615656 static void event_handler##idx(const nrfx_pdm_evt_t *evt) \
@@ -624,6 +665,7 @@ static const struct _dmic_ops dmic_ops = {
624665 .nrfx_def_cfg.skip_psel_cfg = true, \
625666 .pcfg = PINCTRL_DT_DEV_CONFIG_GET(PDM(idx)), \
626667 .clk_src = PDM_CLK_SRC(idx), \
668+ .mem_reg = DMM_DEV_TO_REG(PDM(idx)), \
627669 }; \
628670 BUILD_ASSERT(PDM_CLK_SRC(idx) != ACLK || NRF_PDM_HAS_MCLKCONFIG, \
629671 "Clock source ACLK is not available."); \
0 commit comments