Lines Matching +full:de +full:- +full:assert +full:- +full:time
6 * SPDX-License-Identifier: Apache-2.0
50 /* Device run time data */
66 struct spi_sam_data *data = dev->data; in spi_spin_lock()
68 return k_spin_lock(&data->lock); in spi_spin_lock()
73 struct spi_sam_data *data = dev->data; in spi_spin_unlock()
75 k_spin_unlock(&data->lock, key); in spi_spin_unlock()
83 * select decode(SPI_MR.PCSDEC = 0), based on Atmel | SMART ARM-based in spi_slave_to_mr_pcs()
97 const struct spi_sam_config *cfg = dev->config; in spi_sam_configure()
98 struct spi_sam_data *data = dev->data; in spi_sam_configure()
99 Spi *regs = cfg->regs; in spi_sam_configure()
101 uint16_t spi_csr_idx = spi_cs_is_gpio(config) ? 0 : config->slave; in spi_sam_configure()
104 if (spi_context_configured(&data->ctx, config)) { in spi_sam_configure()
108 if (config->operation & SPI_HALF_DUPLEX) { in spi_sam_configure()
109 LOG_ERR("Half-duplex not supported"); in spi_sam_configure()
110 return -ENOTSUP; in spi_sam_configure()
113 if (SPI_OP_MODE_GET(config->operation) != SPI_OP_MODE_MASTER) { in spi_sam_configure()
115 return -ENOTSUP; in spi_sam_configure()
118 if (config->slave > (SAM_SPI_CHIP_SELECT_COUNT - 1)) { in spi_sam_configure()
120 config->slave, SAM_SPI_CHIP_SELECT_COUNT - 1); in spi_sam_configure()
121 return -EINVAL; in spi_sam_configure()
130 if (cfg->loopback) { in spi_sam_configure()
134 if ((config->operation & SPI_MODE_CPOL) != 0U) { in spi_sam_configure()
138 if ((config->operation & SPI_MODE_CPHA) == 0U) { in spi_sam_configure()
142 if (SPI_WORD_SIZE_GET(config->operation) != 8) { in spi_sam_configure()
143 return -ENOTSUP; in spi_sam_configure()
149 div = SOC_ATMEL_SAM_MCK_FREQ_HZ / config->frequency; in spi_sam_configure()
153 regs->SPI_CR = SPI_CR_SPIDIS; /* Disable SPI */ in spi_sam_configure()
154 regs->SPI_MR = spi_mr; in spi_sam_configure()
155 regs->SPI_CSR[spi_csr_idx] = spi_csr; in spi_sam_configure()
156 regs->SPI_CR = SPI_CR_SPIEN; /* Enable SPI */ in spi_sam_configure()
158 data->ctx.config = config; in spi_sam_configure()
166 while ((regs->SPI_SR & SPI_SR_TXEMPTY) == 0) { in spi_sam_finish()
169 while (regs->SPI_SR & SPI_SR_RDRF) { in spi_sam_finish()
170 (void)regs->SPI_RDR; in spi_sam_finish()
184 while ((regs->SPI_SR & SPI_SR_TDRE) == 0) { in spi_sam_fast_tx()
187 regs->SPI_TDR = SPI_TDR_TD(ch); in spi_sam_fast_tx()
202 regs->SPI_TDR = SPI_TDR_TD(0); in spi_sam_fast_rx()
203 len--; in spi_sam_fast_rx()
206 while ((regs->SPI_SR & SPI_SR_TDRE) == 0) { in spi_sam_fast_rx()
210 while ((regs->SPI_SR & SPI_SR_RDRF) == 0) { in spi_sam_fast_rx()
213 *rx = (uint8_t)regs->SPI_RDR; in spi_sam_fast_rx()
217 regs->SPI_TDR = SPI_TDR_TD(0); in spi_sam_fast_rx()
218 len--; in spi_sam_fast_rx()
222 while ((regs->SPI_SR & SPI_SR_RDRF) == 0) { in spi_sam_fast_rx()
225 *rx = (uint8_t)regs->SPI_RDR; in spi_sam_fast_rx()
249 * - Transmit byte n+1 in spi_sam_fast_txrx()
250 * - Receive byte n in spi_sam_fast_txrx()
255 regs->SPI_TDR = SPI_TDR_TD(*tx++); in spi_sam_fast_txrx()
258 while ((regs->SPI_SR & SPI_SR_TDRE) == 0) { in spi_sam_fast_txrx()
265 regs->SPI_TDR = SPI_TDR_TD(*tx++); in spi_sam_fast_txrx()
268 while ((regs->SPI_SR & SPI_SR_RDRF) == 0) { in spi_sam_fast_txrx()
271 *rx++ = (uint8_t)regs->SPI_RDR; in spi_sam_fast_txrx()
275 while ((regs->SPI_SR & SPI_SR_RDRF) == 0) { in spi_sam_fast_txrx()
278 *rx = (uint8_t)regs->SPI_RDR; in spi_sam_fast_txrx()
300 struct spi_sam_data *drv_data = dev->data; in dma_callback()
303 struct spi_rtio *rtio_ctx = drv_data->rtio_ctx; in dma_callback()
305 if (rtio_ctx->txn_head != NULL) { in dma_callback()
310 k_sem_give(&drv_data->dma_sem); in dma_callback()
321 const struct spi_sam_config *drv_cfg = dev->config; in spi_sam_dma_txrx()
322 struct spi_sam_data *drv_data = dev->data; in spi_sam_dma_txrx()
324 struct spi_rtio *rtio_ctx = drv_data->rtio_ctx; in spi_sam_dma_txrx()
325 bool blocking = rtio_ctx->txn_head == NULL; in spi_sam_dma_txrx()
338 .dma_slot = drv_cfg->dma_rx_perid, in spi_sam_dma_txrx()
360 .source_address = (uint32_t)®s->SPI_RDR, in spi_sam_dma_txrx()
370 .dma_slot = drv_cfg->dma_tx_perid, in spi_sam_dma_txrx()
393 .dest_address = (uint32_t)®s->SPI_TDR in spi_sam_dma_txrx()
398 res = dma_config(drv_cfg->dma_dev, drv_cfg->dma_rx_channel, &rx_dma_cfg); in spi_sam_dma_txrx()
404 res = dma_config(drv_cfg->dma_dev, drv_cfg->dma_tx_channel, &tx_dma_cfg); in spi_sam_dma_txrx()
411 res = dma_start(drv_cfg->dma_dev, drv_cfg->dma_rx_channel); in spi_sam_dma_txrx()
417 res = dma_start(drv_cfg->dma_dev, drv_cfg->dma_tx_channel); in spi_sam_dma_txrx()
420 dma_stop(drv_cfg->dma_dev, drv_cfg->dma_rx_channel); in spi_sam_dma_txrx()
425 k_sem_take(&drv_data->dma_sem, K_FOREVER); in spi_sam_dma_txrx()
428 res = -EWOULDBLOCK; in spi_sam_dma_txrx()
446 const struct spi_sam_config *cfg = dev->config; in spi_sam_rx()
448 if ((rx_buf_len < SAM_SPI_DMA_THRESHOLD || cfg->dma_dev == NULL) && in spi_sam_rx()
474 const struct spi_sam_config *cfg = dev->config; in spi_sam_tx()
476 if ((tx_buf_len < SAM_SPI_DMA_THRESHOLD || cfg->dma_dev == NULL) && in spi_sam_tx()
503 const struct spi_sam_config *cfg = dev->config; in spi_sam_txrx()
505 if ((buf_len < SAM_SPI_DMA_THRESHOLD || cfg->dma_dev == NULL) && in spi_sam_txrx()
530 const struct spi_sam_config *cfg = dev->config; in spi_sam_fast_transceive()
533 Spi *regs = cfg->regs; in spi_sam_fast_transceive()
538 tx = tx_bufs->buffers; in spi_sam_fast_transceive()
539 tx_count = tx_bufs->count; in spi_sam_fast_transceive()
543 rx = rx_bufs->buffers; in spi_sam_fast_transceive()
544 rx_count = rx_bufs->count; in spi_sam_fast_transceive()
548 if (tx->buf == NULL) { in spi_sam_fast_transceive()
549 spi_sam_rx(dev, regs, rx->buf, rx->len); in spi_sam_fast_transceive()
550 } else if (rx->buf == NULL) { in spi_sam_fast_transceive()
551 spi_sam_tx(dev, regs, tx->buf, tx->len); in spi_sam_fast_transceive()
552 } else if (rx->len == tx->len) { in spi_sam_fast_transceive()
553 spi_sam_txrx(dev, regs, tx->buf, rx->buf, rx->len); in spi_sam_fast_transceive()
559 tx_count--; in spi_sam_fast_transceive()
561 rx_count--; in spi_sam_fast_transceive()
564 for (; tx_count != 0; tx_count--) { in spi_sam_fast_transceive()
565 spi_sam_tx(dev, regs, tx->buf, tx->len); in spi_sam_fast_transceive()
569 for (; rx_count != 0; rx_count--) { in spi_sam_fast_transceive()
570 spi_sam_rx(dev, regs, rx->buf, rx->len); in spi_sam_fast_transceive()
577 return spi_context_tx_on(&data->ctx) || spi_context_rx_on(&data->ctx); in spi_sam_transfer_ongoing()
585 if (spi_context_tx_buf_on(&data->ctx)) { in spi_sam_shift_master()
586 tx = *(uint8_t *)(data->ctx.tx_buf); in spi_sam_shift_master()
591 while ((regs->SPI_SR & SPI_SR_TDRE) == 0) { in spi_sam_shift_master()
594 regs->SPI_TDR = SPI_TDR_TD(tx); in spi_sam_shift_master()
595 spi_context_update_tx(&data->ctx, 1, 1); in spi_sam_shift_master()
597 while ((regs->SPI_SR & SPI_SR_RDRF) == 0) { in spi_sam_shift_master()
600 rx = (uint8_t)regs->SPI_RDR; in spi_sam_shift_master()
602 if (spi_context_rx_buf_on(&data->ctx)) { in spi_sam_shift_master()
603 *data->ctx.rx_buf = rx; in spi_sam_shift_master()
605 spi_context_update_rx(&data->ctx, 1, 1); in spi_sam_shift_master()
611 * - Zero or more RX and TX buf pairs where each is the same length.
612 * - Zero or more trailing RX only bufs
613 * - Zero or more trailing TX only bufs
624 tx = tx_bufs->buffers; in spi_sam_is_regular()
625 tx_count = tx_bufs->count; in spi_sam_is_regular()
629 rx = rx_bufs->buffers; in spi_sam_is_regular()
630 rx_count = rx_bufs->count; in spi_sam_is_regular()
638 if (tx->len != rx->len) { in spi_sam_is_regular()
643 tx_count--; in spi_sam_is_regular()
645 rx_count--; in spi_sam_is_regular()
657 const struct spi_sam_config *cfg = dev->config; in spi_sam_iodev_start()
658 struct spi_sam_data *data = dev->data; in spi_sam_iodev_start()
659 struct spi_rtio *rtio_ctx = data->rtio_ctx; in spi_sam_iodev_start()
660 struct rtio_sqe *sqe = &rtio_ctx->txn_curr->sqe; in spi_sam_iodev_start()
663 switch (sqe->op) { in spi_sam_iodev_start()
665 ret = spi_sam_rx(dev, cfg->regs, sqe->rx.buf, sqe->rx.buf_len); in spi_sam_iodev_start()
668 ret = spi_sam_tx(dev, cfg->regs, sqe->tx.buf, sqe->tx.buf_len); in spi_sam_iodev_start()
671 ret = spi_sam_tx(dev, cfg->regs, sqe->tiny_tx.buf, sqe->tiny_tx.buf_len); in spi_sam_iodev_start()
674 ret = spi_sam_txrx(dev, cfg->regs, sqe->txrx.tx_buf, sqe->txrx.rx_buf, in spi_sam_iodev_start()
675 sqe->txrx.buf_len); in spi_sam_iodev_start()
678 LOG_ERR("Invalid op code %d for submission %p\n", sqe->op, (void *)sqe); in spi_sam_iodev_start()
679 spi_sam_iodev_complete(dev, -EINVAL); in spi_sam_iodev_start()
686 if (ret != 0 && ret != -EWOULDBLOCK) { in spi_sam_iodev_start()
693 struct spi_sam_data *data = dev->data; in spi_sam_iodev_prepare_start()
694 struct spi_rtio *rtio_ctx = data->rtio_ctx; in spi_sam_iodev_prepare_start()
695 struct spi_dt_spec *spi_dt_spec = rtio_ctx->txn_curr->sqe.iodev->data; in spi_sam_iodev_prepare_start()
696 struct spi_config *spi_config = &spi_dt_spec->config; in spi_sam_iodev_prepare_start()
702 spi_context_cs_control(&data->ctx, true); in spi_sam_iodev_prepare_start()
707 struct spi_sam_data *data = dev->data; in spi_sam_iodev_complete()
708 struct spi_rtio *rtio_ctx = data->rtio_ctx; in spi_sam_iodev_complete()
710 if (!status && rtio_ctx->txn_curr->sqe.flags & RTIO_SQE_TRANSACTION) { in spi_sam_iodev_complete()
711 rtio_ctx->txn_curr = rtio_txn_next(rtio_ctx->txn_curr); in spi_sam_iodev_complete()
714 /** De-assert CS-line to space from next transaction */ in spi_sam_iodev_complete()
715 spi_context_cs_control(&data->ctx, false); in spi_sam_iodev_complete()
727 struct spi_sam_data *data = dev->data; in spi_sam_iodev_submit()
728 struct spi_rtio *rtio_ctx = data->rtio_ctx; in spi_sam_iodev_submit()
742 struct spi_sam_data *data = dev->data; in spi_sam_transceive()
745 spi_context_lock(&data->ctx, false, NULL, NULL, config); in spi_sam_transceive()
748 struct spi_rtio *rtio_ctx = data->rtio_ctx; in spi_sam_transceive()
752 const struct spi_sam_config *cfg = dev->config; in spi_sam_transceive()
759 spi_context_cs_control(&data->ctx, true); in spi_sam_transceive()
764 spi_context_buffers_setup(&data->ctx, tx_bufs, rx_bufs, 1); in spi_sam_transceive()
767 spi_sam_shift_master(cfg->regs, data); in spi_sam_transceive()
771 spi_context_cs_control(&data->ctx, false); in spi_sam_transceive()
774 spi_context_release(&data->ctx, err); in spi_sam_transceive()
795 return -ENOTSUP; in spi_sam_transceive_async()
802 struct spi_sam_data *data = dev->data; in spi_sam_release()
804 spi_context_unlock_unconditionally(&data->ctx); in spi_sam_release()
812 const struct spi_sam_config *cfg = dev->config; in spi_sam_init()
813 struct spi_sam_data *data = dev->data; in spi_sam_init()
817 (clock_control_subsys_t)&cfg->clock_cfg); in spi_sam_init()
819 err = pinctrl_apply_state(cfg->pcfg, PINCTRL_STATE_DEFAULT); in spi_sam_init()
824 err = spi_context_cs_configure_all(&data->ctx); in spi_sam_init()
830 k_sem_init(&data->dma_sem, 0, K_SEM_MAX_LIMIT); in spi_sam_init()
834 spi_rtio_init(data->rtio_ctx, dev); in spi_sam_init()
837 spi_context_unlock_unconditionally(&data->ctx); in spi_sam_init()