From 00abc5a66133f311e9f71ccd5318e2dac61d42d1 Mon Sep 17 00:00:00 2001 From: Luis Ubieda Date: Sat, 17 Aug 2024 08:36:52 -0400 Subject: [PATCH] spi: rtio: Move spi_rtio_copy to spi_rtio To group all common APIs for SPI RTIO. Signed-off-by: Luis Ubieda --- drivers/spi/spi_rtio.c | 158 ++++++++++++++++++++++++++++++ drivers/spi/spi_sam.c | 1 + include/zephyr/drivers/spi.h | 158 ------------------------------ include/zephyr/drivers/spi/rtio.h | 18 ++++ 4 files changed, 177 insertions(+), 158 deletions(-) diff --git a/drivers/spi/spi_rtio.c b/drivers/spi/spi_rtio.c index 2852eb9df6e09c..c514b5acad63e2 100644 --- a/drivers/spi/spi_rtio.c +++ b/drivers/spi/spi_rtio.c @@ -109,6 +109,164 @@ void spi_rtio_iodev_default_submit(const struct device *dev, rtio_work_req_submit(req, iodev_sqe, spi_rtio_iodev_default_submit_sync); } +/** + * @brief Copy the tx_bufs and rx_bufs into a set of RTIO requests + * + * @param[in] r rtio context + * @param[in] iodev iodev to transceive with + * @param[in] tx_bufs transmit buffer set + * @param[in] rx_bufs receive buffer set + * @param[out] last_sqe last sqe submitted, NULL if not enough memory + * + * @retval Number of submission queue entries + * @retval -ENOMEM out of memory + */ +int spi_rtio_copy(struct rtio *r, + struct rtio_iodev *iodev, + const struct spi_buf_set *tx_bufs, + const struct spi_buf_set *rx_bufs, + struct rtio_sqe **last_sqe) +{ + int ret = 0; + size_t tx_count = tx_bufs ? tx_bufs->count : 0; + size_t rx_count = rx_bufs ? rx_bufs->count : 0; + + uint32_t tx = 0, tx_len = 0; + uint32_t rx = 0, rx_len = 0; + uint8_t *tx_buf, *rx_buf; + + struct rtio_sqe *sqe = NULL; + + if (tx < tx_count) { + tx_buf = tx_bufs->buffers[tx].buf; + tx_len = tx_bufs->buffers[tx].len; + } else { + tx_buf = NULL; + tx_len = rx_bufs->buffers[rx].len; + } + + if (rx < rx_count) { + rx_buf = rx_bufs->buffers[rx].buf; + rx_len = rx_bufs->buffers[rx].len; + } else { + rx_buf = NULL; + rx_len = tx_bufs->buffers[tx].len; + } + + + while ((tx < tx_count || rx < rx_count) && (tx_len > 0 || rx_len > 0)) { + sqe = rtio_sqe_acquire(r); + + if (sqe == NULL) { + ret = -ENOMEM; + rtio_sqe_drop_all(r); + goto out; + } + + ret++; + + /* If tx/rx len are same, we can do a simple transceive */ + if (tx_len == rx_len) { + if (tx_buf == NULL) { + rtio_sqe_prep_read(sqe, iodev, RTIO_PRIO_NORM, + rx_buf, rx_len, NULL); + } else if (rx_buf == NULL) { + rtio_sqe_prep_write(sqe, iodev, RTIO_PRIO_NORM, + tx_buf, tx_len, NULL); + } else { + rtio_sqe_prep_transceive(sqe, iodev, RTIO_PRIO_NORM, + tx_buf, rx_buf, rx_len, NULL); + } + tx++; + rx++; + if (rx < rx_count) { + rx_buf = rx_bufs->buffers[rx].buf; + rx_len = rx_bufs->buffers[rx].len; + } else { + rx_buf = NULL; + rx_len = 0; + } + if (tx < tx_count) { + tx_buf = tx_bufs->buffers[tx].buf; + tx_len = tx_bufs->buffers[tx].len; + } else { + tx_buf = NULL; + tx_len = 0; + } + } else if (tx_len == 0) { + rtio_sqe_prep_read(sqe, iodev, RTIO_PRIO_NORM, + (uint8_t *)rx_buf, + (uint32_t)rx_len, + NULL); + rx++; + if (rx < rx_count) { + rx_buf = rx_bufs->buffers[rx].buf; + rx_len = rx_bufs->buffers[rx].len; + } else { + rx_buf = NULL; + rx_len = 0; + } + } else if (rx_len == 0) { + rtio_sqe_prep_write(sqe, iodev, RTIO_PRIO_NORM, + (uint8_t *)tx_buf, + (uint32_t)tx_len, + NULL); + tx++; + if (tx < tx_count) { + tx_buf = rx_bufs->buffers[rx].buf; + tx_len = rx_bufs->buffers[rx].len; + } else { + tx_buf = NULL; + tx_len = 0; + } + } else if (tx_len > rx_len) { + rtio_sqe_prep_transceive(sqe, iodev, RTIO_PRIO_NORM, + (uint8_t *)tx_buf, + (uint8_t *)rx_buf, + (uint32_t)rx_len, + NULL); + tx_len -= rx_len; + tx_buf += rx_len; + rx++; + if (rx < rx_count) { + rx_buf = rx_bufs->buffers[rx].buf; + rx_len = rx_bufs->buffers[rx].len; + } else { + rx_buf = NULL; + rx_len = tx_len; + } + } else if (rx_len > tx_len) { + rtio_sqe_prep_transceive(sqe, iodev, RTIO_PRIO_NORM, + (uint8_t *)tx_buf, + (uint8_t *)rx_buf, + (uint32_t)tx_len, + NULL); + rx_len -= tx_len; + rx_buf += tx_len; + tx++; + if (tx < tx_count) { + tx_buf = tx_bufs->buffers[tx].buf; + tx_len = tx_bufs->buffers[tx].len; + } else { + tx_buf = NULL; + tx_len = rx_len; + } + } else { + __ASSERT(false, "Invalid %s state", __func__); + } + + sqe->flags = RTIO_SQE_TRANSACTION; + } + + if (sqe != NULL) { + sqe->flags = 0; + *last_sqe = sqe; + } + +out: + return ret; +} + /** * @brief Lock the SPI RTIO spinlock * diff --git a/drivers/spi/spi_sam.c b/drivers/spi/spi_sam.c index fc8e296194ef0c..e8fd42375ab082 100644 --- a/drivers/spi/spi_sam.c +++ b/drivers/spi/spi_sam.c @@ -17,6 +17,7 @@ LOG_MODULE_REGISTER(spi_sam); #include #include #include +#include #include #include #include diff --git a/include/zephyr/drivers/spi.h b/include/zephyr/drivers/spi.h index 56d2cd3d925382..958211e8294d03 100644 --- a/include/zephyr/drivers/spi.h +++ b/include/zephyr/drivers/spi.h @@ -1085,164 +1085,6 @@ static inline bool spi_is_ready_iodev(const struct rtio_iodev *spi_iodev) return spi_is_ready_dt(spec); } -/** - * @brief Copy the tx_bufs and rx_bufs into a set of RTIO requests - * - * @param[in] r rtio context - * @param[in] iodev iodev to transceive with - * @param[in] tx_bufs transmit buffer set - * @param[in] rx_bufs receive buffer set - * @param[out] last_sqe last sqe submitted, NULL if not enough memory - * - * @retval Number of submission queue entries - * @retval -ENOMEM out of memory - */ -static inline int spi_rtio_copy(struct rtio *r, - struct rtio_iodev *iodev, - const struct spi_buf_set *tx_bufs, - const struct spi_buf_set *rx_bufs, - struct rtio_sqe **last_sqe) -{ - int ret = 0; - size_t tx_count = tx_bufs ? tx_bufs->count : 0; - size_t rx_count = rx_bufs ? rx_bufs->count : 0; - - uint32_t tx = 0, tx_len = 0; - uint32_t rx = 0, rx_len = 0; - uint8_t *tx_buf, *rx_buf; - - struct rtio_sqe *sqe = NULL; - - if (tx < tx_count) { - tx_buf = tx_bufs->buffers[tx].buf; - tx_len = tx_bufs->buffers[tx].len; - } else { - tx_buf = NULL; - tx_len = rx_bufs->buffers[rx].len; - } - - if (rx < rx_count) { - rx_buf = rx_bufs->buffers[rx].buf; - rx_len = rx_bufs->buffers[rx].len; - } else { - rx_buf = NULL; - rx_len = tx_bufs->buffers[tx].len; - } - - - while ((tx < tx_count || rx < rx_count) && (tx_len > 0 || rx_len > 0)) { - sqe = rtio_sqe_acquire(r); - - if (sqe == NULL) { - ret = -ENOMEM; - rtio_sqe_drop_all(r); - goto out; - } - - ret++; - - /* If tx/rx len are same, we can do a simple transceive */ - if (tx_len == rx_len) { - if (tx_buf == NULL) { - rtio_sqe_prep_read(sqe, iodev, RTIO_PRIO_NORM, - rx_buf, rx_len, NULL); - } else if (rx_buf == NULL) { - rtio_sqe_prep_write(sqe, iodev, RTIO_PRIO_NORM, - tx_buf, tx_len, NULL); - } else { - rtio_sqe_prep_transceive(sqe, iodev, RTIO_PRIO_NORM, - tx_buf, rx_buf, rx_len, NULL); - } - tx++; - rx++; - if (rx < rx_count) { - rx_buf = rx_bufs->buffers[rx].buf; - rx_len = rx_bufs->buffers[rx].len; - } else { - rx_buf = NULL; - rx_len = 0; - } - if (tx < tx_count) { - tx_buf = tx_bufs->buffers[tx].buf; - tx_len = tx_bufs->buffers[tx].len; - } else { - tx_buf = NULL; - tx_len = 0; - } - } else if (tx_len == 0) { - rtio_sqe_prep_read(sqe, iodev, RTIO_PRIO_NORM, - (uint8_t *)rx_buf, - (uint32_t)rx_len, - NULL); - rx++; - if (rx < rx_count) { - rx_buf = rx_bufs->buffers[rx].buf; - rx_len = rx_bufs->buffers[rx].len; - } else { - rx_buf = NULL; - rx_len = 0; - } - } else if (rx_len == 0) { - rtio_sqe_prep_write(sqe, iodev, RTIO_PRIO_NORM, - (uint8_t *)tx_buf, - (uint32_t)tx_len, - NULL); - tx++; - if (tx < tx_count) { - tx_buf = rx_bufs->buffers[rx].buf; - tx_len = rx_bufs->buffers[rx].len; - } else { - tx_buf = NULL; - tx_len = 0; - } - } else if (tx_len > rx_len) { - rtio_sqe_prep_transceive(sqe, iodev, RTIO_PRIO_NORM, - (uint8_t *)tx_buf, - (uint8_t *)rx_buf, - (uint32_t)rx_len, - NULL); - tx_len -= rx_len; - tx_buf += rx_len; - rx++; - if (rx < rx_count) { - rx_buf = rx_bufs->buffers[rx].buf; - rx_len = rx_bufs->buffers[rx].len; - } else { - rx_buf = NULL; - rx_len = tx_len; - } - } else if (rx_len > tx_len) { - rtio_sqe_prep_transceive(sqe, iodev, RTIO_PRIO_NORM, - (uint8_t *)tx_buf, - (uint8_t *)rx_buf, - (uint32_t)tx_len, - NULL); - rx_len -= tx_len; - rx_buf += tx_len; - tx++; - if (tx < tx_count) { - tx_buf = tx_bufs->buffers[tx].buf; - tx_len = tx_bufs->buffers[tx].len; - } else { - tx_buf = NULL; - tx_len = rx_len; - } - } else { - __ASSERT_NO_MSG("Invalid spi_rtio_copy state"); - } - - sqe->flags = RTIO_SQE_TRANSACTION; - } - - if (sqe != NULL) { - sqe->flags = 0; - *last_sqe = sqe; - } - -out: - return ret; -} - #endif /* CONFIG_SPI_RTIO */ /** diff --git a/include/zephyr/drivers/spi/rtio.h b/include/zephyr/drivers/spi/rtio.h index 91726655c85e3a..04d5bad8e69119 100644 --- a/include/zephyr/drivers/spi/rtio.h +++ b/include/zephyr/drivers/spi/rtio.h @@ -41,6 +41,24 @@ struct spi_rtio { .r = &CONCAT(_name, _r), \ }; +/** + * @brief Copy the tx_bufs and rx_bufs into a set of RTIO requests + * + * @param[in] r rtio context + * @param[in] iodev iodev to transceive with + * @param[in] tx_bufs transmit buffer set + * @param[in] rx_bufs receive buffer set + * @param[out] last_sqe last sqe submitted, NULL if not enough memory + * + * @retval Number of submission queue entries + * @retval -ENOMEM out of memory + */ +int spi_rtio_copy(struct rtio *r, + struct rtio_iodev *iodev, + const struct spi_buf_set *tx_bufs, + const struct spi_buf_set *rx_bufs, + struct rtio_sqe **last_sqe); + /** * @brief Initialize a SPI RTIO context *