1 /*
2  * Copyright (c) 2021-2023 HPMicro
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  *
6  */
7 
8 #ifndef HPM_I2S_DRV_H
9 #define HPM_I2S_DRV_H
10 #include "hpm_common.h"
11 #include "hpm_soc_feature.h"
12 #include "hpm_i2s_regs.h"
13 #include "hpm_i2s_common.h"
14 
15 /**
16  * @brief I2S driver APIs
17  * @defgroup i2s_interface I2S driver APIs
18  * @ingroup io_interfaces
19  * @{
20  */
21 
22 /**
23  * @brief I2S data line
24  */
25 #define I2S_DATA_LINE_0 (0U)
26 #define I2S_DATA_LINE_1 (1U)
27 #define I2S_DATA_LINE_2 (2U)
28 #define I2S_DATA_LINE_3 (3U)
29 #define I2S_DATA_LINE_MAX I2S_DATA_LINE_3
30 
31 /**
32  * @brief I2S config
33  */
34 typedef struct i2s_config {
35     bool invert_mclk_out;
36     bool invert_mclk_in;
37     bool use_external_mclk;
38     bool invert_bclk_out;
39     bool invert_bclk_in;
40     bool use_external_bclk;
41     bool invert_fclk_out;
42     bool invert_fclk_in;
43     bool use_external_fclk;
44     bool enable_mclk_out;
45     bool frame_start_at_rising_edge;
46     uint16_t tx_fifo_threshold;
47     uint16_t rx_fifo_threshold;
48 } i2s_config_t;
49 
50 /**
51  * @brief I2S transfer config
52  */
53 typedef struct i2x_transfer_config {
54     uint32_t sample_rate;
55     bool enable_tdm_mode;
56     uint8_t channel_num_per_frame;
57     uint8_t channel_length;          /* 16-bit or 32-bit */
58     uint8_t audio_depth;             /* 16-bit, 24-bit, 32-bit */
59     bool master_mode;
60     uint8_t protocol;
61     uint8_t data_line;
62     uint32_t channel_slot_mask;
63 } i2s_transfer_config_t;
64 
65 typedef enum {
66     i2s_tx_fifo_threshold_irq_mask = I2S_CTRL_TXDNIE_MASK,
67     i2s_rx_fifo_threshold_irq_mask = I2S_CTRL_RXDAIE_MASK,
68     i2s_fifo_error_irq_mask = I2S_CTRL_ERRIE_MASK, /*<! rx fifo overrun, tx fifo underrun */
69 } i2s_irq_mask_t;
70 
71 typedef enum {
72     i2s_data_line_rx_fifo_avail = 1U, /*<! data avail */
73     i2s_data_line_tx_fifo_avail = 2U, /*<! fifo empty avail */
74     i2s_data_line_rx_fifo_overrun = 4U,
75     i2s_data_line_tx_fifo_underrun = 8U,
76 } i2s_data_line_stat_t;
77 
78 #ifdef __cplusplus
79 extern "C" {
80 #endif
81 
82 /**
83  * @brief enable TDM
84  *
85  * @param [in] ptr I2S base address
86  */
i2s_enable_tdm(I2S_Type * ptr)87 static inline void i2s_enable_tdm(I2S_Type *ptr)
88 {
89     ptr->CFGR |= I2S_CFGR_TDM_EN_MASK;
90 }
91 
92 /**
93  * @brief disable TDM
94  *
95  * @param [in] ptr I2S base address
96  */
i2s_disable_tdm(I2S_Type * ptr)97 static inline void i2s_disable_tdm(I2S_Type *ptr)
98 {
99     ptr->CFGR &= ~I2S_CFGR_TDM_EN_MASK;
100 }
101 
102 /**
103  * @brief update rx fifo threshold
104  *
105  * @param [in] ptr I2S base address
106  * @param [in] threshold fifo threshold value
107  */
i2s_update_rx_fifo_threshold(I2S_Type * ptr,uint8_t threshold)108 static inline void i2s_update_rx_fifo_threshold(I2S_Type *ptr, uint8_t threshold)
109 {
110     ptr->FIFO_THRESH = (ptr->FIFO_THRESH & ~I2S_FIFO_THRESH_RX_MASK)
111         | I2S_FIFO_THRESH_RX_SET(threshold);
112 }
113 
114 /**
115  * @brief update tx fifo threshold
116  *
117  * @param [in] ptr I2S base address
118  * @param [in] threshold fifo threshold value
119  */
i2s_update_tx_fifo_threshold(I2S_Type * ptr,uint8_t threshold)120 static inline void i2s_update_tx_fifo_threshold(I2S_Type *ptr, uint8_t threshold)
121 {
122     ptr->FIFO_THRESH = (ptr->FIFO_THRESH & ~I2S_FIFO_THRESH_TX_MASK)
123         | I2S_FIFO_THRESH_TX_SET(threshold);
124 }
125 
126 /**
127  * @brief open BCLK
128  *
129  * @param [in] ptr I2S base address
130  */
i2s_ungate_bclk(I2S_Type * ptr)131 static inline void i2s_ungate_bclk(I2S_Type *ptr)
132 {
133     ptr->CFGR &= ~I2S_CFGR_BCLK_GATEOFF_MASK;
134 }
135 
136 /**
137  * @brief gete off BCLK
138  *
139  * @param [in] ptr I2S base address
140  */
i2s_gate_bclk(I2S_Type * ptr)141 static inline void i2s_gate_bclk(I2S_Type *ptr)
142 {
143     ptr->CFGR |= I2S_CFGR_BCLK_GATEOFF_MASK;
144 }
145 
146 /**
147  * @brief open MCLK
148  *
149  * @param [in] ptr I2S base address
150  */
i2s_ungate_mclk(I2S_Type * ptr)151 static inline void i2s_ungate_mclk(I2S_Type *ptr)
152 {
153     ptr->MISC_CFGR &= ~I2S_MISC_CFGR_MCLK_GATEOFF_MASK;
154 }
155 
156 /**
157  * @brief gate off MCLK
158  *
159  * @param [in] ptr I2S base address
160  */
i2s_gate_mclk(I2S_Type * ptr)161 static inline void i2s_gate_mclk(I2S_Type *ptr)
162 {
163     ptr->MISC_CFGR |= I2S_MISC_CFGR_MCLK_GATEOFF_MASK;
164 }
165 
166 /**
167  * @brief enable TX dma request
168  *
169  * @param [in] ptr I2S base address
170  */
i2s_enable_tx_dma_request(I2S_Type * ptr)171 static inline void i2s_enable_tx_dma_request(I2S_Type *ptr)
172 {
173     ptr->CTRL |= I2S_CTRL_TX_DMA_EN_MASK;
174 }
175 
176 /**
177  * @brief disable TX dma request
178  *
179  * @param [in] ptr I2S base address
180  */
i2s_disable_tx_dma_request(I2S_Type * ptr)181 static inline void i2s_disable_tx_dma_request(I2S_Type *ptr)
182 {
183     ptr->CTRL &= ~I2S_CTRL_TX_DMA_EN_MASK;
184 }
185 
186 /**
187  * @brief enable RX dma request
188  *
189  * @param [in] ptr I2S base address
190  */
i2s_enable_rx_dma_request(I2S_Type * ptr)191 static inline void i2s_enable_rx_dma_request(I2S_Type *ptr)
192 {
193     ptr->CTRL |= I2S_CTRL_RX_DMA_EN_MASK;
194 }
195 
196 /**
197  * @brief disable RX dma request
198  *
199  * @param [in] ptr I2S base address
200  */
i2s_disable_rx_dma_request(I2S_Type * ptr)201 static inline void i2s_disable_rx_dma_request(I2S_Type *ptr)
202 {
203     ptr->CTRL &= ~I2S_CTRL_RX_DMA_EN_MASK;
204 }
205 
206 /**
207  * @brief enable IRQ
208  *
209  * @param [in] ptr I2S base address
210  * @param [in] mask irq bit mask
211  */
i2s_enable_irq(I2S_Type * ptr,uint32_t mask)212 static inline void i2s_enable_irq(I2S_Type *ptr, uint32_t mask)
213 {
214     ptr->CTRL |= mask;
215 }
216 
217 /**
218  * @brief disable IRQ
219  *
220  * @param [in] ptr I2S base address
221  * @param [in] mask irq bit mask
222  */
i2s_disable_irq(I2S_Type * ptr,uint32_t mask)223 static inline void i2s_disable_irq(I2S_Type *ptr, uint32_t mask)
224 {
225     ptr->CTRL &= ~mask;
226 }
227 
228 /**
229  * @brief I2S enable
230  *
231  * @note dropped API, please use i2s_start
232  *
233  * @param [in] ptr I2S base address
234  */
i2s_enable(I2S_Type * ptr)235 static inline void i2s_enable(I2S_Type *ptr)
236 {
237     ptr->CTRL |= I2S_CTRL_I2S_EN_MASK;
238 }
239 
240 /**
241  * @brief I2S disable
242  *
243  * @note dropped API, please use i2s_stop
244  *
245  * @param [in] ptr I2S base address
246  */
i2s_disable(I2S_Type * ptr)247 static inline void i2s_disable(I2S_Type *ptr)
248 {
249     ptr->CTRL &= ~I2S_CTRL_I2S_EN_MASK;
250 }
251 
252 /**
253  * @brief I2S start
254  *
255  * @param [in] ptr I2S base address
256  */
i2s_start(I2S_Type * ptr)257 static inline void i2s_start(I2S_Type *ptr)
258 {
259     ptr->CTRL |= I2S_CTRL_I2S_EN_MASK;
260 }
261 
262 /**
263  * @brief I2S stop
264  *
265  * @param [in] ptr I2S base address
266  */
i2s_stop(I2S_Type * ptr)267 static inline void i2s_stop(I2S_Type *ptr)
268 {
269     ptr->CTRL &= ~I2S_CTRL_I2S_EN_MASK;
270 }
271 
272 /**
273  * @brief I2S enable rx function
274  *
275  * @param [in] ptr I2S base address
276  * @param [in] rx_mask rx data line mask
277  */
i2s_enable_rx(I2S_Type * ptr,uint8_t rx_mask)278 static inline void i2s_enable_rx(I2S_Type *ptr, uint8_t rx_mask)
279 {
280     ptr->CTRL |= I2S_CTRL_RX_EN_SET(rx_mask);
281 }
282 
283 /**
284  * @brief I2S disable rx function
285  *
286  * @param [in] ptr I2S base address
287  * @param [in] rx_mask rx data line mask
288  */
i2s_disable_rx(I2S_Type * ptr,uint8_t rx_mask)289 static inline void i2s_disable_rx(I2S_Type *ptr, uint8_t rx_mask)
290 {
291     ptr->CTRL &= ~I2S_CTRL_RX_EN_SET(rx_mask);
292 }
293 
294 /**
295  * @brief I2S enable tx function
296  *
297  * @param [in] ptr I2S base address
298  * @param [in] tx_mask tx data line mask
299  */
i2s_enable_tx(I2S_Type * ptr,uint8_t tx_mask)300 static inline void i2s_enable_tx(I2S_Type *ptr, uint8_t tx_mask)
301 {
302     ptr->CTRL |= I2S_CTRL_TX_EN_SET(tx_mask);
303 }
304 
305 /**
306  * @brief I2S disbale tx function
307  *
308  * @param [in] ptr I2S base address
309  * @param [in] tx_mask tx data line mask
310  */
i2s_disable_tx(I2S_Type * ptr,uint8_t tx_mask)311 static inline void i2s_disable_tx(I2S_Type *ptr, uint8_t tx_mask)
312 {
313     ptr->CTRL &= ~I2S_CTRL_TX_EN_SET(tx_mask);
314 }
315 
316 /**
317  * @brief I2S reset clock generator
318  *
319  * @param [in] ptr I2S base address
320  */
i2s_reset_clock_gen(I2S_Type * ptr)321 static inline void i2s_reset_clock_gen(I2S_Type *ptr)
322 {
323     ptr->CTRL |= I2S_CTRL_SFTRST_CLKGEN_MASK;
324     ptr->CTRL &= ~I2S_CTRL_SFTRST_CLKGEN_MASK;
325 }
326 
327 /**
328  * @brief I2S reset tx function
329  *
330  * @note This API will disable I2S, reset tx function
331  * Please ensure that there is a valid BCLK when calling this function
332  *
333  * @param [in] ptr I2S base address
334  */
i2s_reset_tx(I2S_Type * ptr)335 static inline void i2s_reset_tx(I2S_Type *ptr)
336 {
337     /* disable I2S */
338     ptr->CTRL &= ~I2S_CTRL_I2S_EN_MASK;
339 
340     /* reset tx and clear fifo */
341     ptr->CTRL |= (I2S_CTRL_TXFIFOCLR_MASK | I2S_CTRL_SFTRST_TX_MASK);
342     ptr->CTRL &= ~(I2S_CTRL_TXFIFOCLR_MASK | I2S_CTRL_SFTRST_TX_MASK);
343 }
344 
345 /**
346  * @brief I2S reset rx function
347  *
348  * @note This API will disable I2S, reset rx function
349  * Please ensure that there is a valid BCLK when calling this function
350  *
351  * @param [in] ptr I2S base address
352  */
i2s_reset_rx(I2S_Type * ptr)353 static inline void i2s_reset_rx(I2S_Type *ptr)
354 {
355     /* disable I2S */
356     ptr->CTRL &= ~I2S_CTRL_I2S_EN_MASK;
357 
358     /* reset rx and clear fifo */
359     ptr->CTRL |= (I2S_CTRL_RXFIFOCLR_MASK | I2S_CTRL_SFTRST_RX_MASK);
360     ptr->CTRL &= ~(I2S_CTRL_RXFIFOCLR_MASK | I2S_CTRL_SFTRST_RX_MASK);
361 }
362 
363 /**
364  * @brief I2S reset tx and rx function
365  *
366  * @note This API will disable I2S, reset tx/rx function
367  * Please ensure that there is a valid BCLK when calling this function
368  *
369  * @param [in] ptr I2S base address
370  */
i2s_reset_tx_rx(I2S_Type * ptr)371 static inline void i2s_reset_tx_rx(I2S_Type *ptr)
372 {
373     /* disable I2S */
374     ptr->CTRL &= ~I2S_CTRL_I2S_EN_MASK;
375 
376     /* reset tx/rx and clear fifo */
377     ptr->CTRL |= (I2S_CTRL_TXFIFOCLR_MASK | I2S_CTRL_RXFIFOCLR_MASK | I2S_CTRL_SFTRST_TX_MASK | I2S_CTRL_SFTRST_RX_MASK);
378     ptr->CTRL &= ~(I2S_CTRL_TXFIFOCLR_MASK | I2S_CTRL_RXFIFOCLR_MASK | I2S_CTRL_SFTRST_TX_MASK | I2S_CTRL_SFTRST_RX_MASK);
379 }
380 
381 /**
382  * @brief I2S reset tx/rx and clock generator module
383  *
384  * @note This API will disable I2S, reset tx/rx and clock generator module
385  * This function uses an internal clock to generate BCLK, then do reset operation,
386  * and finally restores the previous clock settings
387  *
388  * @param [in] ptr I2S base address
389  */
390 void i2s_reset_all(I2S_Type *ptr);
391 
392 /**
393  * @brief I2S get tx fifo level
394  *
395  * @param [in] ptr I2S base address
396  *
397  * @retval I2S tx fifo level
398  */
i2s_get_tx_fifo_level(I2S_Type * ptr)399 static inline uint32_t i2s_get_tx_fifo_level(I2S_Type *ptr)
400 {
401     return ptr->TFIFO_FILLINGS;
402 }
403 
404 /**
405  * @brief I2S get data line tx fifo level
406  *
407  * @param [in] ptr I2S base address
408  * @param [in] line I2S data line
409  *
410  * @retval I2S data line tx fifo level
411  */
i2s_get_tx_line_fifo_level(I2S_Type * ptr,uint8_t line)412 static inline uint32_t i2s_get_tx_line_fifo_level(I2S_Type *ptr, uint8_t line)
413 {
414     return (i2s_get_tx_fifo_level(ptr) & (0xFF << (line << 3))) >> (line << 3);
415 }
416 
417 /**
418  * @brief I2S get rx fifo level
419  *
420  * @param [in] ptr I2S base address
421  *
422  * @retval I2S rx fifo level
423  */
i2s_get_rx_fifo_level(I2S_Type * ptr)424 static inline uint32_t i2s_get_rx_fifo_level(I2S_Type *ptr)
425 {
426     return ptr->RFIFO_FILLINGS;
427 }
428 
429 /**
430  * @brief I2S get data line rx fifo level
431  *
432  * @param [in] ptr I2S base address
433  * @param [in] line I2S data line
434  *
435  * @retval I2S data line rx fifo level
436  */
i2s_get_rx_line_fifo_level(I2S_Type * ptr,uint8_t line)437 static inline uint32_t i2s_get_rx_line_fifo_level(I2S_Type *ptr, uint8_t line)
438 {
439     return (i2s_get_rx_fifo_level(ptr) & (0xFF << (line << 3))) >> (line << 3);
440 }
441 
442 /**
443  * @brief Check I2S data line status
444  *
445  * @param[in] ptr I2S base address
446  * @param[in] line I2S data line
447  *
448  * @retval i2s_data_line_rx_fifo_avail data in rx fifo >= threshold
449  * @retval i2s_data_line_tx_fifo_avail data in tx fifo <= threshold
450  * @retval i2s_data_line_rx_fifo_overrun  rx fifo overrun occured
451  * @retval i2s_data_line_tx_fifo_underrun  tx fifo underrun occured
452  */
i2s_check_data_line_status(I2S_Type * ptr,uint8_t line)453 static inline uint32_t i2s_check_data_line_status(I2S_Type *ptr, uint8_t line)
454 {
455     volatile uint32_t reg_val = ptr->STA;
456     uint32_t bit_mask;
457     uint32_t stat = 0;
458 
459     bit_mask = 1 << (I2S_STA_RX_DA_SHIFT + line);
460     if ((bit_mask & reg_val) != 0) {
461         stat |= i2s_data_line_rx_fifo_avail;
462     }
463 
464     bit_mask = 1 << (I2S_STA_TX_DN_SHIFT + line);
465     if ((bit_mask & reg_val) != 0) {
466         stat |= i2s_data_line_tx_fifo_avail;
467     }
468 
469     bit_mask = 1 << (I2S_STA_RX_OV_SHIFT + line);
470     if ((bit_mask & reg_val) != 0) {
471         stat |= i2s_data_line_rx_fifo_overrun;
472         ptr->STA = bit_mask; /* clear flag: W1C*/
473     }
474 
475     bit_mask = 1 << (I2S_STA_TX_UD_SHIFT + line);
476     if ((bit_mask & reg_val) != 0) {
477         stat |= i2s_data_line_tx_fifo_underrun;
478         ptr->STA = bit_mask; /* clear flag: W1C*/
479     }
480 
481     return stat;
482 }
483 
484 /**
485  * @brief I2S get IRQ status
486  *
487  * @param [in] ptr I2S base address
488  *
489  * @retval I2S STA register value
490  */
i2s_get_irq_status(I2S_Type * ptr)491 static inline uint32_t i2s_get_irq_status(I2S_Type *ptr)
492 {
493     return ptr->STA;
494 }
495 
496 /**
497  * @brief I2S stop transfer
498  *
499  * @param [in] ptr I2S base address
500  */
i2s_stop_transfer(I2S_Type * ptr)501 static inline void i2s_stop_transfer(I2S_Type *ptr)
502 {
503     i2s_disable(ptr);
504 }
505 
506 /**
507  * @brief I2S config tx
508  *
509  * @note This API will disable I2S and configure parameters, could call i2s_enable() to enable I2S
510  *
511  * @param [in] ptr I2S base address
512  * @param [in] mclk_in_hz mclk frequency in Hz
513  * @param [in] config i2s_transfer_config_t
514  * @retval hpm_stat_t status_invalid_argument or status_success
515  */
516 hpm_stat_t i2s_config_tx(I2S_Type *ptr, uint32_t mclk_in_hz, i2s_transfer_config_t *config);
517 
518 /**
519  * @brief I2S config tx for slave
520  *
521  * @note This API will disable I2S and configure parameters, could call i2s_enable() to enable I2S
522  *
523  * @param [in] ptr I2S base address
524  * @param [in] config i2s_transfer_config_t
525  */
526 hpm_stat_t i2s_config_tx_slave(I2S_Type *ptr, i2s_transfer_config_t *config);
527 
528 /**
529  * @brief I2S config rx
530  *
531  * @note This API will disable I2S and configure parameters, could call i2s_enable() to enable I2S
532  *
533  * @param [in] ptr I2S base address
534  * @param [in] mclk_in_hz mclk frequency in Hz
535  * @param [in] config i2s_transfer_config_t
536  * @retval hpm_stat_t status_invalid_argument or status_success
537  */
538 hpm_stat_t i2s_config_rx(I2S_Type *ptr, uint32_t mclk_in_hz, i2s_transfer_config_t *config);
539 
540 /**
541  * @brief I2S config rx for slave
542  *
543  * @note This API will disable I2S and configure parameters, could call i2s_enable() to enable I2S
544  *
545  * @param [in] ptr I2S base address
546  * @param [in] config i2s_transfer_config_t
547  * @retval hpm_stat_t status_invalid_argument or status_success
548  */
549 hpm_stat_t i2s_config_rx_slave(I2S_Type *ptr, i2s_transfer_config_t *config);
550 
551 /**
552  * @brief I2S config transfer
553  *
554  * @note This API will disable I2S and configure parameters, could call i2s_enable() to enable I2S
555  *
556  * @param [in] ptr I2S base address
557  * @param [in] mclk_in_hz mclk frequency in Hz
558  * @param [in] config i2s_transfer_config_t
559  * @retval hpm_stat_t status_invalid_argument or status_success
560  */
561 hpm_stat_t i2s_config_transfer(I2S_Type *ptr, uint32_t mclk_in_hz, i2s_transfer_config_t *config);
562 
563 /**
564  * @brief I2S config transfer for slave
565  *
566  * @note This API will disable I2S and configure parameters, could call i2s_enable() to enable I2S
567  *
568  * @param [in] ptr I2S base address
569  * @param [in] config i2s_transfer_config_t
570  * @retval hpm_stat_t status_invalid_argument or status_success
571  */
572 hpm_stat_t i2s_config_transfer_slave(I2S_Type *ptr, i2s_transfer_config_t *config);
573 
574 /**
575  * @brief I2S send data
576  *
577  * @param [in] ptr I2S base address
578  * @param [in] tx_line_index data line
579  * @param [in] data data to be written
580  */
i2s_send_data(I2S_Type * ptr,uint8_t tx_line_index,uint32_t data)581 static inline void i2s_send_data(I2S_Type *ptr, uint8_t tx_line_index, uint32_t data)
582 {
583      ptr->TXD[tx_line_index] = data;
584 }
585 
586 /**
587  * @brief I2S receive data
588  *
589  * @param [in] ptr I2S base address
590  * @param [in] rx_line_index data line
591  * @param [out] data point to store data address
592  */
i2s_receive_data(I2S_Type * ptr,uint8_t rx_line_index,uint32_t * data)593 static inline void i2s_receive_data(I2S_Type *ptr, uint8_t rx_line_index, uint32_t *data)
594 {
595     *data = ptr->RXD[rx_line_index];
596 }
597 
598 /**
599  * @brief I2S send data in buff
600  *
601  * @param [in] ptr I2S base address
602  * @param [in] tx_line_index data line
603  * @param [in] samplebits audio data width
604  * @param [in] src source data buff
605  * @param [in] size data size
606  *
607  * @retval I2S sent data size in byte
608  */
609 uint32_t i2s_send_buff(I2S_Type *ptr, uint8_t tx_line_index, uint8_t samplebits, uint8_t *src, uint32_t size);
610 
611 /**
612  * @brief I2S receive data in buff
613  *
614  * @param [in] ptr I2S base address
615  * @param [in] rx_line_index data line
616  * @param [in] samplebits audio data width
617  * @param [out] dst target data buff
618  * @param [in] size data size
619  *
620  * @retval I2S sent data size in byte
621  */
622 uint32_t i2s_receive_buff(I2S_Type *ptr, uint8_t rx_line_index, uint8_t samplebits, uint8_t *dst, uint32_t size);
623 
624 /**
625  * @brief I2S get default config
626  *
627  * @param [in] ptr I2S base address
628  * @param [out] config i2s_config_t
629  */
630 void i2s_get_default_config(I2S_Type *ptr, i2s_config_t *config);
631 
632 /**
633  * @brief I2S initialization
634  *
635  * @param [in] ptr I2S base address
636  * @param [in] config i2s_config_t
637  */
638 void i2s_init(I2S_Type *ptr, i2s_config_t *config);
639 
640 /**
641  * @brief I2S get default transfer config for pdm
642  *
643  * @param [out] transfer i2s_transfer_config_t
644  */
645 void i2s_get_default_transfer_config_for_pdm(i2s_transfer_config_t *transfer);
646 
647 /**
648  * @brief I2S get default transfer config for dao
649  *
650  * @param [out] transfer i2s_transfer_config_t
651  */
652 void i2s_get_default_transfer_config_for_dao(i2s_transfer_config_t *transfer);
653 
654 /**
655  * @brief I2S get default transfer config
656  *
657  * @param [out] transfer i2s_transfer_config_t
658  */
659 void i2s_get_default_transfer_config(i2s_transfer_config_t *transfer);
660 
661 /**
662  * @brief I2S fill dummy data into TX fifo
663  *
664  * @note workaround: fill dummy data into TX fifo to avoid TX underflow during tx start
665  *
666  * @param [in] ptr I2S base address
667  * @param [in] data_line data line
668  * @param [in] data_count dummy data count, This value should be the same as the number of audio channels
669  *
670  * @retval status_success if no error occurred
671  */
672 hpm_stat_t i2s_fill_tx_dummy_data(I2S_Type *ptr, uint8_t data_line, uint8_t data_count);
673 
674 /**
675  * @}
676  */
677 
678 #ifdef __cplusplus
679 }
680 #endif
681 
682 #endif /* HPM_I2S_DRV_H */
683