Skip to content

Commit

Permalink
spi: rtio: Move spi_rtio_copy to spi_rtio
Browse files Browse the repository at this point in the history
To group all common APIs for SPI RTIO.

Signed-off-by: Luis Ubieda <luisf@croxel.com>
  • Loading branch information
ubieda authored and carlescufi committed Sep 16, 2024
1 parent bd8a23f commit 00abc5a
Show file tree
Hide file tree
Showing 4 changed files with 177 additions and 158 deletions.
158 changes: 158 additions & 0 deletions drivers/spi/spi_rtio.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
*
Expand Down
1 change: 1 addition & 0 deletions drivers/spi/spi_sam.c
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ LOG_MODULE_REGISTER(spi_sam);
#include <zephyr/spinlock.h>
#include <zephyr/device.h>
#include <zephyr/drivers/spi.h>
#include <zephyr/drivers/spi/rtio.h>
#include <zephyr/drivers/dma.h>
#include <zephyr/drivers/pinctrl.h>
#include <zephyr/drivers/clock_control/atmel_sam_pmc.h>
Expand Down
158 changes: 0 additions & 158 deletions include/zephyr/drivers/spi.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 */

/**
Expand Down
18 changes: 18 additions & 0 deletions include/zephyr/drivers/spi/rtio.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
*
Expand Down

0 comments on commit 00abc5a

Please sign in to comment.