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