drivers: spi: mcux_flexcomm: fix chip select bug w/ dma transfers

Fix for bug:
https://github.com/zephyrproject-rtos/zephyr/issues/59575

The dma version of the version of the driver can
invoke multiple intermediate dma transfers, like
when the spi_buf_set count is greater than one.
However, there is a bug where chip select is not kept
asserted for all intermediate dma transfers required
to process the entire spi_buf_set.

Signed-off-by: Mike J. Chen <mjchen@google.com>
This commit is contained in:
Mike J. Chen 2023-06-21 17:42:42 -07:00 committed by David Leach
commit 2a4acb2c42

View file

@ -610,6 +610,10 @@ static int transceive_dma(const struct device *dev,
while (data->ctx.rx_len > 0 || data->ctx.tx_len > 0) {
size_t dma_len;
/* last is used to deassert chip select if this
* is the last transfer in the set.
*/
bool last = false;
if (data->ctx.rx_len == 0) {
@ -626,6 +630,34 @@ static int transceive_dma(const struct device *dev,
last = false;
}
/* at this point, last just means whether or not
* this transfer will completely cover
* the current tx/rx buffer in data->ctx
* or require additional transfers because the
* the two buffers are not the same size.
*
* if it covers the current ctx tx/rx buffers, then
* we'll move to the next pair of buffers (if any)
* after the transfer, but if there are
* no more buffer pairs, then this is the last
* transfer in the set and we need to deassert CS.
*/
if (last) {
/* this dma transfer should cover
* the entire current data->ctx set
* of buffers. if there are more
* buffers in the set, then we don't
* want to deassert CS.
*/
if ((data->ctx.tx_count > 1) ||
(data->ctx.rx_count > 1)) {
/* more buffers to transfer so
* this isn't last
*/
last = false;
}
}
data->status_flags = 0;
ret = spi_mcux_dma_move_buffers(dev, dma_len, spi_cfg, last);