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