Lines Matching +full:rx +full:- +full:extra +full:- +full:mode

4  * SPDX-License-Identifier: Apache-2.0
13 * - TX and RX path share a common bit clock divider and as a result they cannot
14 * be configured independently. If RX and TX path are set to different bit
17 * - DMA is used in simple single block transfer mode and as such is not able
19 * linked list mode should be used.
99 struct stream rx; member
122 if (rb->tail == rb->head) { in queue_get()
125 return -ENOMEM; in queue_get()
128 *mem_block = rb->buf[rb->tail].mem_block; in queue_get()
129 *size = rb->buf[rb->tail].size; in queue_get()
130 MODULO_INC(rb->tail, rb->len); in queue_get()
147 head_next = rb->head; in queue_put()
148 MODULO_INC(head_next, rb->len); in queue_put()
150 if (head_next == rb->tail) { in queue_put()
153 return -ENOMEM; in queue_put()
156 rb->buf[rb->head].mem_block = mem_block; in queue_put()
157 rb->buf[rb->head].size = size; in queue_put()
158 rb->head = head_next; in queue_put()
192 cfg->head_block = &blk_cfg; in start_dma()
209 const struct i2s_sam_dev_cfg *const dev_cfg = dev->config; in dma_rx_callback()
210 struct i2s_sam_dev_data *const dev_data = dev->data; in dma_rx_callback()
211 Ssc *const ssc = dev_cfg->regs; in dma_rx_callback()
212 struct stream *stream = &dev_data->rx; in dma_rx_callback()
216 __ASSERT_NO_MSG(stream->mem_block != NULL); in dma_rx_callback()
219 if (stream->state == I2S_STATE_ERROR) { in dma_rx_callback()
224 ret = queue_put(&stream->mem_block_queue, stream->mem_block, in dma_rx_callback()
225 stream->cfg.block_size); in dma_rx_callback()
227 stream->state = I2S_STATE_ERROR; in dma_rx_callback()
230 stream->mem_block = NULL; in dma_rx_callback()
231 k_sem_give(&stream->sem); in dma_rx_callback()
234 if (stream->state == I2S_STATE_STOPPING) { in dma_rx_callback()
235 stream->state = I2S_STATE_READY; in dma_rx_callback()
240 ret = k_mem_slab_alloc(stream->cfg.mem_slab, &stream->mem_block, in dma_rx_callback()
243 stream->state = I2S_STATE_ERROR; in dma_rx_callback()
248 DCACHE_INVALIDATE(stream->mem_block, stream->cfg.block_size); in dma_rx_callback()
250 ret = reload_dma(dev_cfg->dev_dma, stream->dma_channel, in dma_rx_callback()
251 (void *)&(ssc->SSC_RHR), stream->mem_block, in dma_rx_callback()
252 stream->cfg.block_size); in dma_rx_callback()
254 LOG_DBG("Failed to reload RX DMA transfer: %d", ret); in dma_rx_callback()
261 rx_stream_disable(stream, ssc, dev_cfg->dev_dma); in dma_rx_callback()
269 const struct i2s_sam_dev_cfg *const dev_cfg = dev->config; in dma_tx_callback()
270 struct i2s_sam_dev_data *const dev_data = dev->data; in dma_tx_callback()
271 Ssc *const ssc = dev_cfg->regs; in dma_tx_callback()
272 struct stream *stream = &dev_data->tx; in dma_tx_callback()
277 __ASSERT_NO_MSG(stream->mem_block != NULL); in dma_tx_callback()
280 k_mem_slab_free(stream->cfg.mem_slab, stream->mem_block); in dma_tx_callback()
281 stream->mem_block = NULL; in dma_tx_callback()
284 if (stream->state == I2S_STATE_ERROR) { in dma_tx_callback()
290 if (stream->last_block) { in dma_tx_callback()
291 stream->state = I2S_STATE_READY; in dma_tx_callback()
296 ret = queue_get(&stream->mem_block_queue, &stream->mem_block, in dma_tx_callback()
299 if (stream->state == I2S_STATE_STOPPING) { in dma_tx_callback()
300 stream->state = I2S_STATE_READY; in dma_tx_callback()
302 stream->state = I2S_STATE_ERROR; in dma_tx_callback()
306 k_sem_give(&stream->sem); in dma_tx_callback()
309 DCACHE_CLEAN(stream->mem_block, mem_block_size); in dma_tx_callback()
311 ret = reload_dma(dev_cfg->dev_dma, stream->dma_channel, in dma_tx_callback()
312 stream->mem_block, (void *)&(ssc->SSC_THR), in dma_tx_callback()
322 tx_stream_disable(stream, ssc, dev_cfg->dev_dma); in dma_tx_callback()
328 Ssc *const ssc = dev_cfg->regs; in set_rx_data_format()
331 uint8_t word_size_bits = i2s_cfg->word_size; in set_rx_data_format()
332 uint8_t num_words = i2s_cfg->channels; in set_rx_data_format()
336 bool frame_clk_master = !(i2s_cfg->options & I2S_OPT_FRAME_CLK_SLAVE); in set_rx_data_format()
338 switch (i2s_cfg->format & I2S_FMT_DATA_FORMAT_MASK) { in set_rx_data_format()
342 fslen = word_size_bits - 1; in set_rx_data_format()
361 fslen = num_words * word_size_bits / 2U - 1; in set_rx_data_format()
371 fslen = num_words * word_size_bits / 2U - 1; in set_rx_data_format()
383 return -EINVAL; in set_rx_data_format()
387 ssc_rcmr |= ((i2s_cfg->options & I2S_OPT_BIT_CLK_SLAVE) in set_rx_data_format()
389 | ((i2s_cfg->options & I2S_OPT_BIT_CLK_GATED) in set_rx_data_format()
400 | SSC_RCMR_PERIOD((num_words * word_size_bits + 1) / 2U - 1); in set_rx_data_format()
402 /* Receive Clock Mode Register */ in set_rx_data_format()
403 ssc->SSC_RCMR = ssc_rcmr; in set_rx_data_format()
405 ssc_rfmr |= SSC_RFMR_DATLEN(word_size_bits - 1) in set_rx_data_format()
406 | ((i2s_cfg->format & I2S_FMT_DATA_ORDER_LSB) in set_rx_data_format()
408 | SSC_RFMR_DATNB(num_words - 1) in set_rx_data_format()
412 /* Receive Frame Mode Register */ in set_rx_data_format()
413 ssc->SSC_RFMR = ssc_rfmr; in set_rx_data_format()
421 Ssc *const ssc = dev_cfg->regs; in set_tx_data_format()
422 uint8_t word_size_bits = i2s_cfg->word_size; in set_tx_data_format()
423 uint8_t num_words = i2s_cfg->channels; in set_tx_data_format()
428 switch (i2s_cfg->format & I2S_FMT_DATA_FORMAT_MASK) { in set_tx_data_format()
432 fslen = word_size_bits - 1; in set_tx_data_format()
449 fslen = num_words * word_size_bits / 2U - 1; in set_tx_data_format()
459 fslen = num_words * word_size_bits / 2U - 1; in set_tx_data_format()
469 return -EINVAL; in set_tx_data_format()
476 ssc_tcmr |= ((i2s_cfg->options & I2S_OPT_BIT_CLK_SLAVE) in set_tx_data_format()
478 | ((i2s_cfg->options & I2S_OPT_BIT_CLK_GATED) in set_tx_data_format()
480 | SSC_TCMR_PERIOD((num_words * word_size_bits + 1) / 2U - 1); in set_tx_data_format()
482 /* Transmit Clock Mode Register */ in set_tx_data_format()
483 ssc->SSC_TCMR = ssc_tcmr; in set_tx_data_format()
485 if (i2s_cfg->options & I2S_OPT_FRAME_CLK_SLAVE) { in set_tx_data_format()
490 ssc_tfmr |= SSC_TFMR_DATLEN(word_size_bits - 1) in set_tx_data_format()
491 | ((i2s_cfg->format & I2S_FMT_DATA_ORDER_LSB) in set_tx_data_format()
493 | SSC_TFMR_DATNB(num_words - 1) in set_tx_data_format()
497 /* Transmit Frame Mode Register */ in set_tx_data_format()
498 ssc->SSC_TFMR = ssc_tfmr; in set_tx_data_format()
520 return -EINVAL; in bit_clock_set()
523 ssc->SSC_CMR = clk_div; in bit_clock_set()
533 struct i2s_sam_dev_data *const dev_data = dev->data; in i2s_sam_config_get()
537 stream = &dev_data->rx; in i2s_sam_config_get()
539 stream = &dev_data->tx; in i2s_sam_config_get()
542 if (stream->state == I2S_STATE_NOT_READY) { in i2s_sam_config_get()
546 return &stream->cfg; in i2s_sam_config_get()
552 const struct i2s_sam_dev_cfg *const dev_cfg = dev->config; in i2s_sam_configure()
553 struct i2s_sam_dev_data *const dev_data = dev->data; in i2s_sam_configure()
554 Ssc *const ssc = dev_cfg->regs; in i2s_sam_configure()
555 uint8_t num_words = i2s_cfg->channels; in i2s_sam_configure()
556 uint8_t word_size_bits = i2s_cfg->word_size; in i2s_sam_configure()
562 stream = &dev_data->rx; in i2s_sam_configure()
564 stream = &dev_data->tx; in i2s_sam_configure()
566 return -ENOSYS; in i2s_sam_configure()
568 LOG_ERR("Either RX or TX direction must be selected"); in i2s_sam_configure()
569 return -EINVAL; in i2s_sam_configure()
572 if (stream->state != I2S_STATE_NOT_READY && in i2s_sam_configure()
573 stream->state != I2S_STATE_READY) { in i2s_sam_configure()
575 return -EINVAL; in i2s_sam_configure()
578 if (i2s_cfg->frame_clk_freq == 0U) { in i2s_sam_configure()
579 stream->queue_drop(stream); in i2s_sam_configure()
580 (void)memset(&stream->cfg, 0, sizeof(struct i2s_config)); in i2s_sam_configure()
581 stream->state = I2S_STATE_NOT_READY; in i2s_sam_configure()
585 if (i2s_cfg->format & I2S_FMT_FRAME_CLK_INV) { in i2s_sam_configure()
588 return -EINVAL; in i2s_sam_configure()
591 if (i2s_cfg->format & I2S_FMT_BIT_CLK_INV) { in i2s_sam_configure()
594 return -EINVAL; in i2s_sam_configure()
600 return -EINVAL; in i2s_sam_configure()
606 return -EINVAL; in i2s_sam_configure()
609 memcpy(&stream->cfg, i2s_cfg, sizeof(struct i2s_config)); in i2s_sam_configure()
611 bit_clk_freq = i2s_cfg->frame_clk_freq * word_size_bits * num_words; in i2s_sam_configure()
617 ret = stream->set_data_format(dev_cfg, i2s_cfg); in i2s_sam_configure()
623 stream->word_size_bytes = get_word_size_bytes(word_size_bits); in i2s_sam_configure()
625 if (i2s_cfg->options & I2S_OPT_LOOPBACK) { in i2s_sam_configure()
626 ssc->SSC_RFMR |= SSC_RFMR_LOOP; in i2s_sam_configure()
629 stream->state = I2S_STATE_READY; in i2s_sam_configure()
639 ret = k_mem_slab_alloc(stream->cfg.mem_slab, &stream->mem_block, in rx_stream_start()
646 * item even if SSC_SR.RXEN (Receive Enable) is not set. An extra read in rx_stream_start()
649 (void)ssc->SSC_RHR; in rx_stream_start()
652 .source_data_size = stream->word_size_bytes, in rx_stream_start()
653 .dest_data_size = stream->word_size_bytes, in rx_stream_start()
655 .dma_slot = stream->dma_perid, in rx_stream_start()
662 ret = start_dma(dev_dma, stream->dma_channel, &dma_cfg, in rx_stream_start()
663 (void *)&(ssc->SSC_RHR), stream->mem_block, in rx_stream_start()
664 stream->cfg.block_size); in rx_stream_start()
666 LOG_ERR("Failed to start RX DMA transfer: %d", ret); in rx_stream_start()
671 (void)ssc->SSC_SR; in rx_stream_start()
673 ssc->SSC_IER = SSC_IER_OVRUN; in rx_stream_start()
675 ssc->SSC_CR = SSC_CR_RXEN; in rx_stream_start()
686 ret = queue_get(&stream->mem_block_queue, &stream->mem_block, in tx_stream_start()
691 k_sem_give(&stream->sem); in tx_stream_start()
694 * item even if SSC_SR.TXEN (Transmit Enable) is not set. An extra write in tx_stream_start()
698 ssc->SSC_THR = 0; in tx_stream_start()
701 .source_data_size = stream->word_size_bytes, in tx_stream_start()
702 .dest_data_size = stream->word_size_bytes, in tx_stream_start()
704 .dma_slot = stream->dma_perid, in tx_stream_start()
712 DCACHE_CLEAN(stream->mem_block, mem_block_size); in tx_stream_start()
714 ret = start_dma(dev_dma, stream->dma_channel, &dma_cfg, in tx_stream_start()
715 stream->mem_block, (void *)&(ssc->SSC_THR), in tx_stream_start()
723 (void)ssc->SSC_SR; in tx_stream_start()
725 ssc->SSC_IER = SSC_IER_TXEMPTY; in tx_stream_start()
727 ssc->SSC_CR = SSC_CR_TXEN; in tx_stream_start()
735 ssc->SSC_CR = SSC_CR_RXDIS; in rx_stream_disable()
736 ssc->SSC_IDR = SSC_IDR_OVRUN; in rx_stream_disable()
737 dma_stop(dev_dma, stream->dma_channel); in rx_stream_disable()
738 if (stream->mem_block != NULL) { in rx_stream_disable()
739 k_mem_slab_free(stream->cfg.mem_slab, stream->mem_block); in rx_stream_disable()
740 stream->mem_block = NULL; in rx_stream_disable()
747 ssc->SSC_CR = SSC_CR_TXDIS; in tx_stream_disable()
748 ssc->SSC_IDR = SSC_IDR_TXEMPTY; in tx_stream_disable()
749 dma_stop(dev_dma, stream->dma_channel); in tx_stream_disable()
750 if (stream->mem_block != NULL) { in tx_stream_disable()
751 k_mem_slab_free(stream->cfg.mem_slab, stream->mem_block); in tx_stream_disable()
752 stream->mem_block = NULL; in tx_stream_disable()
761 while (queue_get(&stream->mem_block_queue, &mem_block, &size) == 0) { in rx_queue_drop()
762 k_mem_slab_free(stream->cfg.mem_slab, mem_block); in rx_queue_drop()
765 k_sem_reset(&stream->sem); in rx_queue_drop()
774 while (queue_get(&stream->mem_block_queue, &mem_block, &size) == 0) { in tx_queue_drop()
775 k_mem_slab_free(stream->cfg.mem_slab, mem_block); in tx_queue_drop()
779 for (; n > 0; n--) { in tx_queue_drop()
780 k_sem_give(&stream->sem); in tx_queue_drop()
787 const struct i2s_sam_dev_cfg *const dev_cfg = dev->config; in i2s_sam_trigger()
788 struct i2s_sam_dev_data *const dev_data = dev->data; in i2s_sam_trigger()
789 Ssc *const ssc = dev_cfg->regs; in i2s_sam_trigger()
795 stream = &dev_data->rx; in i2s_sam_trigger()
797 stream = &dev_data->tx; in i2s_sam_trigger()
799 return -ENOSYS; in i2s_sam_trigger()
801 LOG_ERR("Either RX or TX direction must be selected"); in i2s_sam_trigger()
802 return -EINVAL; in i2s_sam_trigger()
807 if (stream->state != I2S_STATE_READY) { in i2s_sam_trigger()
809 return -EIO; in i2s_sam_trigger()
812 __ASSERT_NO_MSG(stream->mem_block == NULL); in i2s_sam_trigger()
814 ret = stream->stream_start(stream, ssc, dev_cfg->dev_dma); in i2s_sam_trigger()
820 stream->state = I2S_STATE_RUNNING; in i2s_sam_trigger()
821 stream->last_block = false; in i2s_sam_trigger()
826 if (stream->state != I2S_STATE_RUNNING) { in i2s_sam_trigger()
829 return -EIO; in i2s_sam_trigger()
831 stream->state = I2S_STATE_STOPPING; in i2s_sam_trigger()
833 stream->last_block = true; in i2s_sam_trigger()
838 if (stream->state != I2S_STATE_RUNNING) { in i2s_sam_trigger()
841 return -EIO; in i2s_sam_trigger()
843 stream->state = I2S_STATE_STOPPING; in i2s_sam_trigger()
848 if (stream->state == I2S_STATE_NOT_READY) { in i2s_sam_trigger()
850 return -EIO; in i2s_sam_trigger()
852 stream->stream_disable(stream, ssc, dev_cfg->dev_dma); in i2s_sam_trigger()
853 stream->queue_drop(stream); in i2s_sam_trigger()
854 stream->state = I2S_STATE_READY; in i2s_sam_trigger()
858 if (stream->state != I2S_STATE_ERROR) { in i2s_sam_trigger()
860 return -EIO; in i2s_sam_trigger()
862 stream->state = I2S_STATE_READY; in i2s_sam_trigger()
863 stream->queue_drop(stream); in i2s_sam_trigger()
868 return -EINVAL; in i2s_sam_trigger()
877 struct i2s_sam_dev_data *const dev_data = dev->data; in i2s_sam_read()
880 if (dev_data->rx.state == I2S_STATE_NOT_READY) { in i2s_sam_read()
882 return -EIO; in i2s_sam_read()
885 if (dev_data->rx.state != I2S_STATE_ERROR) { in i2s_sam_read()
886 ret = k_sem_take(&dev_data->rx.sem, in i2s_sam_read()
887 SYS_TIMEOUT_MS(dev_data->rx.cfg.timeout)); in i2s_sam_read()
893 /* Get data from the beginning of RX queue */ in i2s_sam_read()
894 ret = queue_get(&dev_data->rx.mem_block_queue, mem_block, size); in i2s_sam_read()
896 return -EIO; in i2s_sam_read()
905 struct i2s_sam_dev_data *const dev_data = dev->data; in i2s_sam_write()
908 if (dev_data->tx.state != I2S_STATE_RUNNING && in i2s_sam_write()
909 dev_data->tx.state != I2S_STATE_READY) { in i2s_sam_write()
911 return -EIO; in i2s_sam_write()
914 ret = k_sem_take(&dev_data->tx.sem, in i2s_sam_write()
915 SYS_TIMEOUT_MS(dev_data->tx.cfg.timeout)); in i2s_sam_write()
921 queue_put(&dev_data->tx.mem_block_queue, mem_block, size); in i2s_sam_write()
928 const struct i2s_sam_dev_cfg *const dev_cfg = dev->config; in i2s_sam_isr()
929 struct i2s_sam_dev_data *const dev_data = dev->data; in i2s_sam_isr()
930 Ssc *const ssc = dev_cfg->regs; in i2s_sam_isr()
934 isr_status = ssc->SSC_SR & ssc->SSC_IMR; in i2s_sam_isr()
936 /* Check for RX buffer overrun */ in i2s_sam_isr()
938 dev_data->rx.state = I2S_STATE_ERROR; in i2s_sam_isr()
940 ssc->SSC_IDR = SSC_IDR_OVRUN; in i2s_sam_isr()
941 LOG_DBG("RX buffer overrun error"); in i2s_sam_isr()
945 dev_data->tx.state = I2S_STATE_ERROR; in i2s_sam_isr()
947 ssc->SSC_IDR = SSC_IDR_TXEMPTY; in i2s_sam_isr()
954 const struct i2s_sam_dev_cfg *const dev_cfg = dev->config; in i2s_sam_initialize()
955 struct i2s_sam_dev_data *const dev_data = dev->data; in i2s_sam_initialize()
956 Ssc *const ssc = dev_cfg->regs; in i2s_sam_initialize()
960 dev_cfg->irq_config(); in i2s_sam_initialize()
963 k_sem_init(&dev_data->rx.sem, 0, CONFIG_I2S_SAM_SSC_RX_BLOCK_COUNT); in i2s_sam_initialize()
964 k_sem_init(&dev_data->tx.sem, CONFIG_I2S_SAM_SSC_TX_BLOCK_COUNT, in i2s_sam_initialize()
967 if (!device_is_ready(dev_cfg->dev_dma)) { in i2s_sam_initialize()
968 LOG_ERR("%s device not ready", dev_cfg->dev_dma->name); in i2s_sam_initialize()
969 return -ENODEV; in i2s_sam_initialize()
973 ret = pinctrl_apply_state(dev_cfg->pcfg, PINCTRL_STATE_DEFAULT); in i2s_sam_initialize()
980 (clock_control_subsys_t)&dev_cfg->clock_cfg); in i2s_sam_initialize()
983 ssc->SSC_CR = SSC_CR_RXDIS | SSC_CR_TXDIS | SSC_CR_SWRST; in i2s_sam_initialize()
986 irq_enable(dev_cfg->irq_id); in i2s_sam_initialize()
988 LOG_INF("Device %s initialized", dev->name); in i2s_sam_initialize()
1029 .rx = {
1030 .dma_channel = DT_INST_DMAS_CELL_BY_NAME(0, rx, channel),
1031 .dma_perid = DT_INST_DMAS_CELL_BY_NAME(0, rx, perid),