1 /* 2 * Copyright (c) 2024 Croxel, Inc. 3 * 4 * SPDX-License-Identifier: Apache-2.0 5 */ 6 7 #ifndef ZEPHYR_DRIVERS_SPI_RTIO_H_ 8 #define ZEPHYR_DRIVERS_SPI_RTIO_H_ 9 10 #include <zephyr/kernel.h> 11 #include <zephyr/drivers/spi.h> 12 #include <zephyr/rtio/rtio.h> 13 14 #ifdef __cplusplus 15 extern "C" { 16 #endif 17 18 /** 19 * @brief Driver context for implementing SPI with RTIO 20 */ 21 struct spi_rtio { 22 struct k_spinlock lock; 23 struct rtio *r; 24 struct mpsc io_q; 25 struct rtio_iodev iodev; 26 struct rtio_iodev_sqe *txn_head; 27 struct rtio_iodev_sqe *txn_curr; 28 struct spi_dt_spec dt_spec; 29 }; 30 31 /** 32 * @brief Statically define a spi_rtio context 33 * 34 * @param _name Symbolic name of the context 35 * @param _sq_sz Submission queue entry pool size 36 * @param _cq_sz Completion queue entry pool size 37 */ 38 #define SPI_RTIO_DEFINE(_name, _sq_sz, _cq_sz) \ 39 RTIO_DEFINE(CONCAT(_name, _r), _sq_sz, _cq_sz); \ 40 static struct spi_rtio _name = { \ 41 .r = &CONCAT(_name, _r), \ 42 }; 43 44 /** 45 * @brief Copy the tx_bufs and rx_bufs into a set of RTIO requests 46 * 47 * @param[in] r rtio context 48 * @param[in] iodev iodev to transceive with 49 * @param[in] tx_bufs transmit buffer set 50 * @param[in] rx_bufs receive buffer set 51 * @param[out] last_sqe last sqe submitted, NULL if not enough memory 52 * 53 * @retval Number of submission queue entries 54 * @retval -ENOMEM out of memory 55 */ 56 int spi_rtio_copy(struct rtio *r, 57 struct rtio_iodev *iodev, 58 const struct spi_buf_set *tx_bufs, 59 const struct spi_buf_set *rx_bufs, 60 struct rtio_sqe **last_sqe); 61 62 /** 63 * @brief Initialize a SPI RTIO context 64 * 65 * @param ctx SPI RTIO driver context 66 * @param dev SPI bus 67 */ 68 void spi_rtio_init(struct spi_rtio *ctx, const struct device *dev); 69 70 /** 71 * @brief Signal that the current (ctx->txn_curr) submission has been completed 72 * 73 * @param ctx SPI RTIO driver context 74 * @param status Completion status, negative values are errors 75 * 76 * @retval true Next submission is ready to start 77 * @retval false No more submissions to work on 78 */ 79 bool spi_rtio_complete(struct spi_rtio *ctx, int status); 80 81 /** 82 * @brief Submit, atomically, a submission to work on at some point 83 * 84 * @retval true Next submission is ready to start 85 * @retval false No new submission to start or submissions are in progress already 86 */ 87 bool spi_rtio_submit(struct spi_rtio *ctx, struct rtio_iodev_sqe *iodev_sqe); 88 89 /** 90 * @brief Perform a SPI Transfer (transceive) in a blocking call 91 * 92 * Provides a compatible API for the existing spi_transceive API by blocking 93 * the caller until the operation is complete. 94 * For details see @ref spi_transceive. 95 */ 96 int spi_rtio_transceive(struct spi_rtio *ctx, 97 const struct spi_config *config, 98 const struct spi_buf_set *tx_bufs, 99 const struct spi_buf_set *rx_bufs); 100 101 /** 102 * @brief Fallback SPI RTIO submit implementation. 103 * 104 * Default RTIO SPI implementation for drivers who do no yet have 105 * native support. For details, see @ref spi_iodev_submit. 106 */ 107 void spi_rtio_iodev_default_submit(const struct device *dev, 108 struct rtio_iodev_sqe *iodev_sqe); 109 110 #ifdef __cplusplus 111 } 112 #endif 113 114 #endif /* ZEPHYR_DRIVERS_SPI_RTIO_H_ */ 115