From 4c20403629df1ae6a58d37a7a5bd73d4698cc11a Mon Sep 17 00:00:00 2001 From: Tom Burdick Date: Mon, 15 Aug 2022 15:57:43 -0500 Subject: [PATCH] spi: callback API for asynchronous transcieve Adds a new spi_transcieve_cb API which enables asynchronous SPI transactions with callback notification. The exist spi_transcieve_async API remains and uses the new spi_transcieve_cb API to provide a k_poll_signal notifier. The driver API changes to provide a callback and userdata parameter to async transcieve. All drivers in the tree have been updated to the change. Signed-off-by: Tom Burdick --- drivers/spi/CMakeLists.txt | 1 + drivers/spi/spi_b91.c | 10 +- drivers/spi/spi_bitbang.c | 2 +- drivers/spi/spi_cc13xx_cc26xx.c | 2 +- drivers/spi/spi_context.h | 17 ++- drivers/spi/spi_dw.c | 16 +-- drivers/spi/spi_esp32_spim.c | 21 ++-- drivers/spi/spi_ll_stm32.c | 23 ++-- drivers/spi/spi_mcux_dspi.c | 14 ++- drivers/spi/spi_mcux_flexcomm.c | 30 ++--- drivers/spi/spi_mcux_lpspi.c | 30 ++--- drivers/spi/spi_npcx_fiu.c | 2 +- drivers/spi/spi_nrfx_spi.c | 14 ++- drivers/spi/spi_nrfx_spim.c | 14 ++- drivers/spi/spi_nrfx_spis.c | 17 +-- drivers/spi/spi_oc_simple.c | 4 +- drivers/spi/spi_pl022.c | 18 +-- drivers/spi/spi_psoc6.c | 9 +- drivers/spi/spi_rv32m1_lpspi.c | 14 ++- drivers/spi/spi_sam.c | 7 +- drivers/spi/spi_sam0.c | 11 +- drivers/spi/spi_signal.c | 28 +++++ drivers/spi/spi_test.c | 3 +- drivers/spi/spi_xec_qmspi.c | 2 +- drivers/spi/spi_xec_qmspi_ldma.c | 11 +- drivers/spi/spi_xlnx_axi_quadspi.c | 17 +-- include/zephyr/drivers/spi.h | 134 ++++++++++++++++++++--- tests/drivers/spi/spi_loopback/src/spi.c | 2 +- 28 files changed, 325 insertions(+), 148 deletions(-) create mode 100644 drivers/spi/spi_signal.c diff --git a/drivers/spi/CMakeLists.txt b/drivers/spi/CMakeLists.txt index b9e59571a32..9774fe73349 100644 --- a/drivers/spi/CMakeLists.txt +++ b/drivers/spi/CMakeLists.txt @@ -32,4 +32,5 @@ zephyr_library_sources_ifdef(CONFIG_SPI_GD32 spi_gd32.c) zephyr_library_sources_ifdef(CONFIG_SPI_MCHP_QSPI spi_mchp_mss_qspi.c) zephyr_library_sources_ifdef(CONFIG_SPI_PL022 spi_pl022.c) +zephyr_library_sources_ifdef(CONFIG_SPI_ASYNC spi_signal.c) zephyr_library_sources_ifdef(CONFIG_USERSPACE spi_handlers.c) diff --git a/drivers/spi/spi_b91.c b/drivers/spi/spi_b91.c index ad804cbd6e2..9c402a6a368 100644 --- a/drivers/spi/spi_b91.c +++ b/drivers/spi/spi_b91.c @@ -233,7 +233,7 @@ static void spi_b91_txrx(const struct device *dev, uint32_t len) }; /* context complete */ - spi_context_complete(ctx, 0); + spi_context_complete(ctx, dev, 0); } /* Check for supported configuration */ @@ -393,7 +393,7 @@ static int spi_b91_transceive(const struct device *dev, } /* context setup */ - spi_context_lock(&data->ctx, false, NULL, config); + spi_context_lock(&data->ctx, false, NULL, NULL, config); spi_context_buffers_setup(&data->ctx, tx_bufs, rx_bufs, 1); /* if cs is defined: software cs control, set active true */ @@ -422,13 +422,15 @@ static int spi_b91_transceive_async(const struct device *dev, const struct spi_config *config, const struct spi_buf_set *tx_bufs, const struct spi_buf_set *rx_bufs, - struct k_poll_signal *async) + spi_callback_t cb, + void *userdata) { ARG_UNUSED(dev); ARG_UNUSED(config); ARG_UNUSED(tx_bufs); ARG_UNUSED(rx_bufs); - ARG_UNUSED(async); + ARG_UNUSED(cb); + ARG_UNUSED(userdata); return -ENOTSUP; } diff --git a/drivers/spi/spi_bitbang.c b/drivers/spi/spi_bitbang.c index b0e2d587e52..ff8935a0801 100644 --- a/drivers/spi/spi_bitbang.c +++ b/drivers/spi/spi_bitbang.c @@ -221,7 +221,7 @@ static int spi_bitbang_transceive(const struct device *dev, spi_context_cs_control(ctx, false); - spi_context_complete(ctx, 0); + spi_context_complete(ctx, dev, 0); return 0; } diff --git a/drivers/spi/spi_cc13xx_cc26xx.c b/drivers/spi/spi_cc13xx_cc26xx.c index dd3a852fc08..eba9433442d 100644 --- a/drivers/spi/spi_cc13xx_cc26xx.c +++ b/drivers/spi/spi_cc13xx_cc26xx.c @@ -140,7 +140,7 @@ static int spi_cc13xx_cc26xx_transceive(const struct device *dev, uint32_t txd, rxd; int err; - spi_context_lock(ctx, false, NULL, config); + spi_context_lock(ctx, false, NULL, NULL, config); pm_policy_state_lock_get(PM_STATE_STANDBY, PM_ALL_SUBSTATES); err = spi_cc13xx_cc26xx_configure(dev, config); diff --git a/drivers/spi/spi_context.h b/drivers/spi/spi_context.h index b9d8ab31bb7..0e2df0d53d9 100644 --- a/drivers/spi/spi_context.h +++ b/drivers/spi/spi_context.h @@ -35,7 +35,8 @@ struct spi_context { int sync_status; #ifdef CONFIG_SPI_ASYNC - struct k_poll_signal *signal; + spi_callback_t callback; + void *callback_data; bool asynchronous; #endif /* CONFIG_SPI_ASYNC */ const struct spi_buf *current_tx; @@ -86,7 +87,8 @@ static inline bool spi_context_is_slave(struct spi_context *ctx) static inline void spi_context_lock(struct spi_context *ctx, bool asynchronous, - struct k_poll_signal *signal, + spi_callback_t callback, + void *callback_data, const struct spi_config *spi_cfg) { if ((spi_cfg->operation & SPI_LOCK_ON) && @@ -100,7 +102,8 @@ static inline void spi_context_lock(struct spi_context *ctx, #ifdef CONFIG_SPI_ASYNC ctx->asynchronous = asynchronous; - ctx->signal = signal; + ctx->callback = callback; + ctx->callback_data = callback_data; #endif /* CONFIG_SPI_ASYNC */ } @@ -171,14 +174,16 @@ static inline int spi_context_wait_for_completion(struct spi_context *ctx) return status; } -static inline void spi_context_complete(struct spi_context *ctx, int status) +static inline void spi_context_complete(struct spi_context *ctx, + const struct device *dev, + int status) { #ifdef CONFIG_SPI_ASYNC if (!ctx->asynchronous) { ctx->sync_status = status; k_sem_give(&ctx->sync); } else { - if (ctx->signal) { + if (ctx->callback) { #ifdef CONFIG_SPI_SLAVE if (spi_context_is_slave(ctx) && !status) { /* Let's update the status so it tells @@ -187,7 +192,7 @@ static inline void spi_context_complete(struct spi_context *ctx, int status) status = ctx->recv_frames; } #endif /* CONFIG_SPI_SLAVE */ - k_poll_signal_raise(ctx->signal, status); + ctx->callback(dev, status, ctx->callback_data); } if (!(ctx->config->operation & SPI_LOCK_ON)) { diff --git a/drivers/spi/spi_dw.c b/drivers/spi/spi_dw.c index 4d6b0c9f3ee..d4ccd267a3d 100644 --- a/drivers/spi/spi_dw.c +++ b/drivers/spi/spi_dw.c @@ -81,7 +81,7 @@ out: LOG_DBG("SPI transaction completed %s error", error ? "with" : "without"); - spi_context_complete(&spi->ctx, error); + spi_context_complete(&spi->ctx, dev, error); } static void push_data(const struct device *dev) @@ -338,7 +338,8 @@ static int transceive(const struct device *dev, const struct spi_buf_set *tx_bufs, const struct spi_buf_set *rx_bufs, bool asynchronous, - struct k_poll_signal *signal) + spi_callback_t cb, + void *userdata) { const struct spi_dw_config *info = dev->config; struct spi_dw_data *spi = dev->data; @@ -346,7 +347,7 @@ static int transceive(const struct device *dev, uint32_t reg_data; int ret; - spi_context_lock(&spi->ctx, asynchronous, signal, config); + spi_context_lock(&spi->ctx, asynchronous, cb, userdata, config); #ifdef CONFIG_PM_DEVICE if (!pm_device_is_busy(dev)) { @@ -451,7 +452,7 @@ static int spi_dw_transceive(const struct device *dev, { LOG_DBG("%p, %p, %p", dev, tx_bufs, rx_bufs); - return transceive(dev, config, tx_bufs, rx_bufs, false, NULL); + return transceive(dev, config, tx_bufs, rx_bufs, false, NULL, NULL); } #ifdef CONFIG_SPI_ASYNC @@ -459,11 +460,12 @@ static int spi_dw_transceive_async(const struct device *dev, const struct spi_config *config, const struct spi_buf_set *tx_bufs, const struct spi_buf_set *rx_bufs, - struct k_poll_signal *async) + spi_callback_t cb, + void *userdata) { - LOG_DBG("%p, %p, %p, %p", dev, tx_bufs, rx_bufs, async); + LOG_DBG("%p, %p, %p, %p, %p", dev, tx_bufs, rx_bufs, cb, userdata); - return transceive(dev, config, tx_bufs, rx_bufs, true, async); + return transceive(dev, config, tx_bufs, rx_bufs, true, cb, userdata); } #endif /* CONFIG_SPI_ASYNC */ diff --git a/drivers/spi/spi_esp32_spim.c b/drivers/spi/spi_esp32_spim.c index 43df0a71e5a..43438e1bf02 100644 --- a/drivers/spi/spi_esp32_spim.c +++ b/drivers/spi/spi_esp32_spim.c @@ -35,7 +35,8 @@ static bool spi_esp32_transfer_ongoing(struct spi_esp32_data *data) return spi_context_tx_on(&data->ctx) || spi_context_rx_on(&data->ctx); } -static inline void spi_esp32_complete(struct spi_esp32_data *data, +static inline void spi_esp32_complete(const struct device *dev, + struct spi_esp32_data *data, spi_dev_t *spi, int status) { #ifdef CONFIG_SPI_ESP32_INTERRUPT @@ -46,7 +47,7 @@ static inline void spi_esp32_complete(struct spi_esp32_data *data, spi_context_cs_control(&data->ctx, false); #ifdef CONFIG_SPI_ESP32_INTERRUPT - spi_context_complete(&data->ctx, status); + spi_context_complete(&data->ctx, dev, status); #endif } @@ -98,7 +99,7 @@ static void IRAM_ATTR spi_esp32_isr(void *arg) spi_esp32_transfer(dev); } while (spi_esp32_transfer_ongoing(data)); - spi_esp32_complete(data, cfg->spi, 0); + spi_esp32_complete(dev, data, cfg->spi, 0); } #endif @@ -249,7 +250,8 @@ static int transceive(const struct device *dev, const struct spi_config *spi_cfg, const struct spi_buf_set *tx_bufs, const struct spi_buf_set *rx_bufs, bool asynchronous, - struct k_poll_signal *signal) + spi_callback_t cb, + void *userdata) { const struct spi_esp32_config *cfg = dev->config; struct spi_esp32_data *data = dev->data; @@ -265,7 +267,7 @@ static int transceive(const struct device *dev, } #endif - spi_context_lock(&data->ctx, asynchronous, signal, spi_cfg); + spi_context_lock(&data->ctx, asynchronous, cb, userdata, spi_cfg); ret = spi_esp32_configure(dev, spi_cfg); if (ret) { @@ -287,7 +289,7 @@ static int transceive(const struct device *dev, spi_esp32_transfer(dev); } while (spi_esp32_transfer_ongoing(data)); - spi_esp32_complete(data, cfg->spi, 0); + spi_esp32_complete(dev, data, cfg->spi, 0); #endif /* CONFIG_SPI_ESP32_INTERRUPT */ @@ -302,7 +304,7 @@ static int spi_esp32_transceive(const struct device *dev, const struct spi_buf_set *tx_bufs, const struct spi_buf_set *rx_bufs) { - return transceive(dev, spi_cfg, tx_bufs, rx_bufs, false, NULL); + return transceive(dev, spi_cfg, tx_bufs, rx_bufs, false, NULL, NULL); } #ifdef CONFIG_SPI_ASYNC @@ -310,9 +312,10 @@ static int spi_esp32_transceive_async(const struct device *dev, const struct spi_config *spi_cfg, const struct spi_buf_set *tx_bufs, const struct spi_buf_set *rx_bufs, - struct k_poll_signal *async) + spi_callback_t cb, + void *userdata) { - return transceive(dev, spi_cfg, tx_bufs, rx_bufs, true, async); + return transceive(dev, spi_cfg, tx_bufs, rx_bufs, true, cb, userdata); } #endif /* CONFIG_SPI_ASYNC */ diff --git a/drivers/spi/spi_ll_stm32.c b/drivers/spi/spi_ll_stm32.c index fd914db9665..4fda21a1399 100644 --- a/drivers/spi/spi_ll_stm32.c +++ b/drivers/spi/spi_ll_stm32.c @@ -413,7 +413,7 @@ static void spi_stm32_complete(const struct device *dev, int status) ll_func_disable_spi(spi); #ifdef CONFIG_SPI_STM32_INTERRUPT - spi_context_complete(&data->ctx, status); + spi_context_complete(&data->ctx, dev, status); #endif } @@ -600,7 +600,9 @@ static int transceive(const struct device *dev, const struct spi_config *config, const struct spi_buf_set *tx_bufs, const struct spi_buf_set *rx_bufs, - bool asynchronous, struct k_poll_signal *signal) + bool asynchronous, + spi_callback_t cb, + void *userdata) { const struct spi_stm32_config *cfg = dev->config; struct spi_stm32_data *data = dev->data; @@ -617,7 +619,7 @@ static int transceive(const struct device *dev, } #endif - spi_context_lock(&data->ctx, asynchronous, signal, config); + spi_context_lock(&data->ctx, asynchronous, cb, userdata, config); ret = spi_stm32_configure(dev, config); if (ret) { @@ -699,7 +701,9 @@ static int transceive_dma(const struct device *dev, const struct spi_config *config, const struct spi_buf_set *tx_bufs, const struct spi_buf_set *rx_bufs, - bool asynchronous, struct k_poll_signal *signal) + bool asynchronous, + spi_callback_t cb, + void *userdata) { const struct spi_stm32_config *cfg = dev->config; struct spi_stm32_data *data = dev->data; @@ -714,7 +718,7 @@ static int transceive_dma(const struct device *dev, return -ENOTSUP; } - spi_context_lock(&data->ctx, asynchronous, signal, config); + spi_context_lock(&data->ctx, asynchronous, cb, userdata, config); k_sem_reset(&data->status_sem); @@ -819,10 +823,10 @@ static int spi_stm32_transceive(const struct device *dev, if ((data->dma_tx.dma_dev != NULL) && (data->dma_rx.dma_dev != NULL)) { return transceive_dma(dev, config, tx_bufs, rx_bufs, - false, NULL); + false, NULL, NULL); } #endif /* CONFIG_SPI_STM32_DMA */ - return transceive(dev, config, tx_bufs, rx_bufs, false, NULL); + return transceive(dev, config, tx_bufs, rx_bufs, false, NULL, NULL); } #ifdef CONFIG_SPI_ASYNC @@ -830,9 +834,10 @@ static int spi_stm32_transceive_async(const struct device *dev, const struct spi_config *config, const struct spi_buf_set *tx_bufs, const struct spi_buf_set *rx_bufs, - struct k_poll_signal *async) + spi_callback_t cb, + void *userdata) { - return transceive(dev, config, tx_bufs, rx_bufs, true, async); + return transceive(dev, config, tx_bufs, rx_bufs, true, cb, userdata); } #endif /* CONFIG_SPI_ASYNC */ diff --git a/drivers/spi/spi_mcux_dspi.c b/drivers/spi/spi_mcux_dspi.c index d3a13177860..5a3980bb397 100644 --- a/drivers/spi/spi_mcux_dspi.c +++ b/drivers/spi/spi_mcux_dspi.c @@ -95,7 +95,7 @@ static int spi_mcux_transfer_next_packet(const struct device *dev) /* nothing left to rx or tx, we're done! */ LOG_DBG("spi transceive done"); spi_context_cs_control(&data->ctx, false); - spi_context_complete(&data->ctx, 0); + spi_context_complete(&data->ctx, dev, 0); return 0; } @@ -675,7 +675,8 @@ static int transceive(const struct device *dev, const struct spi_buf_set *tx_bufs, const struct spi_buf_set *rx_bufs, bool asynchronous, - struct k_poll_signal *signal) + spi_callback_t cb, + void *userdata) { struct spi_mcux_data *data = dev->data; int ret; @@ -684,7 +685,7 @@ static int transceive(const struct device *dev, SPI_Type *base = config->base; #endif - spi_context_lock(&data->ctx, asynchronous, signal, spi_cfg); + spi_context_lock(&data->ctx, asynchronous, cb, userdata, spi_cfg); ret = spi_mcux_configure(dev, spi_cfg); if (ret) { @@ -731,7 +732,7 @@ static int spi_mcux_transceive(const struct device *dev, const struct spi_buf_set *tx_bufs, const struct spi_buf_set *rx_bufs) { - return transceive(dev, spi_cfg, tx_bufs, rx_bufs, false, NULL); + return transceive(dev, spi_cfg, tx_bufs, rx_bufs, false, NULL, NULL); } #ifdef CONFIG_SPI_ASYNC @@ -739,9 +740,10 @@ static int spi_mcux_transceive_async(const struct device *dev, const struct spi_config *spi_cfg, const struct spi_buf_set *tx_bufs, const struct spi_buf_set *rx_bufs, - struct k_poll_signal *async) + spi_callback_t cb, + void *userdata) { - return transceive(dev, spi_cfg, tx_bufs, rx_bufs, true, async); + return transceive(dev, spi_cfg, tx_bufs, rx_bufs, true, cb, userdata); } #endif /* CONFIG_SPI_ASYNC */ diff --git a/drivers/spi/spi_mcux_flexcomm.c b/drivers/spi/spi_mcux_flexcomm.c index ccf236b64de..34108d08d42 100644 --- a/drivers/spi/spi_mcux_flexcomm.c +++ b/drivers/spi/spi_mcux_flexcomm.c @@ -85,7 +85,7 @@ static void spi_mcux_transfer_next_packet(const struct device *dev) if ((ctx->tx_len == 0) && (ctx->rx_len == 0)) { /* nothing left to rx or tx, we're done! */ spi_context_cs_control(&data->ctx, false); - spi_context_complete(&data->ctx, 0); + spi_context_complete(&data->ctx, dev, 0); return; } @@ -305,7 +305,8 @@ static void spi_mcux_dma_callback(const struct device *dev, void *arg, uint32_t channel, int status) { /* arg directly holds the spi device */ - struct spi_mcux_data *data = arg; + const struct device *spi_dev = arg; + struct spi_mcux_data *data = spi_dev->data; if (status != 0) { LOG_ERR("DMA callback error with channel %d.", channel); @@ -325,7 +326,7 @@ static void spi_mcux_dma_callback(const struct device *dev, void *arg, } } - spi_context_complete(&data->ctx, 0); + spi_context_complete(&data->ctx, spi_dev, 0); } @@ -463,7 +464,7 @@ static int spi_mcux_dma_tx_load(const struct device *dev, const uint8_t *buf, /* direction is given by the DT */ stream->dma_cfg.head_block = &stream->dma_blk_cfg[0]; /* give the client dev as arg, as the callback comes from the dma */ - stream->dma_cfg.user_data = data; + stream->dma_cfg.user_data = (struct device *)dev; /* pass our client origin to the dma: data->dma_tx.dma_channel */ ret = dma_config(data->dma_tx.dma_dev, data->dma_tx.channel, &stream->dma_cfg); @@ -525,7 +526,7 @@ static int spi_mcux_dma_rx_load(const struct device *dev, uint8_t *buf, /* direction is given by the DT */ stream->dma_cfg.head_block = blk_cfg; - stream->dma_cfg.user_data = data; + stream->dma_cfg.user_data = (struct device *)dev; /* Enables the DMA request from SPI rxFIFO */ base->FIFOCFG |= SPI_FIFOCFG_DMARX_MASK; @@ -583,7 +584,8 @@ static int transceive_dma(const struct device *dev, const struct spi_buf_set *tx_bufs, const struct spi_buf_set *rx_bufs, bool asynchronous, - struct k_poll_signal *signal) + spi_callback_t cb, + void *userdata) { const struct spi_mcux_config *config = dev->config; struct spi_mcux_data *data = dev->data; @@ -591,7 +593,7 @@ static int transceive_dma(const struct device *dev, int ret; uint32_t word_size; - spi_context_lock(&data->ctx, asynchronous, signal, spi_cfg); + spi_context_lock(&data->ctx, asynchronous, cb, userdata, spi_cfg); ret = spi_mcux_configure(dev, spi_cfg); if (ret) { @@ -664,12 +666,13 @@ static int transceive(const struct device *dev, const struct spi_buf_set *tx_bufs, const struct spi_buf_set *rx_bufs, bool asynchronous, - struct k_poll_signal *signal) + spi_callback_t cb, + void *userdata) { struct spi_mcux_data *data = dev->data; int ret; - spi_context_lock(&data->ctx, asynchronous, signal, spi_cfg); + spi_context_lock(&data->ctx, asynchronous, cb, userdata, spi_cfg); ret = spi_mcux_configure(dev, spi_cfg); if (ret) { @@ -695,9 +698,9 @@ static int spi_mcux_transceive(const struct device *dev, const struct spi_buf_set *rx_bufs) { #ifdef CONFIG_SPI_MCUX_FLEXCOMM_DMA - return transceive_dma(dev, spi_cfg, tx_bufs, rx_bufs, false, NULL); + return transceive_dma(dev, spi_cfg, tx_bufs, rx_bufs, false, NULL, NULL); #endif - return transceive(dev, spi_cfg, tx_bufs, rx_bufs, false, NULL); + return transceive(dev, spi_cfg, tx_bufs, rx_bufs, false, NULL, NULL); } #ifdef CONFIG_SPI_ASYNC @@ -705,9 +708,10 @@ static int spi_mcux_transceive_async(const struct device *dev, const struct spi_config *spi_cfg, const struct spi_buf_set *tx_bufs, const struct spi_buf_set *rx_bufs, - struct k_poll_signal *async) + spi_callback_t cb, + void *userdata) { - return transceive(dev, spi_cfg, tx_bufs, rx_bufs, true, async); + return transceive(dev, spi_cfg, tx_bufs, rx_bufs, true, cb, userdata); } #endif /* CONFIG_SPI_ASYNC */ diff --git a/drivers/spi/spi_mcux_lpspi.c b/drivers/spi/spi_mcux_lpspi.c index f8ebea89ee9..bbe9c7fceaa 100644 --- a/drivers/spi/spi_mcux_lpspi.c +++ b/drivers/spi/spi_mcux_lpspi.c @@ -81,7 +81,7 @@ static void spi_mcux_transfer_next_packet(const struct device *dev) if ((ctx->tx_len == 0) && (ctx->rx_len == 0)) { /* nothing left to rx or tx, we're done! */ spi_context_cs_control(&data->ctx, false); - spi_context_complete(&data->ctx, 0); + spi_context_complete(&data->ctx, dev, 0); return; } @@ -245,7 +245,8 @@ static void spi_mcux_dma_callback(const struct device *dev, void *arg, uint32_t channel, int status) { /* arg directly holds the spi device */ - struct spi_mcux_data *data = arg; + const struct device *spi_dev = arg; + struct spi_mcux_data *data = (struct spi_mcux_data *)spi_dev->data; if (status != 0) { LOG_ERR("DMA callback error with channel %d.", channel); @@ -266,7 +267,7 @@ static void spi_mcux_dma_callback(const struct device *dev, void *arg, data->status_flags |= SPI_MCUX_LPSPI_DMA_ERROR_FLAG; } } - spi_context_complete(&data->ctx, 0); + spi_context_complete(&data->ctx, spi_dev, 0); } static int spi_mcux_dma_tx_load(const struct device *dev, const uint8_t *buf, size_t len) @@ -305,7 +306,7 @@ static int spi_mcux_dma_tx_load(const struct device *dev, const uint8_t *buf, si stream->dma_cfg.head_block = &stream->dma_blk_cfg; /* give the client dev as arg, as the callback comes from the dma */ - stream->dma_cfg.user_data = data; + stream->dma_cfg.user_data = (struct device *)dev; /* pass our client origin to the dma: data->dma_tx.dma_channel */ return dma_config(data->dma_tx.dma_dev, data->dma_tx.channel, &stream->dma_cfg); @@ -346,7 +347,7 @@ static int spi_mcux_dma_rx_load(const struct device *dev, uint8_t *buf, stream->dma_cfg.source_burst_length = 1; stream->dma_cfg.head_block = blk_cfg; - stream->dma_cfg.user_data = data; + stream->dma_cfg.user_data = (struct device *)dev; /* pass our client origin to the dma: data->dma_rx.channel */ return dma_config(data->dma_rx.dma_dev, data->dma_rx.channel, @@ -381,7 +382,8 @@ static int transceive_dma(const struct device *dev, const struct spi_buf_set *tx_bufs, const struct spi_buf_set *rx_bufs, bool asynchronous, - struct k_poll_signal *sig) + spi_callback_t cb, + void *userdata) { const struct spi_mcux_config *config = dev->config; struct spi_mcux_data *data = dev->data; @@ -389,7 +391,7 @@ static int transceive_dma(const struct device *dev, int ret; size_t dma_size; - spi_context_lock(&data->ctx, asynchronous, sig, spi_cfg); + spi_context_lock(&data->ctx, asynchronous, cb, userdata, spi_cfg); ret = spi_mcux_configure(dev, spi_cfg); if (ret) { @@ -468,12 +470,13 @@ static int transceive(const struct device *dev, const struct spi_buf_set *tx_bufs, const struct spi_buf_set *rx_bufs, bool asynchronous, - struct k_poll_signal *signal) + spi_callback_t cb, + void *userdata) { struct spi_mcux_data *data = dev->data; int ret; - spi_context_lock(&data->ctx, asynchronous, signal, spi_cfg); + spi_context_lock(&data->ctx, asynchronous, cb, userdata, spi_cfg); ret = spi_mcux_configure(dev, spi_cfg); if (ret) { @@ -499,9 +502,9 @@ static int spi_mcux_transceive(const struct device *dev, const struct spi_buf_set *rx_bufs) { #ifdef CONFIG_SPI_MCUX_LPSPI_DMA - return transceive_dma(dev, spi_cfg, tx_bufs, rx_bufs, false, NULL); + return transceive_dma(dev, spi_cfg, tx_bufs, rx_bufs, false, NULL, NULL); #endif /* CONFIG_SPI_MCUX_LPSPI_DMA */ - return transceive(dev, spi_cfg, tx_bufs, rx_bufs, false, NULL); + return transceive(dev, spi_cfg, tx_bufs, rx_bufs, false, NULL, NULL); } #ifdef CONFIG_SPI_ASYNC @@ -509,9 +512,10 @@ static int spi_mcux_transceive_async(const struct device *dev, const struct spi_config *spi_cfg, const struct spi_buf_set *tx_bufs, const struct spi_buf_set *rx_bufs, - struct k_poll_signal *async) + spi_callback_t cb, + void *userdata) { - return transceive(dev, spi_cfg, tx_bufs, rx_bufs, true, async); + return transceive(dev, spi_cfg, tx_bufs, rx_bufs, true, cb, userdata); } #endif /* CONFIG_SPI_ASYNC */ diff --git a/drivers/spi/spi_npcx_fiu.c b/drivers/spi/spi_npcx_fiu.c index ec386d5b1ee..b085324b006 100644 --- a/drivers/spi/spi_npcx_fiu.c +++ b/drivers/spi/spi_npcx_fiu.c @@ -75,7 +75,7 @@ static int spi_npcx_fiu_transceive(const struct device *dev, size_t cur_xfer_len; int error = 0; - spi_context_lock(ctx, false, NULL, spi_cfg); + spi_context_lock(ctx, false, NULL, NULL, spi_cfg); ctx->config = spi_cfg; /* diff --git a/drivers/spi/spi_nrfx_spi.c b/drivers/spi/spi_nrfx_spi.c index 7f1263b8787..42b9802ece8 100644 --- a/drivers/spi/spi_nrfx_spi.c +++ b/drivers/spi/spi_nrfx_spi.c @@ -182,7 +182,7 @@ static void transfer_next_chunk(const struct device *dev) LOG_DBG("Transaction finished with status %d", error); - spi_context_complete(ctx, error); + spi_context_complete(ctx, dev, error); dev_data->busy = false; } @@ -203,12 +203,13 @@ static int transceive(const struct device *dev, const struct spi_buf_set *tx_bufs, const struct spi_buf_set *rx_bufs, bool asynchronous, - struct k_poll_signal *signal) + spi_callback_t cb, + void *userdata) { struct spi_nrfx_data *dev_data = dev->data; int error; - spi_context_lock(&dev_data->ctx, asynchronous, signal, spi_cfg); + spi_context_lock(&dev_data->ctx, asynchronous, cb, userdata, spi_cfg); error = configure(dev, spi_cfg); if (error == 0) { @@ -232,7 +233,7 @@ static int spi_nrfx_transceive(const struct device *dev, const struct spi_buf_set *tx_bufs, const struct spi_buf_set *rx_bufs) { - return transceive(dev, spi_cfg, tx_bufs, rx_bufs, false, NULL); + return transceive(dev, spi_cfg, tx_bufs, rx_bufs, false, NULL, NULL); } #ifdef CONFIG_SPI_ASYNC @@ -240,9 +241,10 @@ static int spi_nrfx_transceive_async(const struct device *dev, const struct spi_config *spi_cfg, const struct spi_buf_set *tx_bufs, const struct spi_buf_set *rx_bufs, - struct k_poll_signal *async) + spi_callback_t cb, + void *userdata) { - return transceive(dev, spi_cfg, tx_bufs, rx_bufs, true, async); + return transceive(dev, spi_cfg, tx_bufs, rx_bufs, true, cb, userdata); } #endif /* CONFIG_SPI_ASYNC */ diff --git a/drivers/spi/spi_nrfx_spim.c b/drivers/spi/spi_nrfx_spim.c index 11d8df9c854..ad0fa7d9e56 100644 --- a/drivers/spi/spi_nrfx_spim.c +++ b/drivers/spi/spi_nrfx_spim.c @@ -345,7 +345,7 @@ static void transfer_next_chunk(const struct device *dev) LOG_DBG("Transaction finished with status %d", error); - spi_context_complete(ctx, error); + spi_context_complete(ctx, dev, error); dev_data->busy = false; } @@ -369,12 +369,13 @@ static int transceive(const struct device *dev, const struct spi_buf_set *tx_bufs, const struct spi_buf_set *rx_bufs, bool asynchronous, - struct k_poll_signal *signal) + spi_callback_t cb, + void *userdata) { struct spi_nrfx_data *dev_data = dev->data; int error; - spi_context_lock(&dev_data->ctx, asynchronous, signal, spi_cfg); + spi_context_lock(&dev_data->ctx, asynchronous, cb, userdata, spi_cfg); error = configure(dev, spi_cfg); if (error == 0) { @@ -398,7 +399,7 @@ static int spi_nrfx_transceive(const struct device *dev, const struct spi_buf_set *tx_bufs, const struct spi_buf_set *rx_bufs) { - return transceive(dev, spi_cfg, tx_bufs, rx_bufs, false, NULL); + return transceive(dev, spi_cfg, tx_bufs, rx_bufs, false, NULL, NULL); } #ifdef CONFIG_SPI_ASYNC @@ -406,9 +407,10 @@ static int spi_nrfx_transceive_async(const struct device *dev, const struct spi_config *spi_cfg, const struct spi_buf_set *tx_bufs, const struct spi_buf_set *rx_bufs, - struct k_poll_signal *async) + spi_callback_t cb, + void *userdata) { - return transceive(dev, spi_cfg, tx_bufs, rx_bufs, true, async); + return transceive(dev, spi_cfg, tx_bufs, rx_bufs, true, cb, userdata); } #endif /* CONFIG_SPI_ASYNC */ diff --git a/drivers/spi/spi_nrfx_spis.c b/drivers/spi/spi_nrfx_spis.c index d739f20f31a..b7970c5c1de 100644 --- a/drivers/spi/spi_nrfx_spis.c +++ b/drivers/spi/spi_nrfx_spis.c @@ -137,7 +137,7 @@ static void prepare_for_transfer(const struct device *dev, status = -EIO; } - spi_context_complete(&dev_data->ctx, status); + spi_context_complete(&dev_data->ctx, dev, status); } @@ -146,12 +146,13 @@ static int transceive(const struct device *dev, const struct spi_buf_set *tx_bufs, const struct spi_buf_set *rx_bufs, bool asynchronous, - struct k_poll_signal *signal) + spi_callback_t cb, + void *userdata) { struct spi_nrfx_data *dev_data = dev->data; int error; - spi_context_lock(&dev_data->ctx, asynchronous, signal, spi_cfg); + spi_context_lock(&dev_data->ctx, asynchronous, cb, userdata, spi_cfg); error = configure(dev, spi_cfg); if (error != 0) { @@ -184,7 +185,7 @@ static int spi_nrfx_transceive(const struct device *dev, const struct spi_buf_set *tx_bufs, const struct spi_buf_set *rx_bufs) { - return transceive(dev, spi_cfg, tx_bufs, rx_bufs, false, NULL); + return transceive(dev, spi_cfg, tx_bufs, rx_bufs, false, NULL, NULL); } #ifdef CONFIG_SPI_ASYNC @@ -192,9 +193,10 @@ static int spi_nrfx_transceive_async(const struct device *dev, const struct spi_config *spi_cfg, const struct spi_buf_set *tx_bufs, const struct spi_buf_set *rx_bufs, - struct k_poll_signal *async) + spi_callback_t cb, + void *userdata) { - return transceive(dev, spi_cfg, tx_bufs, rx_bufs, true, async); + return transceive(dev, spi_cfg, tx_bufs, rx_bufs, true, cb, userdata); } #endif /* CONFIG_SPI_ASYNC */ @@ -223,9 +225,10 @@ static const struct spi_driver_api spi_nrfx_driver_api = { static void event_handler(const nrfx_spis_evt_t *p_event, void *p_context) { struct spi_nrfx_data *dev_data = p_context; + struct device *dev = CONTAINER_OF(dev_data, struct device, data); if (p_event->evt_type == NRFX_SPIS_XFER_DONE) { - spi_context_complete(&dev_data->ctx, p_event->rx_amount); + spi_context_complete(&dev_data->ctx, dev, p_event->rx_amount); } } diff --git a/drivers/spi/spi_oc_simple.c b/drivers/spi/spi_oc_simple.c index 4709ab537e2..4f813eb1867 100644 --- a/drivers/spi/spi_oc_simple.c +++ b/drivers/spi/spi_oc_simple.c @@ -104,7 +104,7 @@ int spi_oc_simple_transceive(const struct device *dev, int rc; /* Lock the SPI Context */ - spi_context_lock(ctx, false, NULL, config); + spi_context_lock(ctx, false, NULL, NULL, config); spi_oc_simple_configure(info, spi, config); @@ -153,7 +153,7 @@ int spi_oc_simple_transceive(const struct device *dev, sys_write8(0 << config->slave, SPI_OC_SIMPLE_SPSS(info)); } - spi_context_complete(ctx, 0); + spi_context_complete(ctx, dev, 0); rc = spi_context_wait_for_completion(ctx); spi_context_release(ctx, rc); diff --git a/drivers/spi/spi_pl022.c b/drivers/spi/spi_pl022.c index 0688b0b5cd6..c5e610f1cd9 100644 --- a/drivers/spi/spi_pl022.c +++ b/drivers/spi/spi_pl022.c @@ -401,7 +401,7 @@ static void spi_pl022_async_xfer(const struct device *dev) chunk_len = spi_context_max_continuous_chunk(ctx); } else { /* All data is processed, complete the process */ - spi_context_complete(ctx, 0); + spi_context_complete(ctx, dev, 0); return; } } @@ -452,7 +452,7 @@ static void spi_pl022_isr(const struct device *dev) if (mis & SSP_MIS_MASK_RORMIS) { SSP_WRITE_REG(SSP_IMSC(cfg->reg), 0); - spi_context_complete(ctx, -EIO); + spi_context_complete(ctx, dev, -EIO); } else { spi_pl022_async_xfer(dev); } @@ -511,13 +511,14 @@ static int spi_pl022_transceive_impl(const struct device *dev, const struct spi_config *config, const struct spi_buf_set *tx_bufs, const struct spi_buf_set *rx_bufs, - struct k_poll_signal *async) + spi_callback_t cb, + void *userdata) { struct spi_pl022_data *data = dev->data; struct spi_context *ctx = &data->ctx; int ret; - spi_context_lock(&data->ctx, (async ? true : false), async, config); + spi_context_lock(&data->ctx, (cb ? true : false), cb, userdata, config); ret = spi_pl022_configure(dev, config); if (ret < 0) { @@ -539,7 +540,7 @@ static int spi_pl022_transceive_impl(const struct device *dev, } while (spi_pl022_transfer_ongoing(data)); #ifdef CONFIG_SPI_ASYNC - spi_context_complete(&data->ctx, ret); + spi_context_complete(&data->ctx, dev, ret); #endif #endif @@ -558,7 +559,7 @@ static int spi_pl022_transceive(const struct device *dev, const struct spi_buf_set *tx_bufs, const struct spi_buf_set *rx_bufs) { - return spi_pl022_transceive_impl(dev, config, tx_bufs, rx_bufs, NULL); + return spi_pl022_transceive_impl(dev, config, tx_bufs, rx_bufs, NULL, NULL); } #if IS_ENABLED(CONFIG_SPI_ASYNC) @@ -567,9 +568,10 @@ static int spi_pl022_transceive_async(const struct device *dev, const struct spi_config *config, const struct spi_buf_set *tx_bufs, const struct spi_buf_set *rx_bufs, - struct k_poll_signal *async) + spi_callback_t cb, + void *userdata) { - return spi_pl022_transceive_impl(dev, config, tx_bufs, rx_bufs, async); + return spi_pl022_transceive_impl(dev, config, tx_bufs, rx_bufs, cb, userdata); } #endif diff --git a/drivers/spi/spi_psoc6.c b/drivers/spi/spi_psoc6.c index 57d2d69b4fc..287e6e9314f 100644 --- a/drivers/spi/spi_psoc6.c +++ b/drivers/spi/spi_psoc6.c @@ -62,7 +62,7 @@ static void spi_psoc6_transfer_next_packet(const struct device *dev) xfer->dataSize = 0U; spi_context_cs_control(ctx, false); - spi_context_complete(ctx, 0U); + spi_context_complete(ctx, dev, 0U); return; } @@ -124,7 +124,7 @@ err: xfer->dataSize = 0U; spi_context_cs_control(ctx, false); - spi_context_complete(ctx, -ENOMEM); + spi_context_complete(ctx, dev, -ENOMEM); } static void spi_psoc6_isr(const struct device *dev) @@ -296,13 +296,14 @@ static int spi_psoc6_transceive(const struct device *dev, const struct spi_buf_set *tx_bufs, const struct spi_buf_set *rx_bufs, bool asynchronous, - struct k_poll_signal *signal) + spi_callback_t cb, + void *userdata) { const struct spi_psoc6_config *config = dev->config; struct spi_psoc6_data *data = dev->data; int ret; - spi_context_lock(&data->ctx, asynchronous, signal, spi_cfg); + spi_context_lock(&data->ctx, asynchronous, cb, userdata, spi_cfg); LOG_DBG("\n\n"); diff --git a/drivers/spi/spi_rv32m1_lpspi.c b/drivers/spi/spi_rv32m1_lpspi.c index 78add297a60..b34a460fbfa 100644 --- a/drivers/spi/spi_rv32m1_lpspi.c +++ b/drivers/spi/spi_rv32m1_lpspi.c @@ -56,7 +56,7 @@ static void spi_mcux_transfer_next_packet(const struct device *dev) if ((ctx->tx_len == 0) && (ctx->rx_len == 0)) { /* nothing left to rx or tx, we're done! */ spi_context_cs_control(&data->ctx, false); - spi_context_complete(&data->ctx, 0); + spi_context_complete(&data->ctx, dev, 0); return; } @@ -214,12 +214,13 @@ static int transceive(const struct device *dev, const struct spi_buf_set *tx_bufs, const struct spi_buf_set *rx_bufs, bool asynchronous, - struct k_poll_signal *signal) + spi_callback_t cb, + void *userdata) { struct spi_mcux_data *data = dev->data; int ret; - spi_context_lock(&data->ctx, asynchronous, signal, spi_cfg); + spi_context_lock(&data->ctx, asynchronous, cb, userdata, spi_cfg); ret = spi_mcux_configure(dev, spi_cfg); if (ret) { @@ -244,7 +245,7 @@ static int spi_mcux_transceive(const struct device *dev, const struct spi_buf_set *tx_bufs, const struct spi_buf_set *rx_bufs) { - return transceive(dev, spi_cfg, tx_bufs, rx_bufs, false, NULL); + return transceive(dev, spi_cfg, tx_bufs, rx_bufs, false, NULL, NULL); } #ifdef CONFIG_SPI_ASYNC @@ -252,9 +253,10 @@ static int spi_mcux_transceive_async(const struct device *dev, const struct spi_config *spi_cfg, const struct spi_buf_set *tx_bufs, const struct spi_buf_set *rx_bufs, - struct k_poll_signal *async) + spi_callback_t cb, + void *userdata) { - return transceive(dev, spi_cfg, tx_bufs, rx_bufs, true, async); + return transceive(dev, spi_cfg, tx_bufs, rx_bufs, true, cb, userdata); } #endif /* CONFIG_SPI_ASYNC */ diff --git a/drivers/spi/spi_sam.c b/drivers/spi/spi_sam.c index 161ce2d5d46..35b7c00ec0b 100644 --- a/drivers/spi/spi_sam.c +++ b/drivers/spi/spi_sam.c @@ -370,7 +370,7 @@ static int spi_sam_transceive(const struct device *dev, Spi *regs = cfg->regs; int err; - spi_context_lock(&data->ctx, false, NULL, config); + spi_context_lock(&data->ctx, false, NULL, NULL, config); err = spi_sam_configure(dev, config); if (err != 0) { @@ -414,9 +414,10 @@ static int spi_sam_transceive_async(const struct device *dev, const struct spi_config *config, const struct spi_buf_set *tx_bufs, const struct spi_buf_set *rx_bufs, - struct k_poll_signal *async) + spi_callback_t cb, + void *userdata) { - /* TODO: implement asyc transceive */ + /* TODO: implement async transceive */ return -ENOTSUP; } #endif /* CONFIG_SPI_ASYNC */ diff --git a/drivers/spi/spi_sam0.c b/drivers/spi/spi_sam0.c index c6528e7061c..4a3188272cf 100644 --- a/drivers/spi/spi_sam0.c +++ b/drivers/spi/spi_sam0.c @@ -358,7 +358,7 @@ static int spi_sam0_transceive(const struct device *dev, SercomSpi *regs = cfg->regs; int err; - spi_context_lock(&data->ctx, false, NULL, config); + spi_context_lock(&data->ctx, false, NULL, NULL, config); err = spi_sam0_configure(dev, config); if (err != 0) { @@ -562,7 +562,7 @@ static void spi_sam0_dma_rx_done(const struct device *dma_dev, void *arg, if (!spi_sam0_dma_advance_segment(dev)) { /* Done */ spi_context_cs_control(&data->ctx, false); - spi_context_complete(&data->ctx, 0); + spi_context_complete(&data->ctx, dev, 0); return; } @@ -571,7 +571,7 @@ static void spi_sam0_dma_rx_done(const struct device *dma_dev, void *arg, dma_stop(cfg->dma_dev, cfg->tx_dma_channel); dma_stop(cfg->dma_dev, cfg->rx_dma_channel); spi_context_cs_control(&data->ctx, false); - spi_context_complete(&data->ctx, retval); + spi_context_complete(&data->ctx, dev, retval); return; } } @@ -581,7 +581,8 @@ static int spi_sam0_transceive_async(const struct device *dev, const struct spi_config *config, const struct spi_buf_set *tx_bufs, const struct spi_buf_set *rx_bufs, - struct k_poll_signal *async) + spi_callback_t cb, + void *userdata) { const struct spi_sam0_config *cfg = dev->config; struct spi_sam0_data *data = dev->data; @@ -595,7 +596,7 @@ static int spi_sam0_transceive_async(const struct device *dev, return -ENOTSUP; } - spi_context_lock(&data->ctx, true, async, config); + spi_context_lock(&data->ctx, true, cb, userdata, config); retval = spi_sam0_configure(dev, config); if (retval != 0) { diff --git a/drivers/spi/spi_signal.c b/drivers/spi/spi_signal.c new file mode 100644 index 00000000000..09553ce3dfd --- /dev/null +++ b/drivers/spi/spi_signal.c @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2022 Intel Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * @file + * @brief Async callback used with signal notifier + */ + +#include +#include + +#ifdef CONFIG_POLL + +void z_spi_transfer_signal_cb(const struct device *dev, + int result, + void *userdata) +{ + ARG_UNUSED(dev); + + struct k_poll_signal *sig = userdata; + + k_poll_signal_raise(sig, result); +} + +#endif /* CONFIG_POLL */ diff --git a/drivers/spi/spi_test.c b/drivers/spi/spi_test.c index 80bd5bfc669..cb98157b427 100644 --- a/drivers/spi/spi_test.c +++ b/drivers/spi/spi_test.c @@ -27,7 +27,8 @@ static int vnd_spi_transceive_async(const struct device *dev, const struct spi_config *spi_cfg, const struct spi_buf_set *tx_bufs, const struct spi_buf_set *rx_bufs, - struct k_poll_signal *async) + spi_callback_t cb, + void *userdata) { return -ENOTSUP; } diff --git a/drivers/spi/spi_xec_qmspi.c b/drivers/spi/spi_xec_qmspi.c index 9fa5ff40626..14e8b4f904c 100644 --- a/drivers/spi/spi_xec_qmspi.c +++ b/drivers/spi/spi_xec_qmspi.c @@ -522,7 +522,7 @@ static int qmspi_transceive(const struct device *dev, uint32_t descr, last_didx; int err; - spi_context_lock(&data->ctx, false, NULL, config); + spi_context_lock(&data->ctx, false, NULL, NULL, config); err = qmspi_configure(dev, config); if (err != 0) { diff --git a/drivers/spi/spi_xec_qmspi_ldma.c b/drivers/spi/spi_xec_qmspi_ldma.c index 80920835cdc..d17e9dde53d 100644 --- a/drivers/spi/spi_xec_qmspi_ldma.c +++ b/drivers/spi/spi_xec_qmspi_ldma.c @@ -672,7 +672,7 @@ static int qmspi_transceive(const struct device *dev, size_t nb = 0; int err = 0; - spi_context_lock(&qdata->ctx, false, NULL, config); + spi_context_lock(&qdata->ctx, false, NULL, NULL, config); err = qmspi_configure(dev, config); if (err != 0) { @@ -942,11 +942,12 @@ static int qmspi_transceive_async(const struct device *dev, const struct spi_config *config, const struct spi_buf_set *tx_bufs, const struct spi_buf_set *rx_bufs, - struct k_poll_signal *async) + spi_callback_t cb, + void *userdata) { struct spi_qmspi_data *data = dev->data; - spi_context_lock(&data->ctx, true, async, config); + spi_context_lock(&data->ctx, true, cb, userdata, config); int ret = qmspi_configure(dev, config); @@ -1021,7 +1022,7 @@ void qmspi_xec_isr(const struct device *dev) data->qstatus |= BIT(7); xstatus = (int)qstatus; spi_context_cs_control(&data->ctx, false); - spi_context_complete(&data->ctx, xstatus); + spi_context_complete(&data->ctx, dev, xstatus); } if (data->xfr_flags & BIT(0)) { /* is TX ? */ @@ -1066,7 +1067,7 @@ void qmspi_xec_isr(const struct device *dev) spi_context_cs_control(&data->ctx, false); } - spi_context_complete(&data->ctx, xstatus); + spi_context_complete(&data->ctx, dev, xstatus); data->in_isr = 0; #endif diff --git a/drivers/spi/spi_xlnx_axi_quadspi.c b/drivers/spi/spi_xlnx_axi_quadspi.c index ca126d90da2..edb8e763c03 100644 --- a/drivers/spi/spi_xlnx_axi_quadspi.c +++ b/drivers/spi/spi_xlnx_axi_quadspi.c @@ -243,7 +243,7 @@ static void xlnx_quadspi_start_tx(const struct device *dev) xlnx_quadspi_write32(dev, spicr, SPICR_OFFSET); } - spi_context_complete(ctx, 0); + spi_context_complete(ctx, dev, 0); return; } @@ -301,7 +301,7 @@ static void xlnx_quadspi_start_tx(const struct device *dev) xlnx_quadspi_write32(dev, spicr | SPICR_TX_FIFO_RESET, SPICR_OFFSET); - spi_context_complete(ctx, -ENOTSUP); + spi_context_complete(ctx, dev, -ENOTSUP); } if (!IS_ENABLED(CONFIG_SPI_SLAVE) || !spi_context_is_slave(ctx)) { @@ -315,14 +315,16 @@ static int xlnx_quadspi_transceive(const struct device *dev, const struct spi_config *spi_cfg, const struct spi_buf_set *tx_bufs, const struct spi_buf_set *rx_bufs, - bool async, struct k_poll_signal *signal) + bool async, + spi_callback_t cb, + void *userdata) { const struct xlnx_quadspi_config *config = dev->config; struct xlnx_quadspi_data *data = dev->data; struct spi_context *ctx = &data->ctx; int ret; - spi_context_lock(ctx, async, signal, spi_cfg); + spi_context_lock(ctx, async, cb, userdata, spi_cfg); ret = xlnx_quadspi_configure(dev, spi_cfg); if (ret) { @@ -349,7 +351,7 @@ static int xlnx_quadspi_transceive_blocking(const struct device *dev, const struct spi_buf_set *rx_bufs) { return xlnx_quadspi_transceive(dev, spi_cfg, tx_bufs, rx_bufs, false, - NULL); + NULL, NULL); } #ifdef CONFIG_SPI_ASYNC @@ -357,10 +359,11 @@ static int xlnx_quadspi_transceive_async(const struct device *dev, const struct spi_config *spi_cfg, const struct spi_buf_set *tx_bufs, const struct spi_buf_set *rx_bufs, - struct k_poll_signal *signal) + spi_callback_t cb, + void *userdata) { return xlnx_quadspi_transceive(dev, spi_cfg, tx_bufs, rx_bufs, true, - signal); + cb, userdata); } #endif /* CONFIG_SPI_ASYNC */ diff --git a/include/zephyr/drivers/spi.h b/include/zephyr/drivers/spi.h index acac793bd79..6ed40052aaa 100644 --- a/include/zephyr/drivers/spi.h +++ b/include/zephyr/drivers/spi.h @@ -457,6 +457,15 @@ typedef int (*spi_api_io)(const struct device *dev, const struct spi_buf_set *tx_bufs, const struct spi_buf_set *rx_bufs); +/** + * @brief SPI callback for asynchronous transfer requests + * + * @param dev SPI device which is notifying of transfer completion or error + * @param result Result code of the transfer request. 0 is success, -errno for failure. + * @param data Transfer requester supplied data which is passed along to the callback. + */ +typedef void (*spi_callback_t)(const struct device *dev, int result, void *data); + /** * @typedef spi_api_io * @brief Callback API for asynchronous I/O @@ -466,7 +475,8 @@ typedef int (*spi_api_io_async)(const struct device *dev, const struct spi_config *config, const struct spi_buf_set *tx_bufs, const struct spi_buf_set *rx_bufs, - struct k_poll_signal *async); + spi_callback_t cb, + void *userdata); /** * @typedef spi_api_release @@ -668,7 +678,52 @@ static inline int spi_write_dt(const struct spi_dt_spec *spec, * or NULL if none. * @param rx_bufs Buffer array where data to be read will be written to, * or NULL if none. - * @param async A pointer to a valid and ready to be signaled + * @param callback Function pointer to completion callback. + * (Note: if NULL this function will not + * notify the end of the transaction, and whether it went + * successfully or not). + * @param userdata Userdata passed to callback + * + * @retval frames Positive number of frames received in slave mode. + * @retval 0 If successful in master mode. + * @retval -errno Negative errno code on failure. + */ +static inline int spi_transceive_cb(const struct device *dev, + const struct spi_config *config, + const struct spi_buf_set *tx_bufs, + const struct spi_buf_set *rx_bufs, + spi_callback_t callback, + void *userdata) +{ + const struct spi_driver_api *api = + (const struct spi_driver_api *)dev->api; + + return api->transceive_async(dev, config, tx_bufs, rx_bufs, callback, userdata); +} + +#ifdef CONFIG_POLL + +/** @cond INTERNAL_HIDDEN */ +void z_spi_transfer_signal_cb(const struct device *dev, int result, void *userdata); +/** @endcond */ + +/** + * @brief Read/write the specified amount of data from the SPI driver. + * + * @note This function is asynchronous. + * + * @note This function is available only if @kconfig{CONFIG_SPI_ASYNC} + * and @kconfig{CONFIG_POLL} are selected. + * + * @param dev Pointer to the device structure for the driver instance + * @param config Pointer to a valid spi_config structure instance. + * Pointer-comparison may be used to detect changes from + * previous operations. + * @param tx_bufs Buffer array where data to be sent originates from, + * or NULL if none. + * @param rx_bufs Buffer array where data to be read will be written to, + * or NULL if none. + * @param sig A pointer to a valid and ready to be signaled * struct k_poll_signal. (Note: if NULL this function will not * notify the end of the transaction, and whether it went * successfully or not). @@ -677,16 +732,32 @@ static inline int spi_write_dt(const struct spi_dt_spec *spec, * @retval 0 If successful in master mode. * @retval -errno Negative errno code on failure. */ -static inline int spi_transceive_async(const struct device *dev, +static inline int spi_transceive_signal(const struct device *dev, const struct spi_config *config, const struct spi_buf_set *tx_bufs, const struct spi_buf_set *rx_bufs, - struct k_poll_signal *async) + struct k_poll_signal *sig) { const struct spi_driver_api *api = (const struct spi_driver_api *)dev->api; + spi_callback_t cb = (sig == NULL) ? NULL : z_spi_transfer_signal_cb; + + return api->transceive_async(dev, config, tx_bufs, rx_bufs, cb, sig); +} - return api->transceive_async(dev, config, tx_bufs, rx_bufs, async); +/** + * @brief Alias for spi_transceive_signal for backwards compatibility + * + * @deprecated + * @see spi_transceive_signal + */ +__deprecated static inline int spi_transceive_async(const struct device *dev, + const struct spi_config *config, + const struct spi_buf_set *tx_bufs, + const struct spi_buf_set *rx_bufs, + struct k_poll_signal *sig) +{ + return spi_transceive_signal(dev, config, tx_bufs, rx_bufs, sig); } /** @@ -694,17 +765,17 @@ static inline int spi_transceive_async(const struct device *dev, * * @note This function is asynchronous. * - * @note This function is an helper function calling spi_transceive_async. + * @note This function is an helper function calling spi_transceive_signal. * * @note This function is available only if @kconfig{CONFIG_SPI_ASYNC} - * is selected. + * and @kconfig{CONFIG_POLL} are selected. * * @param dev Pointer to the device structure for the driver instance * @param config Pointer to a valid spi_config structure instance. * Pointer-comparison may be used to detect changes from * previous operations. * @param rx_bufs Buffer array where data to be read will be written to. - * @param async A pointer to a valid and ready to be signaled + * @param sig A pointer to a valid and ready to be signaled * struct k_poll_signal. (Note: if NULL this function will not * notify the end of the transaction, and whether it went * successfully or not). @@ -712,12 +783,26 @@ static inline int spi_transceive_async(const struct device *dev, * @retval 0 If successful * @retval -errno Negative errno code on failure. */ -static inline int spi_read_async(const struct device *dev, +static inline int spi_read_signal(const struct device *dev, + const struct spi_config *config, + const struct spi_buf_set *rx_bufs, + struct k_poll_signal *sig) +{ + return spi_transceive_signal(dev, config, NULL, rx_bufs, sig); +} + +/** + * @brief Alias for spi_read_signal for backwards compatibility + * + * @deprecated + * @see spi_read_signal + */ +__deprecated static inline int spi_read_async(const struct device *dev, const struct spi_config *config, const struct spi_buf_set *rx_bufs, - struct k_poll_signal *async) + struct k_poll_signal *sig) { - return spi_transceive_async(dev, config, NULL, rx_bufs, async); + return spi_read_signal(dev, config, rx_bufs, sig); } /** @@ -728,14 +813,14 @@ static inline int spi_read_async(const struct device *dev, * @note This function is an helper function calling spi_transceive_async. * * @note This function is available only if @kconfig{CONFIG_SPI_ASYNC} - * is selected. + * and @kconfig{CONFIG_POLL} are selected. * * @param dev Pointer to the device structure for the driver instance * @param config Pointer to a valid spi_config structure instance. * Pointer-comparison may be used to detect changes from * previous operations. * @param tx_bufs Buffer array where data to be sent originates from. - * @param async A pointer to a valid and ready to be signaled + * @param sig A pointer to a valid and ready to be signaled * struct k_poll_signal. (Note: if NULL this function will not * notify the end of the transaction, and whether it went * successfully or not). @@ -743,13 +828,30 @@ static inline int spi_read_async(const struct device *dev, * @retval 0 If successful. * @retval -errno Negative errno code on failure. */ -static inline int spi_write_async(const struct device *dev, +static inline int spi_write_signal(const struct device *dev, const struct spi_config *config, const struct spi_buf_set *tx_bufs, - struct k_poll_signal *async) + struct k_poll_signal *sig) +{ + return spi_transceive_signal(dev, config, tx_bufs, NULL, sig); +} + +/** + * @brief Alias for spi_read_signal for backwards compatibility + * + * @deprecated + * @see spi_read_signal + */ +__deprecated static inline int spi_write_async(const struct device *dev, + const struct spi_config *config, + const struct spi_buf_set *tx_bufs, + struct k_poll_signal *sig) { - return spi_transceive_async(dev, config, tx_bufs, NULL, async); + return spi_write_signal(dev, config, tx_bufs, sig); } + +#endif /* CONFIG_POLL */ + #endif /* CONFIG_SPI_ASYNC */ /** diff --git a/tests/drivers/spi/spi_loopback/src/spi.c b/tests/drivers/spi/spi_loopback/src/spi.c index a769e8dd417..5456227e17a 100644 --- a/tests/drivers/spi/spi_loopback/src/spi.c +++ b/tests/drivers/spi/spi_loopback/src/spi.c @@ -480,7 +480,7 @@ static int spi_async_call(struct spi_dt_spec *spec) LOG_INF("Start async call"); - ret = spi_transceive_async(spec->bus, &spec->config, &tx, &rx, &async_sig); + ret = spi_transceive_signal(spec->bus, &spec->config, &tx, &rx, &async_sig); if (ret == -ENOTSUP) { LOG_DBG("Not supported"); return 0;