Browse Source

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 <thomas.burdick@intel.com>
pull/48125/head
Tom Burdick 3 years ago committed by Anas Nashif
parent
commit
4c20403629
  1. 1
      drivers/spi/CMakeLists.txt
  2. 10
      drivers/spi/spi_b91.c
  3. 2
      drivers/spi/spi_bitbang.c
  4. 2
      drivers/spi/spi_cc13xx_cc26xx.c
  5. 17
      drivers/spi/spi_context.h
  6. 16
      drivers/spi/spi_dw.c
  7. 21
      drivers/spi/spi_esp32_spim.c
  8. 23
      drivers/spi/spi_ll_stm32.c
  9. 14
      drivers/spi/spi_mcux_dspi.c
  10. 30
      drivers/spi/spi_mcux_flexcomm.c
  11. 30
      drivers/spi/spi_mcux_lpspi.c
  12. 2
      drivers/spi/spi_npcx_fiu.c
  13. 14
      drivers/spi/spi_nrfx_spi.c
  14. 14
      drivers/spi/spi_nrfx_spim.c
  15. 17
      drivers/spi/spi_nrfx_spis.c
  16. 4
      drivers/spi/spi_oc_simple.c
  17. 18
      drivers/spi/spi_pl022.c
  18. 9
      drivers/spi/spi_psoc6.c
  19. 14
      drivers/spi/spi_rv32m1_lpspi.c
  20. 7
      drivers/spi/spi_sam.c
  21. 11
      drivers/spi/spi_sam0.c
  22. 28
      drivers/spi/spi_signal.c
  23. 3
      drivers/spi/spi_test.c
  24. 2
      drivers/spi/spi_xec_qmspi.c
  25. 11
      drivers/spi/spi_xec_qmspi_ldma.c
  26. 17
      drivers/spi/spi_xlnx_axi_quadspi.c
  27. 134
      include/zephyr/drivers/spi.h
  28. 2
      tests/drivers/spi/spi_loopback/src/spi.c

1
drivers/spi/CMakeLists.txt

@ -32,4 +32,5 @@ zephyr_library_sources_ifdef(CONFIG_SPI_GD32 spi_gd32.c) @@ -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)

10
drivers/spi/spi_b91.c

@ -233,7 +233,7 @@ static void spi_b91_txrx(const struct device *dev, uint32_t len) @@ -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, @@ -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, @@ -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;
}

2
drivers/spi/spi_bitbang.c

@ -221,7 +221,7 @@ static int spi_bitbang_transceive(const struct device *dev, @@ -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;
}

2
drivers/spi/spi_cc13xx_cc26xx.c

@ -140,7 +140,7 @@ static int spi_cc13xx_cc26xx_transceive(const struct device *dev, @@ -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);

17
drivers/spi/spi_context.h

@ -35,7 +35,8 @@ struct spi_context { @@ -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) @@ -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, @@ -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) @@ -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) @@ -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)) {

16
drivers/spi/spi_dw.c

@ -81,7 +81,7 @@ out: @@ -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, @@ -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, @@ -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, @@ -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, @@ -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 */

21
drivers/spi/spi_esp32_spim.c

@ -35,7 +35,8 @@ static bool spi_esp32_transfer_ongoing(struct spi_esp32_data *data) @@ -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, @@ -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) @@ -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, @@ -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, @@ -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, @@ -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, @@ -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, @@ -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 */

23
drivers/spi/spi_ll_stm32.c

@ -413,7 +413,7 @@ static void spi_stm32_complete(const struct device *dev, int status) @@ -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, @@ -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, @@ -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, @@ -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, @@ -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, @@ -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, @@ -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 */

14
drivers/spi/spi_mcux_dspi.c

@ -95,7 +95,7 @@ static int spi_mcux_transfer_next_packet(const struct device *dev) @@ -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, @@ -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, @@ -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, @@ -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, @@ -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 */

30
drivers/spi/spi_mcux_flexcomm.c

@ -85,7 +85,7 @@ static void spi_mcux_transfer_next_packet(const struct device *dev) @@ -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, @@ -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, @@ -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, @@ -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, @@ -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, @@ -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, @@ -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, @@ -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, @@ -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, @@ -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 */

30
drivers/spi/spi_mcux_lpspi.c

@ -81,7 +81,7 @@ static void spi_mcux_transfer_next_packet(const struct device *dev) @@ -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, @@ -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, @@ -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 @@ -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, @@ -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, @@ -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, @@ -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, @@ -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, @@ -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, @@ -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 */

2
drivers/spi/spi_npcx_fiu.c

@ -75,7 +75,7 @@ static int spi_npcx_fiu_transceive(const struct device *dev, @@ -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;
/*

14
drivers/spi/spi_nrfx_spi.c

@ -182,7 +182,7 @@ static void transfer_next_chunk(const struct device *dev) @@ -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, @@ -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, @@ -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, @@ -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 */

14
drivers/spi/spi_nrfx_spim.c

@ -345,7 +345,7 @@ static void transfer_next_chunk(const struct device *dev) @@ -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, @@ -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, @@ -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, @@ -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 */

17
drivers/spi/spi_nrfx_spis.c

@ -137,7 +137,7 @@ static void prepare_for_transfer(const struct device *dev, @@ -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, @@ -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, @@ -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, @@ -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 = { @@ -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);
}
}

4
drivers/spi/spi_oc_simple.c

@ -104,7 +104,7 @@ int spi_oc_simple_transceive(const struct device *dev, @@ -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, @@ -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);

18
drivers/spi/spi_pl022.c

@ -401,7 +401,7 @@ static void spi_pl022_async_xfer(const struct device *dev) @@ -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) @@ -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, @@ -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, @@ -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, @@ -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, @@ -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

9
drivers/spi/spi_psoc6.c

@ -62,7 +62,7 @@ static void spi_psoc6_transfer_next_packet(const struct device *dev) @@ -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: @@ -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, @@ -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");

14
drivers/spi/spi_rv32m1_lpspi.c

@ -56,7 +56,7 @@ static void spi_mcux_transfer_next_packet(const struct device *dev) @@ -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, @@ -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, @@ -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, @@ -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 */

7
drivers/spi/spi_sam.c

@ -370,7 +370,7 @@ static int spi_sam_transceive(const struct device *dev, @@ -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, @@ -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 */

11
drivers/spi/spi_sam0.c

@ -358,7 +358,7 @@ static int spi_sam0_transceive(const struct device *dev, @@ -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, @@ -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, @@ -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, @@ -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, @@ -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) {

28
drivers/spi/spi_signal.c

@ -0,0 +1,28 @@ @@ -0,0 +1,28 @@
/*
* Copyright (c) 2022 Intel Corporation
*
* SPDX-License-Identifier: Apache-2.0
*/
/**
* @file
* @brief Async callback used with signal notifier
*/
#include <zephyr/zephyr.h>
#include <zephyr/device.h>
#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 */

3
drivers/spi/spi_test.c

@ -27,7 +27,8 @@ static int vnd_spi_transceive_async(const struct device *dev, @@ -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;
}

2
drivers/spi/spi_xec_qmspi.c

@ -522,7 +522,7 @@ static int qmspi_transceive(const struct device *dev, @@ -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) {

11
drivers/spi/spi_xec_qmspi_ldma.c

@ -672,7 +672,7 @@ static int qmspi_transceive(const struct device *dev, @@ -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, @@ -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) @@ -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) @@ -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

17
drivers/spi/spi_xlnx_axi_quadspi.c

@ -243,7 +243,7 @@ static void xlnx_quadspi_start_tx(const struct device *dev) @@ -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) @@ -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, @@ -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, @@ -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, @@ -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 */

134
include/zephyr/drivers/spi.h

@ -457,6 +457,15 @@ typedef int (*spi_api_io)(const struct device *dev, @@ -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, @@ -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, @@ -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, @@ -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, @@ -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, @@ -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, @@ -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, @@ -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 */
/**

2
tests/drivers/spi/spi_loopback/src/spi.c

@ -480,7 +480,7 @@ static int spi_async_call(struct spi_dt_spec *spec) @@ -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;

Loading…
Cancel
Save