44 * SPDX-License-Identifier: Apache-2.0 
55 */ 
66
7+ #define  DT_DRV_COMPAT  nordic_nrf_i2s
8+ 
79#include  <stdlib.h> 
810#include  <zephyr/drivers/i2s.h> 
911#include  <zephyr/drivers/clock_control/nrf_clock_control.h> 
@@ -33,21 +35,20 @@ struct i2s_nrfx_drv_data {
3335	struct  k_msgq  tx_queue ;
3436	struct  stream_cfg  rx ;
3537	struct  k_msgq  rx_queue ;
36- 	const   nrfx_i2s_t  * p_i2s ;
38+ 	nrfx_i2s_t  i2s ;
3739	const  uint32_t  * last_tx_buffer ;
3840	enum  i2s_state  state ;
3941	enum  i2s_dir  active_dir ;
4042	bool  stop ;       /* stop after the current (TX or RX) block */ 
4143	bool  discard_rx ; /* discard further RX blocks */ 
4244	volatile  bool  next_tx_buffer_needed ;
43- 	bool  tx_configured   : 1 ;
44- 	bool  rx_configured   : 1 ;
45- 	bool  request_clock   : 1 ;
45+ 	bool  tx_configured : 1 ;
46+ 	bool  rx_configured : 1 ;
47+ 	bool  request_clock : 1 ;
4648};
4749
4850struct  i2s_nrfx_drv_cfg  {
4951	nrfx_i2s_data_handler_t  data_handler ;
50- 	nrfx_i2s_t  i2s ;
5152	nrfx_i2s_config_t  nrfx_def_cfg ;
5253	const  struct  pinctrl_dev_config  * pcfg ;
5354	enum  clock_source  {
@@ -81,7 +82,7 @@ static void find_suitable_clock(const struct i2s_nrfx_drv_cfg *drv_cfg,
8182		.allow_bypass  =  IS_ENABLED (CONFIG_I2S_NRFX_ALLOW_MCK_BYPASS ),
8283	};
8384
84- 	if  (nrfx_i2s_prescalers_calc (& clk_params , & config -> prescalers ) !=  NRFX_SUCCESS ) {
85+ 	if  (nrfx_i2s_prescalers_calc (& clk_params , & config -> prescalers ) !=  0 ) {
8586		LOG_ERR ("Failed to find suitable I2S clock configuration." );
8687	}
8788}
@@ -134,7 +135,7 @@ static bool supply_next_buffers(struct i2s_nrfx_drv_data *drv_data,
134135	if  (drv_data -> active_dir  !=  I2S_DIR_TX ) { /* -> RX active */ 
135136		if  (!get_next_rx_buffer (drv_data , next )) {
136137			drv_data -> state  =  I2S_STATE_ERROR ;
137- 			nrfx_i2s_stop (drv_data -> p_i2s );
138+ 			nrfx_i2s_stop (& drv_data -> i2s );
138139			return  false;
139140		}
140141		/* Set buffer size if there is no TX buffer (which effectively 
@@ -149,7 +150,7 @@ static bool supply_next_buffers(struct i2s_nrfx_drv_data *drv_data,
149150	drv_data -> last_tx_buffer  =  next -> p_tx_buffer ;
150151
151152	LOG_DBG ("Next buffers: %p/%p" , next -> p_tx_buffer , next -> p_rx_buffer );
152- 	nrfx_i2s_next_buffers_set (drv_data -> p_i2s , next );
153+ 	nrfx_i2s_next_buffers_set (& drv_data -> i2s , next );
153154	return  true;
154155}
155156
@@ -181,7 +182,7 @@ static void data_handler(const struct device *dev,
181182			}
182183			drv_data -> last_tx_buffer  =  NULL ;
183184		}
184- 		nrfx_i2s_uninit (drv_data -> p_i2s );
185+ 		nrfx_i2s_uninit (& drv_data -> i2s );
185186		if  (drv_data -> request_clock ) {
186187			(void )onoff_release (drv_data -> clk_mgr );
187188		}
@@ -198,7 +199,7 @@ static void data_handler(const struct device *dev,
198199			LOG_ERR ("Next buffers not supplied on time" );
199200			drv_data -> state  =  I2S_STATE_ERROR ;
200201		}
201- 		nrfx_i2s_stop (drv_data -> p_i2s );
202+ 		nrfx_i2s_stop (& drv_data -> i2s );
202203		return ;
203204	}
204205
@@ -248,7 +249,7 @@ static void data_handler(const struct device *dev,
248249	}
249250
250251	if  (stop_transfer ) {
251- 		nrfx_i2s_stop (drv_data -> p_i2s );
252+ 		nrfx_i2s_stop (& drv_data -> i2s );
252253	} else  if  (status  &  NRFX_I2S_STATUS_NEXT_BUFFERS_NEEDED ) {
253254		nrfx_i2s_buffers_t  next  =  { 0  };
254255
@@ -419,8 +420,8 @@ static int i2s_nrfx_configure(const struct device *dev, enum i2s_dir dir,
419420	 * the MCK output is used), find a suitable clock configuration for it. 
420421	 */ 
421422	if  (nrfx_cfg .mode  ==  NRF_I2S_MODE_MASTER  || 
422- 	    (nrf_i2s_mck_pin_get (drv_cfg -> i2s .p_reg ) &  I2S_PSEL_MCK_CONNECT_Msk )
423- 	     ==  I2S_PSEL_MCK_CONNECT_Connected  << I2S_PSEL_MCK_CONNECT_Pos ) {
423+ 	    (nrf_i2s_mck_pin_get (drv_data -> i2s .p_reg ) &  I2S_PSEL_MCK_CONNECT_Msk )  == 
424+ 		     I2S_PSEL_MCK_CONNECT_Connected  << I2S_PSEL_MCK_CONNECT_Pos ) {
424425		find_suitable_clock (drv_cfg , & nrfx_cfg , i2s_cfg );
425426		/* Unless the PCLK32M source is used with the HFINT oscillator 
426427		 * (which is always available without any additional actions), 
@@ -578,7 +579,7 @@ static int start_transfer(struct i2s_nrfx_drv_data *drv_data)
578579		/* Failed to allocate next RX buffer */ 
579580		ret  =  - ENOMEM ;
580581	} else  {
581- 		nrfx_err_t  err ;
582+ 		int  err ;
582583
583584		/* It is necessary to set buffer size here only for I2S_DIR_RX, 
584585		 * because only then the get_next_tx_buffer() call in the if 
@@ -591,16 +592,16 @@ static int start_transfer(struct i2s_nrfx_drv_data *drv_data)
591592
592593		drv_data -> last_tx_buffer  =  initial_buffers .p_tx_buffer ;
593594
594- 		err  =  nrfx_i2s_start (drv_data -> p_i2s , & initial_buffers , 0 );
595- 		if  (err  ==  NRFX_SUCCESS ) {
595+ 		err  =  nrfx_i2s_start (& drv_data -> i2s , & initial_buffers , 0 );
596+ 		if  (err  ==  0 ) {
596597			return  0 ;
597598		}
598599
599- 		LOG_ERR ("Failed to start I2S transfer: 0x%08x " , err );
600+ 		LOG_ERR ("Failed to start I2S transfer: %d " , err );
600601		ret  =  - EIO ;
601602	}
602603
603- 	nrfx_i2s_uninit (drv_data -> p_i2s );
604+ 	nrfx_i2s_uninit (& drv_data -> i2s );
604605	if  (drv_data -> request_clock ) {
605606		(void )onoff_release (drv_data -> clk_mgr );
606607	}
@@ -629,7 +630,7 @@ static void clock_started_callback(struct onoff_manager *mgr,
629630	 * the actual transfer in such case. 
630631	 */ 
631632	if  (drv_data -> state  ==  I2S_STATE_READY ) {
632- 		nrfx_i2s_uninit (drv_data -> p_i2s );
633+ 		nrfx_i2s_uninit (& drv_data -> i2s );
633634		(void )onoff_release (drv_data -> clk_mgr );
634635	} else  {
635636		(void )start_transfer (drv_data );
@@ -640,22 +641,22 @@ static int trigger_start(const struct device *dev)
640641{
641642	struct  i2s_nrfx_drv_data  * drv_data  =  dev -> data ;
642643	const  struct  i2s_nrfx_drv_cfg  * drv_cfg  =  dev -> config ;
643- 	nrfx_err_t  err ;
644+ 	int  err ;
644645	int  ret ;
645646	const  nrfx_i2s_config_t  * nrfx_cfg  =  (drv_data -> active_dir  ==  I2S_DIR_TX )
646647					    ? & drv_data -> tx .nrfx_cfg 
647648					    : & drv_data -> rx .nrfx_cfg ;
648649
649- 	err  =  nrfx_i2s_init (drv_data -> p_i2s , nrfx_cfg , drv_cfg -> data_handler );
650- 	if  (err  !=  NRFX_SUCCESS ) {
651- 		LOG_ERR ("Failed to initialize I2S: 0x%08x " , err );
650+ 	err  =  nrfx_i2s_init (& drv_data -> i2s , nrfx_cfg , drv_cfg -> data_handler );
651+ 	if  (err  !=  0 ) {
652+ 		LOG_ERR ("Failed to initialize I2S: %d " , err );
652653		return  - EIO ;
653654	}
654655
655656	drv_data -> state  =  I2S_STATE_RUNNING ;
656657
657658#if  NRF_I2S_HAS_CLKCONFIG 
658- 	nrf_i2s_clk_configure (drv_cfg -> i2s .p_reg ,
659+ 	nrf_i2s_clk_configure (drv_data -> i2s .p_reg ,
659660			      drv_cfg -> clk_src  ==  ACLK  ? NRF_I2S_CLKSRC_ACLK 
660661						       : NRF_I2S_CLKSRC_PCLK32M ,
661662			      nrfx_cfg -> prescalers .enable_bypass );
@@ -669,7 +670,7 @@ static int trigger_start(const struct device *dev)
669670					 clock_started_callback );
670671		ret  =  onoff_request (drv_data -> clk_mgr , & drv_data -> clk_cli );
671672		if  (ret  <  0 ) {
672- 			nrfx_i2s_uninit (drv_data -> p_i2s );
673+ 			nrfx_i2s_uninit (& drv_data -> i2s );
673674			drv_data -> state  =  I2S_STATE_READY ;
674675
675676			LOG_ERR ("Failed to request clock: %d" , ret );
@@ -776,7 +777,7 @@ static int i2s_nrfx_trigger(const struct device *dev,
776777	case  I2S_TRIGGER_DROP :
777778		if  (drv_data -> state  !=  I2S_STATE_READY ) {
778779			drv_data -> discard_rx  =  true;
779- 			nrfx_i2s_stop (drv_data -> p_i2s );
780+ 			nrfx_i2s_stop (& drv_data -> i2s );
780781		}
781782		purge_queue (dev , dir );
782783		drv_data -> state  =  I2S_STATE_READY ;
@@ -821,72 +822,56 @@ static DEVICE_API(i2s, i2s_nrf_drv_api) = {
821822	.trigger  =  i2s_nrfx_trigger ,
822823};
823824
824- #define  I2S (idx ) DT_NODELABEL(i2s##idx)
825- #define  I2S_CLK_SRC (idx ) DT_STRING_TOKEN(I2S(idx), clock_source)
826- 
827- #define  I2S_NRFX_DEVICE (idx )						     \
828- 	static struct i2s_buf tx_msgs##idx[CONFIG_I2S_NRFX_TX_BLOCK_COUNT];  \
829- 	static struct i2s_buf rx_msgs##idx[CONFIG_I2S_NRFX_RX_BLOCK_COUNT];  \
830- 	static void data_handler##idx(nrfx_i2s_buffers_t const *p_released,  \
831- 				      uint32_t status)			     \
832- 	{								     \
833- 		data_handler(DEVICE_DT_GET(I2S(idx)), p_released, status);   \
834- 	}								     \
835- 	PINCTRL_DT_DEFINE(I2S(idx));					     \
836- 	static const struct i2s_nrfx_drv_cfg i2s_nrfx_cfg##idx = {	     \
837- 		.data_handler = data_handler##idx,			     \
838- 		.i2s = NRFX_I2S_INSTANCE(idx),				     \
839- 		.nrfx_def_cfg = NRFX_I2S_DEFAULT_CONFIG(		     \
840- 			NRF_I2S_PIN_NOT_CONNECTED,			     \
841- 			NRF_I2S_PIN_NOT_CONNECTED,			     \
842- 			NRF_I2S_PIN_NOT_CONNECTED,			     \
843- 			NRF_I2S_PIN_NOT_CONNECTED,			     \
844- 			NRF_I2S_PIN_NOT_CONNECTED),			     \
845- 		.nrfx_def_cfg.skip_gpio_cfg = true,			     \
846- 		.nrfx_def_cfg.skip_psel_cfg = true,			     \
847- 		.pcfg = PINCTRL_DT_DEV_CONFIG_GET(I2S(idx)),		     \
848- 		.clk_src = I2S_CLK_SRC(idx),				     \
849- 	};								     \
850- 	static struct i2s_nrfx_drv_data i2s_nrfx_data##idx = {		     \
851- 		.state = I2S_STATE_READY,				     \
852- 		.p_i2s = &i2s_nrfx_cfg##idx.i2s				     \
853- 	};								     \
854- 	static int i2s_nrfx_init##idx(const struct device *dev)		     \
855- 	{								     \
856- 		IRQ_CONNECT(DT_IRQN(I2S(idx)), DT_IRQ(I2S(idx), priority),   \
857- 			    nrfx_isr, nrfx_i2s_##idx##_irq_handler, 0);	     \
858- 		const struct i2s_nrfx_drv_cfg *drv_cfg = dev->config;	     \
859- 		int err = pinctrl_apply_state(drv_cfg->pcfg,		     \
860- 					      PINCTRL_STATE_DEFAULT);	     \
861- 		if (err < 0) {						     \
862- 			return err;					     \
863- 		}							     \
864- 		k_msgq_init(&i2s_nrfx_data##idx.tx_queue,		     \
865- 			    (char *)tx_msgs##idx, sizeof(struct i2s_buf),    \
866- 			    ARRAY_SIZE(tx_msgs##idx));			     \
867- 		k_msgq_init(&i2s_nrfx_data##idx.rx_queue,		     \
868- 			    (char *)rx_msgs##idx, sizeof(struct i2s_buf),    \
869- 			    ARRAY_SIZE(rx_msgs##idx));			     \
870- 		init_clock_manager(dev);				     \
871- 		return 0;						     \
872- 	}								     \
873- 	BUILD_ASSERT(I2S_CLK_SRC(idx) != ACLK ||			     \
874- 		     (NRF_I2S_HAS_CLKCONFIG && NRF_CLOCK_HAS_HFCLKAUDIO),    \
875- 		"Clock source ACLK is not available.");			     \
876- 	BUILD_ASSERT(I2S_CLK_SRC(idx) != ACLK ||			     \
877- 		     DT_NODE_HAS_PROP(DT_NODELABEL(clock),		     \
878- 				      hfclkaudio_frequency),		     \
879- 		"Clock source ACLK requires the hfclkaudio-frequency "	     \
880- 		"property to be defined in the nordic,nrf-clock node.");     \
881- 	DEVICE_DT_DEFINE(I2S(idx), i2s_nrfx_init##idx, NULL,		     \
882- 			 &i2s_nrfx_data##idx, &i2s_nrfx_cfg##idx,	     \
883- 			 POST_KERNEL, CONFIG_I2S_INIT_PRIORITY,		     \
884- 			 &i2s_nrf_drv_api);
885- 
886- #ifdef  CONFIG_HAS_HW_NRF_I2S0 
887- I2S_NRFX_DEVICE (0 );
888- #endif 
889- 
890- #ifdef  CONFIG_HAS_HW_NRF_I2S20 
891- I2S_NRFX_DEVICE (20 );
892- #endif 
825+ #define  I2S_CLK_SRC (inst ) DT_STRING_TOKEN(DT_DRV_INST(inst), clock_source)
826+ 
827+ #define  I2S_NRFX_DEVICE (inst )                                                                      \
828+ 	static struct i2s_buf tx_msgs##inst[CONFIG_I2S_NRFX_TX_BLOCK_COUNT];                       \
829+ 	static struct i2s_buf rx_msgs##inst[CONFIG_I2S_NRFX_RX_BLOCK_COUNT];                       \
830+ 	static void data_handler##inst(nrfx_i2s_buffers_t const *p_released, uint32_t status)      \
831+ 	{                                                                                          \
832+ 		data_handler(DEVICE_DT_GET(DT_DRV_INST(inst)), p_released, status);                \
833+ 	}                                                                                          \
834+ 	PINCTRL_DT_DEFINE(DT_DRV_INST(inst));                                                      \
835+ 	static const struct i2s_nrfx_drv_cfg i2s_nrfx_cfg##inst = {                                \
836+ 		.data_handler = data_handler##inst,                                                \
837+ 		.nrfx_def_cfg = NRFX_I2S_DEFAULT_CONFIG(                                           \
838+ 			NRF_I2S_PIN_NOT_CONNECTED, NRF_I2S_PIN_NOT_CONNECTED,                      \
839+ 			NRF_I2S_PIN_NOT_CONNECTED, NRF_I2S_PIN_NOT_CONNECTED,                      \
840+ 			NRF_I2S_PIN_NOT_CONNECTED),                                                \
841+ 		.nrfx_def_cfg.skip_gpio_cfg = true,                                                \
842+ 		.nrfx_def_cfg.skip_psel_cfg = true,                                                \
843+ 		.pcfg = PINCTRL_DT_DEV_CONFIG_GET(DT_DRV_INST(inst)),                              \
844+ 		.clk_src = I2S_CLK_SRC(inst),                                                      \
845+ 	};                                                                                         \
846+ 	static struct i2s_nrfx_drv_data i2s_nrfx_data##inst = {                                    \
847+ 		.state = I2S_STATE_READY,                                                          \
848+ 		.i2s = NRFX_I2S_INSTANCE(DT_INST_REG_ADDR(inst)),                                  \
849+ 	};                                                                                         \
850+ 	static int i2s_nrfx_init##inst(const struct device *dev)                                   \
851+ 	{                                                                                          \
852+ 		IRQ_CONNECT(DT_INST_IRQN(inst), DT_INST_IRQ(inst, priority), nrfx_i2s_irq_handler, \
853+ 			    &i2s_nrfx_data##inst.i2s, 0);                                          \
854+ 		const struct i2s_nrfx_drv_cfg *drv_cfg = dev->config;                              \
855+ 		int err = pinctrl_apply_state(drv_cfg->pcfg, PINCTRL_STATE_DEFAULT);               \
856+ 		if (err < 0) {                                                                     \
857+ 			return err;                                                                \
858+ 		}                                                                                  \
859+ 		k_msgq_init(&i2s_nrfx_data##inst.tx_queue, (char *)tx_msgs##inst,                  \
860+ 			    sizeof(struct i2s_buf), ARRAY_SIZE(tx_msgs##inst));                    \
861+ 		k_msgq_init(&i2s_nrfx_data##inst.rx_queue, (char *)rx_msgs##inst,                  \
862+ 			    sizeof(struct i2s_buf), ARRAY_SIZE(rx_msgs##inst));                    \
863+ 		init_clock_manager(dev);                                                           \
864+ 		return 0;                                                                          \
865+ 	}                                                                                          \
866+ 	BUILD_ASSERT(I2S_CLK_SRC(inst) != ACLK ||                                                  \
867+ 			     (NRF_I2S_HAS_CLKCONFIG && NRF_CLOCK_HAS_HFCLKAUDIO),                  \
868+ 		     "Clock source ACLK is not available.");                                       \
869+ 	BUILD_ASSERT(I2S_CLK_SRC(inst) != ACLK ||                                                  \
870+ 			     DT_NODE_HAS_PROP(DT_NODELABEL(clock), hfclkaudio_frequency),          \
871+ 		     "Clock source ACLK requires the hfclkaudio-frequency "                        \
872+ 		     "property to be defined in the nordic,nrf-clock node.");                      \
873+ 	DEVICE_DT_INST_DEFINE(inst, i2s_nrfx_init##inst, NULL, &i2s_nrfx_data##inst,               \
874+ 			      &i2s_nrfx_cfg##inst, POST_KERNEL, CONFIG_I2S_INIT_PRIORITY,          \
875+ 			      &i2s_nrf_drv_api);
876+ 
877+ DT_INST_FOREACH_STATUS_OKAY (I2S_NRFX_DEVICE )
0 commit comments