Lines Matching +full:set +full:- +full:bit +full:- +full:to +full:- +full:deassert
5 * SPDX-License-Identifier: Apache-2.0
72 /* Used to send the last word */
79 const struct spi_mcux_config *config = dev->config; in spi_mcux_transfer_next_packet()
80 struct spi_mcux_data *data = dev->data; in spi_mcux_transfer_next_packet()
81 SPI_Type *base = config->base; in spi_mcux_transfer_next_packet()
82 struct spi_context *ctx = &data->ctx; in spi_mcux_transfer_next_packet()
86 if ((ctx->tx_len == 0) && (ctx->rx_len == 0)) { in spi_mcux_transfer_next_packet()
87 /* nothing left to rx or tx, we're done! */ in spi_mcux_transfer_next_packet()
88 spi_context_cs_control(&data->ctx, false); in spi_mcux_transfer_next_packet()
89 spi_context_complete(&data->ctx, dev, 0); in spi_mcux_transfer_next_packet()
94 if (ctx->tx_len == 0) { in spi_mcux_transfer_next_packet()
95 /* rx only, nothing to tx */ in spi_mcux_transfer_next_packet()
97 transfer.rxData = ctx->rx_buf; in spi_mcux_transfer_next_packet()
98 transfer.dataSize = ctx->rx_len; in spi_mcux_transfer_next_packet()
99 } else if (ctx->rx_len == 0) { in spi_mcux_transfer_next_packet()
100 /* tx only, nothing to rx */ in spi_mcux_transfer_next_packet()
101 transfer.txData = (uint8_t *) ctx->tx_buf; in spi_mcux_transfer_next_packet()
103 transfer.dataSize = ctx->tx_len; in spi_mcux_transfer_next_packet()
104 } else if (ctx->tx_len == ctx->rx_len) { in spi_mcux_transfer_next_packet()
106 transfer.txData = (uint8_t *) ctx->tx_buf; in spi_mcux_transfer_next_packet()
107 transfer.rxData = ctx->rx_buf; in spi_mcux_transfer_next_packet()
108 transfer.dataSize = ctx->tx_len; in spi_mcux_transfer_next_packet()
109 } else if (ctx->tx_len > ctx->rx_len) { in spi_mcux_transfer_next_packet()
110 /* Break up the tx into multiple transfers so we don't have to in spi_mcux_transfer_next_packet()
114 transfer.txData = (uint8_t *) ctx->tx_buf; in spi_mcux_transfer_next_packet()
115 transfer.rxData = ctx->rx_buf; in spi_mcux_transfer_next_packet()
116 transfer.dataSize = ctx->rx_len; in spi_mcux_transfer_next_packet()
118 /* Break up the rx into multiple transfers so we don't have to in spi_mcux_transfer_next_packet()
122 transfer.txData = (uint8_t *) ctx->tx_buf; in spi_mcux_transfer_next_packet()
123 transfer.rxData = ctx->rx_buf; in spi_mcux_transfer_next_packet()
124 transfer.dataSize = ctx->tx_len; in spi_mcux_transfer_next_packet()
127 if (ctx->tx_count <= 1 && ctx->rx_count <= 1) { in spi_mcux_transfer_next_packet()
131 data->transfer_len = transfer.dataSize; in spi_mcux_transfer_next_packet()
133 status = SPI_MasterTransferNonBlocking(base, &data->handle, &transfer); in spi_mcux_transfer_next_packet()
141 const struct spi_mcux_config *config = dev->config; in spi_mcux_isr()
142 struct spi_mcux_data *data = dev->data; in spi_mcux_isr()
143 SPI_Type *base = config->base; in spi_mcux_isr()
145 SPI_MasterTransferHandleIRQ(base, &data->handle); in spi_mcux_isr()
153 spi_context_update_tx(&data->ctx, 1, data->transfer_len); in spi_mcux_transfer_callback()
154 spi_context_update_rx(&data->ctx, 1, data->transfer_len); in spi_mcux_transfer_callback()
156 spi_mcux_transfer_next_packet(data->dev); in spi_mcux_transfer_callback()
161 /* Convert delay_ns to an integer number of clock cycles of frequency in spi_clock_cycles()
174 const struct spi_mcux_config *config = dev->config; in spi_mcux_configure()
175 struct spi_mcux_data *data = dev->data; in spi_mcux_configure()
176 SPI_Type *base = config->base; in spi_mcux_configure()
180 if (spi_context_configured(&data->ctx, spi_cfg)) { in spi_mcux_configure()
185 if (spi_cfg->operation & SPI_HALF_DUPLEX) { in spi_mcux_configure()
186 LOG_ERR("Half-duplex not supported"); in spi_mcux_configure()
187 return -ENOTSUP; in spi_mcux_configure()
190 word_size = SPI_WORD_SIZE_GET(spi_cfg->operation); in spi_mcux_configure()
194 return -EINVAL; in spi_mcux_configure()
201 if (SPI_OP_MODE_GET(spi_cfg->operation) == SPI_OP_MODE_MASTER) { in spi_mcux_configure()
206 if (!device_is_ready(config->clock_dev)) { in spi_mcux_configure()
208 return -ENODEV; in spi_mcux_configure()
212 if (clock_control_get_rate(config->clock_dev, in spi_mcux_configure()
213 config->clock_subsys, &clock_freq)) { in spi_mcux_configure()
214 return -EINVAL; in spi_mcux_configure()
217 if (spi_cfg->slave > SPI_CHIP_SELECT_COUNT) { in spi_mcux_configure()
219 spi_cfg->slave, SPI_CHIP_SELECT_COUNT); in spi_mcux_configure()
220 return -EINVAL; in spi_mcux_configure()
223 master_config.sselNum = spi_cfg->slave; in spi_mcux_configure()
225 master_config.dataWidth = word_size - 1; in spi_mcux_configure()
228 (SPI_MODE_GET(spi_cfg->operation) & SPI_MODE_CPOL) in spi_mcux_configure()
233 (SPI_MODE_GET(spi_cfg->operation) & SPI_MODE_CPHA) in spi_mcux_configure()
238 (spi_cfg->operation & SPI_TRANSFER_LSB) in spi_mcux_configure()
242 master_config.baudRate_Bps = spi_cfg->frequency; in spi_mcux_configure()
246 delayConfig->preDelay = spi_clock_cycles(config->pre_delay, in spi_mcux_configure()
247 spi_cfg->frequency); in spi_mcux_configure()
248 delayConfig->postDelay = spi_clock_cycles(config->post_delay, in spi_mcux_configure()
249 spi_cfg->frequency); in spi_mcux_configure()
250 delayConfig->frameDelay = spi_clock_cycles(config->frame_delay, in spi_mcux_configure()
251 spi_cfg->frequency); in spi_mcux_configure()
252 delayConfig->transferDelay = spi_clock_cycles(config->transfer_delay, in spi_mcux_configure()
253 spi_cfg->frequency); in spi_mcux_configure()
257 SPI_SetDummyData(base, (uint8_t)config->def_char); in spi_mcux_configure()
259 SPI_MasterTransferCreateHandle(base, &data->handle, in spi_mcux_configure()
262 data->ctx.config = spi_cfg; in spi_mcux_configure()
269 (SPI_MODE_GET(spi_cfg->operation) & SPI_MODE_CPOL) in spi_mcux_configure()
274 (SPI_MODE_GET(spi_cfg->operation) & SPI_MODE_CPHA) in spi_mcux_configure()
279 (spi_cfg->operation & SPI_TRANSFER_LSB) in spi_mcux_configure()
285 slave_config.dataWidth = word_size - 1; in spi_mcux_configure()
289 SPI_SetDummyData(base, (uint8_t)config->def_char); in spi_mcux_configure()
291 SPI_SlaveTransferCreateHandle(base, &data->handle, in spi_mcux_configure()
294 data->ctx.config = spi_cfg; in spi_mcux_configure()
307 struct spi_mcux_data *data = spi_dev->data; in spi_mcux_dma_callback()
311 data->status_flags |= SPI_MCUX_FLEXCOMM_DMA_ERROR_FLAG; in spi_mcux_dma_callback()
314 if (channel == data->dma_tx.channel) { in spi_mcux_dma_callback()
315 if (status != data->dma_tx.wait_for_dma_status) { in spi_mcux_dma_callback()
319 data->status_flags |= SPI_MCUX_FLEXCOMM_DMA_TX_DONE_FLAG; in spi_mcux_dma_callback()
320 } else if (channel == data->dma_rx.channel) { in spi_mcux_dma_callback()
322 data->status_flags |= SPI_MCUX_FLEXCOMM_DMA_RX_DONE_FLAG; in spi_mcux_dma_callback()
326 data->status_flags |= SPI_MCUX_FLEXCOMM_DMA_ERROR_FLAG; in spi_mcux_dma_callback()
330 spi_context_complete(&data->ctx, spi_dev, 0); in spi_mcux_dma_callback()
340 word_size = SPI_WORD_SIZE_GET(spi_cfg->operation); in spi_mcux_prepare_txlastword()
343 *txLastWord = (((uint32_t)buf[len - 1U] << 8U) | in spi_mcux_prepare_txlastword()
344 (buf[len - 2U])); in spi_mcux_prepare_txlastword()
346 *txLastWord = buf[len - 1U]; in spi_mcux_prepare_txlastword()
356 (~(uint32_t)SPI_DEASSERTNUM_SSEL((uint32_t)spi_cfg->slave))); in spi_mcux_prepare_txlastword()
358 /* set width of data - range asserted at entry */ in spi_mcux_prepare_txlastword()
359 *txLastWord |= SPI_FIFOWR_LEN(word_size - 1); in spi_mcux_prepare_txlastword()
368 word_size = SPI_WORD_SIZE_GET(spi_cfg->operation); in spi_mcux_prepare_txdummy()
378 (~(uint32_t)SPI_DEASSERTNUM_SSEL((uint32_t)spi_cfg->slave))); in spi_mcux_prepare_txdummy()
380 /* set width of data - range asserted at entry */ in spi_mcux_prepare_txdummy()
381 *dummy |= SPI_FIFOWR_LEN(word_size - 1); in spi_mcux_prepare_txdummy()
388 const struct spi_mcux_config *cfg = dev->config; in spi_mcux_dma_tx_load()
389 struct spi_mcux_data *data = dev->data; in spi_mcux_dma_tx_load()
392 SPI_Type *base = cfg->base; in spi_mcux_dma_tx_load()
395 word_size = SPI_WORD_SIZE_GET(spi_cfg->operation); in spi_mcux_dma_tx_load()
398 struct stream *stream = &data->dma_tx; in spi_mcux_dma_tx_load()
400 blk_cfg = &stream->dma_blk_cfg[0]; in spi_mcux_dma_tx_load()
407 data->dummy_tx_buffer = 0; in spi_mcux_dma_tx_load()
408 data->last_word = 0; in spi_mcux_dma_tx_load()
409 spi_mcux_prepare_txdummy(&data->dummy_tx_buffer, last_packet, spi_cfg, rx_ignore); in spi_mcux_dma_tx_load()
413 spi_mcux_prepare_txdummy(&data->last_word, last_packet, spi_cfg, rx_ignore); in spi_mcux_dma_tx_load()
414 blk_cfg->source_address = (uint32_t)&data->dummy_tx_buffer; in spi_mcux_dma_tx_load()
415 blk_cfg->dest_address = (uint32_t)&base->FIFOWR; in spi_mcux_dma_tx_load()
416 blk_cfg->block_size = (word_size > 8) ? in spi_mcux_dma_tx_load()
417 (len - 2U) : (len - 1U); in spi_mcux_dma_tx_load()
418 blk_cfg->next_block = &stream->dma_blk_cfg[1]; in spi_mcux_dma_tx_load()
419 blk_cfg->source_addr_adj = DMA_ADDR_ADJ_NO_CHANGE; in spi_mcux_dma_tx_load()
420 blk_cfg->dest_addr_adj = DMA_ADDR_ADJ_NO_CHANGE; in spi_mcux_dma_tx_load()
422 blk_cfg = &stream->dma_blk_cfg[1]; in spi_mcux_dma_tx_load()
426 blk_cfg->source_address = (uint32_t)&data->last_word; in spi_mcux_dma_tx_load()
427 blk_cfg->dest_address = (uint32_t)&base->FIFOWR; in spi_mcux_dma_tx_load()
428 blk_cfg->block_size = sizeof(uint32_t); in spi_mcux_dma_tx_load()
429 blk_cfg->source_addr_adj = DMA_ADDR_ADJ_NO_CHANGE; in spi_mcux_dma_tx_load()
430 blk_cfg->dest_addr_adj = DMA_ADDR_ADJ_NO_CHANGE; in spi_mcux_dma_tx_load()
431 data->dma_tx.wait_for_dma_status = DMA_STATUS_COMPLETE; in spi_mcux_dma_tx_load()
433 blk_cfg->source_address = (uint32_t)&data->dummy_tx_buffer; in spi_mcux_dma_tx_load()
434 blk_cfg->dest_address = (uint32_t)&base->FIFOWR; in spi_mcux_dma_tx_load()
435 blk_cfg->block_size = len; in spi_mcux_dma_tx_load()
436 blk_cfg->source_addr_adj = DMA_ADDR_ADJ_NO_CHANGE; in spi_mcux_dma_tx_load()
437 blk_cfg->dest_addr_adj = DMA_ADDR_ADJ_NO_CHANGE; in spi_mcux_dma_tx_load()
438 data->dma_tx.wait_for_dma_status = DMA_STATUS_BLOCK; in spi_mcux_dma_tx_load()
442 spi_mcux_prepare_txlastword(&data->last_word, buf, spi_cfg, len, rx_ignore); in spi_mcux_dma_tx_load()
445 * use dma descriptor to send the last data. in spi_mcux_dma_tx_load()
449 blk_cfg->source_address = (uint32_t)buf; in spi_mcux_dma_tx_load()
450 blk_cfg->dest_address = (uint32_t)&base->FIFOWR; in spi_mcux_dma_tx_load()
451 blk_cfg->block_size = (word_size > 8) ? in spi_mcux_dma_tx_load()
452 (len - 2U) : (len - 1U); in spi_mcux_dma_tx_load()
453 blk_cfg->next_block = &stream->dma_blk_cfg[1]; in spi_mcux_dma_tx_load()
455 blk_cfg = &stream->dma_blk_cfg[1]; in spi_mcux_dma_tx_load()
459 blk_cfg->source_address = (uint32_t)&data->last_word; in spi_mcux_dma_tx_load()
460 blk_cfg->dest_address = (uint32_t)&base->FIFOWR; in spi_mcux_dma_tx_load()
461 blk_cfg->block_size = sizeof(uint32_t); in spi_mcux_dma_tx_load()
462 blk_cfg->source_addr_adj = DMA_ADDR_ADJ_NO_CHANGE; in spi_mcux_dma_tx_load()
463 blk_cfg->dest_addr_adj = DMA_ADDR_ADJ_NO_CHANGE; in spi_mcux_dma_tx_load()
464 data->dma_tx.wait_for_dma_status = DMA_STATUS_COMPLETE; in spi_mcux_dma_tx_load()
466 blk_cfg->source_address = (uint32_t)buf; in spi_mcux_dma_tx_load()
467 blk_cfg->dest_address = (uint32_t)&base->FIFOWR; in spi_mcux_dma_tx_load()
468 blk_cfg->block_size = len; in spi_mcux_dma_tx_load()
469 data->dma_tx.wait_for_dma_status = DMA_STATUS_BLOCK; in spi_mcux_dma_tx_load()
474 base->FIFOCFG |= SPI_FIFOCFG_DMATX_MASK; in spi_mcux_dma_tx_load()
477 stream->dma_cfg.head_block = &stream->dma_blk_cfg[0]; in spi_mcux_dma_tx_load()
479 stream->dma_cfg.user_data = (struct device *)dev; in spi_mcux_dma_tx_load()
480 /* pass our client origin to the dma: data->dma_tx.dma_channel */ in spi_mcux_dma_tx_load()
481 ret = dma_config(data->dma_tx.dma_dev, data->dma_tx.channel, in spi_mcux_dma_tx_load()
482 &stream->dma_cfg); in spi_mcux_dma_tx_load()
493 * Halfword writes to just the control bits (offset 0xE22) doesn't push in spi_mcux_dma_tx_load()
495 * be uint16_t, byte writes or halfword writes to FIFOWR will push the in spi_mcux_dma_tx_load()
500 *((uint16_t *)((uint32_t)&base->FIFOWR) + 1) = (uint16_t)(tmpData >> 16U); in spi_mcux_dma_tx_load()
502 /* Clear the SPI_FIFOWR_EOT_MASK bit when data is not the last */ in spi_mcux_dma_tx_load()
504 *((uint16_t *)((uint32_t)&base->FIFOWR) + 1) = (uint16_t)(tmpData >> 16U); in spi_mcux_dma_tx_load()
508 return dma_start(data->dma_tx.dma_dev, data->dma_tx.channel); in spi_mcux_dma_tx_load()
514 const struct spi_mcux_config *cfg = dev->config; in spi_mcux_dma_rx_load()
515 struct spi_mcux_data *data = dev->data; in spi_mcux_dma_rx_load()
518 SPI_Type *base = cfg->base; in spi_mcux_dma_rx_load()
521 struct stream *stream = &data->dma_rx; in spi_mcux_dma_rx_load()
524 data->status_flags |= SPI_MCUX_FLEXCOMM_DMA_RX_DONE_FLAG; in spi_mcux_dma_rx_load()
528 blk_cfg = &stream->dma_blk_cfg[0]; in spi_mcux_dma_rx_load()
532 blk_cfg->block_size = len; in spi_mcux_dma_rx_load()
535 blk_cfg->dest_address = (uint32_t)buf; in spi_mcux_dma_rx_load()
536 blk_cfg->source_address = (uint32_t)&base->FIFORD; in spi_mcux_dma_rx_load()
539 stream->dma_cfg.head_block = blk_cfg; in spi_mcux_dma_rx_load()
540 stream->dma_cfg.user_data = (struct device *)dev; in spi_mcux_dma_rx_load()
543 base->FIFOCFG |= SPI_FIFOCFG_DMARX_MASK; in spi_mcux_dma_rx_load()
545 /* pass our client origin to the dma: data->dma_rx.channel */ in spi_mcux_dma_rx_load()
546 ret = dma_config(data->dma_rx.dma_dev, data->dma_rx.channel, in spi_mcux_dma_rx_load()
547 &stream->dma_cfg); in spi_mcux_dma_rx_load()
554 return dma_start(data->dma_rx.dma_dev, data->dma_rx.channel); in spi_mcux_dma_rx_load()
560 struct spi_mcux_data *data = dev->data; in spi_mcux_dma_move_buffers()
561 bool rx_ignore = data->ctx.rx_buf ? false : true; in spi_mcux_dma_move_buffers()
564 ret = spi_mcux_dma_rx_load(dev, data->ctx.rx_buf, len); in spi_mcux_dma_move_buffers()
570 ret = spi_mcux_dma_tx_load(dev, data->ctx.tx_buf, spi_cfg, in spi_mcux_dma_move_buffers()
578 struct spi_mcux_data *data = dev->data; in wait_dma_rx_tx_done()
579 int ret = -1; in wait_dma_rx_tx_done()
582 ret = spi_context_wait_for_completion(&data->ctx); in wait_dma_rx_tx_done()
583 if (data->status_flags & SPI_MCUX_FLEXCOMM_DMA_ERROR_FLAG) { in wait_dma_rx_tx_done()
584 return -EIO; in wait_dma_rx_tx_done()
587 if ((data->status_flags & SPI_MCUX_FLEXCOMM_DMA_DONE_FLAG) == in wait_dma_rx_tx_done()
602 const struct spi_mcux_config *config = dev->config; in transceive_dma()
603 struct spi_mcux_data *data = dev->data; in transceive_dma()
604 SPI_Type *base = config->base; in transceive_dma()
609 spi_context_lock(&data->ctx, asynchronous, cb, userdata, spi_cfg); in transceive_dma()
616 spi_context_buffers_setup(&data->ctx, tx_bufs, rx_bufs, 1); in transceive_dma()
618 spi_context_cs_control(&data->ctx, true); in transceive_dma()
620 word_size = SPI_WORD_SIZE_GET(spi_cfg->operation); in transceive_dma()
623 data->dma_rx.dma_cfg.source_data_size = data_size; in transceive_dma()
624 data->dma_rx.dma_cfg.dest_data_size = data_size; in transceive_dma()
625 data->dma_tx.dma_cfg.source_data_size = data_size; in transceive_dma()
626 data->dma_tx.dma_cfg.dest_data_size = data_size; in transceive_dma()
628 while (data->ctx.rx_len > 0 || data->ctx.tx_len > 0) { in transceive_dma()
631 /* last is used to deassert chip select if this in transceive_dma()
632 * is the last transfer in the set. in transceive_dma()
636 if (data->ctx.rx_len == 0) { in transceive_dma()
637 dma_len = data->ctx.tx_len; in transceive_dma()
639 } else if (data->ctx.tx_len == 0) { in transceive_dma()
640 dma_len = data->ctx.rx_len; in transceive_dma()
642 } else if (data->ctx.tx_len == data->ctx.rx_len) { in transceive_dma()
643 dma_len = data->ctx.rx_len; in transceive_dma()
646 dma_len = MIN(data->ctx.tx_len, data->ctx.rx_len); in transceive_dma()
652 * the current tx/rx buffer in data->ctx in transceive_dma()
657 * we'll move to the next pair of buffers (if any) in transceive_dma()
660 * transfer in the set and we need to deassert CS. in transceive_dma()
664 * the entire current data->ctx set in transceive_dma()
666 * buffers in the set, then we don't in transceive_dma()
667 * want to deassert CS. in transceive_dma()
669 if ((data->ctx.tx_count > 1) || in transceive_dma()
670 (data->ctx.rx_count > 1)) { in transceive_dma()
671 /* more buffers to transfer so in transceive_dma()
678 data->status_flags = 0; in transceive_dma()
691 while (0U == (base->FIFOSTAT & SPI_FIFOSTAT_TXEMPTY_MASK)) { in transceive_dma()
694 spi_context_update_tx(&data->ctx, 1, dma_len); in transceive_dma()
695 spi_context_update_rx(&data->ctx, 1, dma_len); in transceive_dma()
698 base->FIFOCFG &= ~SPI_FIFOCFG_DMATX_MASK; in transceive_dma()
699 base->FIFOCFG &= ~SPI_FIFOCFG_DMARX_MASK; in transceive_dma()
701 spi_context_cs_control(&data->ctx, false); in transceive_dma()
704 spi_context_release(&data->ctx, ret); in transceive_dma()
719 struct spi_mcux_data *data = dev->data; in transceive()
722 spi_context_lock(&data->ctx, asynchronous, cb, userdata, spi_cfg); in transceive()
729 spi_context_buffers_setup(&data->ctx, tx_bufs, rx_bufs, 1); in transceive()
731 spi_context_cs_control(&data->ctx, true); in transceive()
735 ret = spi_context_wait_for_completion(&data->ctx); in transceive()
737 spi_context_release(&data->ctx, ret); in transceive()
772 struct spi_mcux_data *data = dev->data; in spi_mcux_release()
774 spi_context_unlock_unconditionally(&data->ctx); in spi_mcux_release()
781 const struct spi_mcux_config *config = dev->config; in spi_mcux_init()
782 struct spi_mcux_data *data = dev->data; in spi_mcux_init()
785 if (!device_is_ready(config->reset.dev)) { in spi_mcux_init()
787 return -ENODEV; in spi_mcux_init()
790 err = reset_line_toggle(config->reset.dev, config->reset.id); in spi_mcux_init()
795 config->irq_config_func(dev); in spi_mcux_init()
797 data->dev = dev; in spi_mcux_init()
799 err = pinctrl_apply_state(config->pincfg, PINCTRL_STATE_DEFAULT); in spi_mcux_init()
805 if (!device_is_ready(data->dma_tx.dma_dev)) { in spi_mcux_init()
806 LOG_ERR("%s device is not ready", data->dma_tx.dma_dev->name); in spi_mcux_init()
807 return -ENODEV; in spi_mcux_init()
810 if (!device_is_ready(data->dma_rx.dma_dev)) { in spi_mcux_init()
811 LOG_ERR("%s device is not ready", data->dma_rx.dma_dev->name); in spi_mcux_init()
812 return -ENODEV; in spi_mcux_init()
817 err = spi_context_cs_configure_all(&data->ctx); in spi_mcux_init()
822 spi_context_unlock_unconditionally(&data->ctx); in spi_mcux_init()